Merge pull request #39 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
L_J 2018-02-11 17:32:40 +01:00 committed by GitHub
commit 796a938a41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
257 changed files with 3894 additions and 2295 deletions

View file

@ -82,7 +82,7 @@
<Image iconType="3" name="/menu/preferences.png"/>
</Property>
<Property name="text" type="java.lang.String" value="Preferences"/>
<Property name="toolTipText" type="java.lang.String" value="Change the settings for the different areas of XMage."/>
<Property name="toolTipText" type="java.lang.String" value="By changing the settings in the preferences window you can adjust the look and behaviour of xmage."/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="4"/>
<Property name="verticalTextPosition" type="int" value="3"/>
@ -107,14 +107,6 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnConnectActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblStatus">
<Properties>
<Property name="horizontalAlignment" type="int" value="2"/>
<Property name="text" type="java.lang.String" value="Not connected"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="inheritsPopupMenu" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JToolBar$Separator" name="jSeparator1">
</Component>
<Component class="javax.swing.JButton" name="btnDeckEditor">
@ -174,7 +166,7 @@
<Image iconType="3" name="/menu/symbol.png"/>
</Property>
<Property name="text" type="java.lang.String" value="Symbols"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;Load symbols from the internet.&lt;br&gt;&#xa;You need to do that only once."/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;Load the mana and other card symbols from the internet.&lt;br&gt;&#xa;Otherwise you only see the replacement sequence like {U} for blue mana symbol.&lt;br&gt;&#xa;You need to do that only once."/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="4"/>
<Property name="verticalTextPosition" type="int" value="3"/>

View file

@ -105,6 +105,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final String GRAY_MODE_ARG = "-gray";
private static final String FILL_SCREEN_ARG = "-fullscreen";
private static final String NOT_CONNECTED_TEXT = "<not connected>";
private static MageFrame instance;
private final ConnectDialog connectDialog;
@ -300,7 +301,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
setGUISize();
setConnectButtonText(NOT_CONNECTED_TEXT);
SwingUtilities.invokeLater(() -> {
disableButtons();
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_CHECK, "false").equals("true")) {
@ -329,7 +330,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private void setWindowTitle() {
setTitle(TITLE_NAME + " Client: "
+ (VERSION == null ? "<not available>" : VERSION.toString()) + " Server: "
+ ((SessionHandler.getSession() != null && SessionHandler.isConnected()) ? SessionHandler.getVersionInfo() : "<not connected>"));
+ ((SessionHandler.getSession() != null && SessionHandler.isConnected()) ? SessionHandler.getVersionInfo() : NOT_CONNECTED_TEXT));
}
private void addTooltipContainer() {
@ -431,13 +432,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
}
public static boolean isChrismasTime(Date currentTime){
public static boolean isChrismasTime(Date currentTime) {
// from december 15 to january 15
Calendar cal = new GregorianCalendar();
cal.setTime(currentTime);
int currentYear = cal.get(Calendar.YEAR);
if (cal.get(Calendar.MONTH) == Calendar.JANUARY){
int currentYear = cal.get(Calendar.YEAR);
if (cal.get(Calendar.MONTH) == Calendar.JANUARY) {
currentYear = currentYear - 1;
}
@ -455,12 +456,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
String filename;
float ratio;
if (isChrismasTime(Calendar.getInstance().getTime())){
if (isChrismasTime(Calendar.getInstance().getTime())) {
// chrismass logo
LOGGER.info("Yo Ho Ho, Merry Christmas and a Happy New Year");
filename = "/label-xmage-christmas.png";
ratio = 539.0f / 318.0f;
}else{
} else {
// standard logo
filename = "/label-xmage.png";
ratio = 509.0f / 288.0f;
@ -797,7 +798,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnPreferences = new javax.swing.JButton();
jSeparator4 = new javax.swing.JToolBar.Separator();
btnConnect = new javax.swing.JButton();
lblStatus = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JToolBar.Separator();
btnDeckEditor = new javax.swing.JButton();
jSeparator2 = new javax.swing.JToolBar.Separator();
@ -827,11 +827,15 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnPreferences.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/preferences.png"))); // NOI18N
btnPreferences.setText("Preferences");
btnPreferences.setToolTipText("Change the settings for the different areas of XMage.");
btnPreferences.setToolTipText("By changing the settings in the preferences window you can adjust the look and behaviour of xmage.");
btnPreferences.setFocusable(false);
btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnPreferences.addActionListener(evt -> btnPreferencesActionPerformed(evt));
btnPreferences.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPreferencesActionPerformed(evt);
}
});
mageToolbar.add(btnPreferences);
mageToolbar.add(jSeparator4);
@ -840,14 +844,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnConnect.setFocusable(false);
btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnConnect.addActionListener(evt -> btnConnectActionPerformed(evt));
btnConnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnConnectActionPerformed(evt);
}
});
mageToolbar.add(btnConnect);
lblStatus.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
lblStatus.setText("Not connected");
lblStatus.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
lblStatus.setInheritsPopupMenu(false);
mageToolbar.add(lblStatus);
mageToolbar.add(jSeparator1);
btnDeckEditor.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/deck_editor.png"))); // NOI18N
@ -856,7 +858,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnDeckEditor.setFocusable(false);
btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnDeckEditor.addActionListener(evt -> btnDeckEditorActionPerformed(evt));
btnDeckEditor.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnDeckEditorActionPerformed(evt);
}
});
mageToolbar.add(btnDeckEditor);
mageToolbar.add(jSeparator2);
@ -866,7 +872,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnCollectionViewer.setFocusable(false);
btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnCollectionViewer.addActionListener(evt -> btnCollectionViewerActionPerformed(evt));
btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCollectionViewerActionPerformed(evt);
}
});
mageToolbar.add(btnCollectionViewer);
mageToolbar.add(jSeparator5);
@ -876,17 +886,25 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnSendFeedback.setFocusable(false);
btnSendFeedback.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnSendFeedback.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnSendFeedback.addActionListener(evt -> btnSendFeedbackActionPerformed(evt));
btnSendFeedback.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSendFeedbackActionPerformed(evt);
}
});
mageToolbar.add(btnSendFeedback);
mageToolbar.add(jSeparator6);
btnSymbols.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/symbol.png"))); // NOI18N
btnSymbols.setText("Symbols");
btnSymbols.setToolTipText("<HTML>Load symbols from the internet.<br>\nYou need to do that only once.");
btnSymbols.setToolTipText("<HTML>Load the mana and other card symbols from the internet.<br>\nOtherwise you only see the replacement sequence like {U} for blue mana symbol.<br>\nYou need to do that only once.");
btnSymbols.setFocusable(false);
btnSymbols.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnSymbols.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnSymbols.addActionListener(evt -> btnSymbolsActionPerformed(evt));
btnSymbols.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSymbolsActionPerformed(evt);
}
});
mageToolbar.add(btnSymbols);
mageToolbar.add(jSeparatorSymbols);
@ -896,7 +914,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnImages.setFocusable(false);
btnImages.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnImages.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnImages.addActionListener(evt -> btnImagesActionPerformed(evt));
btnImages.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnImagesActionPerformed(evt);
}
});
mageToolbar.add(btnImages);
mageToolbar.add(jSeparatorImages);
@ -906,7 +928,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
btnAbout.setFocusable(false);
btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnAbout.addActionListener(evt -> btnAboutActionPerformed(evt));
btnAbout.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnAboutActionPerformed(evt);
}
});
mageToolbar.add(btnAbout);
mageToolbar.add(jSeparator7);
@ -1201,20 +1227,18 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private javax.swing.JToolBar.Separator jSeparator7;
private javax.swing.JToolBar.Separator jSeparatorImages;
private javax.swing.JToolBar.Separator jSeparatorSymbols;
private javax.swing.JLabel lblStatus;
private javax.swing.JToolBar mageToolbar;
// End of variables declaration//GEN-END:variables
private static final long serialVersionUID = -9104885239063142218L;
private ImagePanel backgroundPane;
private final TablesPane tablesPane;
// private CollectionViewerPane collectionViewerPane;
public void setStatusText(String status) {
this.lblStatus.setText(status);
public void setConnectButtonText(String status) {
this.btnConnect.setText(status);
changeGUISize(); // Needed to layout the tooltbar after text length change
this.lblStatus.repaint();
this.lblStatus.revalidate();
this.btnConnect.repaint();
this.btnConnect.revalidate();
}
public static MageUI getUI() {
@ -1272,11 +1296,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
@Override
public void connected(final String message) {
if (SwingUtilities.isEventDispatchThread()) {
setStatusText(message);
setConnectButtonText(message);
enableButtons();
} else {
SwingUtilities.invokeLater(() -> {
setStatusText(message);
setConnectButtonText(message);
enableButtons();
});
}
@ -1286,14 +1310,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
public void disconnected(final boolean errorCall) {
if (SwingUtilities.isEventDispatchThread()) { // Returns true if the current thread is an AWT event dispatching thread.
LOGGER.info("DISCONNECTED (Event Dispatch Thread)");
setStatusText("Not connected");
setConnectButtonText(NOT_CONNECTED_TEXT);
disableButtons();
hideGames();
hideTables();
} else {
LOGGER.info("DISCONNECTED (NO Event Dispatch Thread)");
SwingUtilities.invokeLater(() -> {
setStatusText("Not connected");
setConnectButtonText(NOT_CONNECTED_TEXT);
disableButtons();
hideGames();
hideTables();

View file

@ -35,15 +35,13 @@ package mage.client;
import java.awt.AWTEvent;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyVetoException;
import javax.swing.*;
import javax.swing.plaf.basic.BasicInternalFrameUI;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public abstract class MagePane extends javax.swing.JLayeredPane {
private String title = "no title set";
/**

View file

@ -113,6 +113,11 @@ public final class Constants {
public static final String BASE_SOUND_PATH = "sounds" + File.separator; // TODO: check path with File.separator
public static final String BASE_MUSICS_PATH = "music" + File.separator;
// battlefield feedback panel colors (used in preferences dialogs too)
public static final int BATTLEFIELD_FEEDBACK_COLORIZING_MODE_DISABLE = 0;
public static final int BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_ONE_COLOR = 1;
public static final int BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR = 2;
public interface IO {
String DEFAULT_IMAGES_DIR = "plugins" + File.separator + "images" + File.separator;
String IMAGE_PROPERTIES_FILE = "image.url.properties";

View file

@ -536,7 +536,7 @@
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="&quot;&lt;html&gt;&lt;strong&gt;Uncommon&lt;/strong&gt;&lt;br/&gt;&quot; &#xd;&#xa;+ tbUncommon.getToolTipText()" type="code"/>
<Connection code="&quot;&lt;html&gt;&lt;strong&gt;Uncommon&lt;/strong&gt;&lt;br/&gt;&quot; &#xd;&#xa;+ tbRarities.getToolTipText()" type="code"/>
</Property>
<Property name="actionCommand" type="java.lang.String" value="Uncommon"/>
<Property name="focusable" type="boolean" value="false"/>

View file

@ -904,7 +904,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
tbUncommon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/rarity_uncommon_20.png"))); // NOI18N
tbUncommon.setSelected(true);
tbUncommon.setToolTipText("<html><strong>Uncommon</strong><br/>"
+ tbUncommon.getToolTipText());
+ tbRarities.getToolTipText());
tbUncommon.setActionCommand("Uncommon");
tbUncommon.setFocusable(false);
tbUncommon.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

View file

@ -80,6 +80,7 @@
<Component id="main_card" alignment="1" max="32767" attributes="0"/>
<Component id="main_gamelog" alignment="1" max="32767" attributes="0"/>
<Component id="main_game" alignment="0" max="32767" attributes="0"/>
<Component id="main_battlefield" alignment="1" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -94,12 +95,73 @@
<Component id="main_game" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="main_gamelog" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="main_battlefield" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="154" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="main_gamelog">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Game log">
<Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="cbDraftLogAutoSave" max="32767" attributes="0"/>
<Component id="cbGameLogAutoSave" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="cbGameLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbDraftLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="cbGameLogAutoSave">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Auto save game logs (to &quot;../Mage.Client/gamelogs/&quot; directory)"/>
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbGameLogAutoSaveActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JCheckBox" name="cbDraftLogAutoSave">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Auto save draft logs (to &quot;../Mage.Client/gamelogs/&quot; directory)"/>
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbDraftLogAutoSaveActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="main_card">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
@ -159,7 +221,7 @@
<Property name="toolTipText" type="java.lang.String" value="Write the card&apos;s name on the card to make the card name more recognizable."/>
<Property name="actionCommand" type="java.lang.String" value=""/>
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
<Color id="Standardcursor"/>
<Color id="Default Cursor"/>
</Property>
</Properties>
<Events>
@ -189,16 +251,11 @@
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="toolTipText" type="java.lang.String" value="Show the path Xmage is expecting for this card&apos;s image (only displays if missing)"/>
<Property name="actionCommand" type="java.lang.String" value=""/>
<Property name="cursor" type="java.awt.Cursor" editor="org.netbeans.modules.form.editors2.CursorEditor">
<Color id="Default Cursor"/>
</Property>
<Property name="label" type="java.lang.String" value="Display image path for missing images"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Display image path for missing images"/>
<Property name="AccessibleContext.accessibleDescription" type="java.lang.String" value="Show the path Xmage is expecting for this card&apos;s image (only displays if missing)"/>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showFullImagePathActionPerformed"/>
</Events>
@ -226,13 +283,13 @@
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="showPlayerNamesPermanently" alignment="0" max="32767" attributes="0"/>
<Component id="nonLandPermanentsInOnePile" alignment="0" max="32767" attributes="0"/>
<Component id="showAbilityPickerForced" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="cbConfirmEmptyManaPool" alignment="0" max="32767" attributes="0"/>
<Component id="cbAllowRequestToShowHandCards" alignment="0" max="32767" attributes="0"/>
<Component id="cbShowStormCounter" alignment="0" max="32767" attributes="0"/>
<Component id="cbAskMoveToGraveOrder" alignment="0" max="32767" attributes="0"/>
<Component id="showAbilityPickerForced" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<EmptySpace pref="255" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -339,11 +396,11 @@
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="main_gamelog">
<Container class="javax.swing.JPanel" name="main_battlefield">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Game log">
<TitledBorder title="Battlefield">
<Border PropertyName="innerBorder" info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>
</Border>
@ -355,46 +412,50 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="cbDraftLogAutoSave" max="32767" attributes="0"/>
<Component id="cbGameLogAutoSave" max="32767" attributes="0"/>
</Group>
<Component id="lblBattlefieldFeedbackColorizingMode" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbBattlefieldFeedbackColorizingMode" min="-2" pref="278" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="cbGameLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cbDraftLogAutoSave" alignment="1" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lblBattlefieldFeedbackColorizingMode" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cbBattlefieldFeedbackColorizingMode" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="cbGameLogAutoSave">
<Component class="javax.swing.JComboBox" name="cbBattlefieldFeedbackColorizingMode">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Auto save game logs (to &quot;../Mage.Client/gamelogs/&quot; directory)"/>
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="3">
<StringItem index="0" value="Disable colorizing"/>
<StringItem index="1" value="Enable one color for all phases"/>
<StringItem index="2" value="Enable multicolor for different phases"/>
</StringArray>
</Property>
<Property name="toolTipText" type="java.lang.String" value="Battlefield feedback panel colorizing on your turn (e.g. use green color if you must select card or answer to request)"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbGameLogAutoSaveActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbBattlefieldFeedbackColorizingModeActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value=""/>
</AuxValues>
</Component>
<Component class="javax.swing.JCheckBox" name="cbDraftLogAutoSave">
<Component class="javax.swing.JLabel" name="lblBattlefieldFeedbackColorizingMode">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Auto save draft logs (to &quot;../Mage.Client/gamelogs/&quot; directory)"/>
<Property name="toolTipText" type="java.lang.String" value="The logs of all your games will be saved to the mentioned folder if this option is switched on."/>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="cbBattlefieldFeedbackColorizingMode"/>
</Property>
<Property name="text" type="java.lang.String" value="Feedback panel colorizing:"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbDraftLogAutoSaveActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>

View file

@ -69,6 +69,8 @@ import mage.client.util.Config;
import mage.client.util.GUISizeHelper;
import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
import static mage.client.constants.Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
import static mage.constants.Constants.DEFAULT_AVATAR_ID;
import static mage.constants.Constants.MAX_AVATAR_ID;
import static mage.constants.Constants.MIN_AVATAR_ID;
@ -101,6 +103,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER = "gameAskMoveToGraveORder";
public static final String KEY_GAME_USE_PROFANITY_FILTER = "gameUseProfanityFilter";
public static final String KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE = "battlefieldFeedbackColorizingMode";
public static final String KEY_GUI_TABLE_FONT_SIZE = "guiTableFontSize";
public static final String KEY_GUI_CHAT_FONT_SIZE = "guiChatFontSize";
public static final String KEY_GUI_CARD_HAND_SIZE = "guiCardHandSize";
@ -398,11 +402,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel = new javax.swing.JTabbedPane();
tabMain = new javax.swing.JPanel();
main_gamelog = new javax.swing.JPanel();
cbGameLogAutoSave = new javax.swing.JCheckBox();
cbDraftLogAutoSave = new javax.swing.JCheckBox();
main_card = new javax.swing.JPanel();
showCardName = new javax.swing.JCheckBox();
showFullImagePath = new javax.swing.JCheckBox();
tooltipDelayLabel = new javax.swing.JLabel();
tooltipDelay = new javax.swing.JSlider();
showFullImagePath = new javax.swing.JCheckBox();
main_game = new javax.swing.JPanel();
nonLandPermanentsInOnePile = new javax.swing.JCheckBox();
showPlayerNamesPermanently = new javax.swing.JCheckBox();
@ -411,9 +418,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
cbShowStormCounter = new javax.swing.JCheckBox();
cbConfirmEmptyManaPool = new javax.swing.JCheckBox();
cbAskMoveToGraveOrder = new javax.swing.JCheckBox();
main_gamelog = new javax.swing.JPanel();
cbGameLogAutoSave = new javax.swing.JCheckBox();
cbDraftLogAutoSave = new javax.swing.JCheckBox();
main_battlefield = new javax.swing.JPanel();
cbBattlefieldFeedbackColorizingMode = new javax.swing.JComboBox();
lblBattlefieldFeedbackColorizingMode = new javax.swing.JLabel();
tabGuiSize = new javax.swing.JPanel();
guiSizeBasic = new javax.swing.JPanel();
sliderFontSize = new javax.swing.JSlider();
@ -589,6 +596,45 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.setMinimumSize(new java.awt.Dimension(532, 451));
main_gamelog.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Game log"));
cbGameLogAutoSave.setSelected(true);
cbGameLogAutoSave.setText("Auto save game logs (to \"../Mage.Client/gamelogs/\" directory)");
cbGameLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
cbGameLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbGameLogAutoSaveActionPerformed(evt);
}
});
cbDraftLogAutoSave.setSelected(true);
cbDraftLogAutoSave.setText("Auto save draft logs (to \"../Mage.Client/gamelogs/\" directory)");
cbDraftLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
cbDraftLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbDraftLogAutoSaveActionPerformed(evt);
}
});
org.jdesktop.layout.GroupLayout main_gamelogLayout = new org.jdesktop.layout.GroupLayout(main_gamelog);
main_gamelog.setLayout(main_gamelogLayout);
main_gamelogLayout.setHorizontalGroup(
main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_gamelogLayout.createSequentialGroup()
.addContainerGap()
.add(main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(cbDraftLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(cbGameLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
main_gamelogLayout.setVerticalGroup(
main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_gamelogLayout.createSequentialGroup()
.add(cbGameLogAutoSave)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cbDraftLogAutoSave))
);
main_card.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Card"));
showCardName.setSelected(true);
@ -615,9 +661,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
tooltipDelay.setToolTipText("<HTML>The time the appearance of the tooltip window for a card is delayed.<br>\nIf set to zero, the tooltip window won't be shown at all.");
tooltipDelay.setValue(300);
showFullImagePath.setSelected(false);
showFullImagePath.setSelected(true);
showFullImagePath.setToolTipText("Show the path Xmage is expecting for this card's image (only displays if missing)");
showFullImagePath.setActionCommand("");
showFullImagePath.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
showFullImagePath.setLabel("Display image path for missing images");
showFullImagePath.addActionListener(new java.awt.event.ActionListener() {
@ -634,7 +679,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(6, 6, 6)
.add(main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_cardLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
.add(tooltipDelayLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)
.add(tooltipDelayLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 308, Short.MAX_VALUE)
.add(tooltipDelay, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.add(main_cardLayout.createSequentialGroup()
.add(showCardName)
@ -654,9 +699,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(tooltipDelay, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
showFullImagePath.getAccessibleContext().setAccessibleName("Display image path for missing images");
showFullImagePath.getAccessibleContext().setAccessibleDescription("Show the path Xmage is expecting for this card's image (only displays if missing)");
main_game.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Game"));
nonLandPermanentsInOnePile.setSelected(true);
@ -737,11 +779,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(main_gameLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(showPlayerNamesPermanently, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(nonLandPermanentsInOnePile, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(showAbilityPickerForced)
.add(cbConfirmEmptyManaPool, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(cbAllowRequestToShowHandCards, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(cbShowStormCounter, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(cbAskMoveToGraveOrder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.add(cbAskMoveToGraveOrder, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(showAbilityPickerForced, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(255, Short.MAX_VALUE))
);
main_gameLayout.setVerticalGroup(
@ -765,43 +807,35 @@ public class PreferencesDialog extends javax.swing.JDialog {
nonLandPermanentsInOnePile.getAccessibleContext().setAccessibleName("nonLandPermanentsInOnePile");
main_gamelog.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Game log"));
main_battlefield.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Battlefield"));
cbGameLogAutoSave.setSelected(true);
cbGameLogAutoSave.setText("Auto save game logs (to \"../Mage.Client/gamelogs/\" directory)");
cbGameLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
cbGameLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
cbBattlefieldFeedbackColorizingMode.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Disable colorizing", "Enable one color for all phases", "Enable multicolor for different phases" }));
cbBattlefieldFeedbackColorizingMode.setToolTipText("Battlefield feedback panel colorizing on your turn (e.g. use green color if you must select card or answer to request)");
cbBattlefieldFeedbackColorizingMode.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbGameLogAutoSaveActionPerformed(evt);
cbBattlefieldFeedbackColorizingModeActionPerformed(evt);
}
});
cbDraftLogAutoSave.setSelected(true);
cbDraftLogAutoSave.setText("Auto save draft logs (to \"../Mage.Client/gamelogs/\" directory)");
cbDraftLogAutoSave.setToolTipText("The logs of all your games will be saved to the mentioned folder if this option is switched on.");
cbDraftLogAutoSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbDraftLogAutoSaveActionPerformed(evt);
}
});
lblBattlefieldFeedbackColorizingMode.setLabelFor(cbBattlefieldFeedbackColorizingMode);
lblBattlefieldFeedbackColorizingMode.setText("Feedback panel colorizing:");
org.jdesktop.layout.GroupLayout main_gamelogLayout = new org.jdesktop.layout.GroupLayout(main_gamelog);
main_gamelog.setLayout(main_gamelogLayout);
main_gamelogLayout.setHorizontalGroup(
main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_gamelogLayout.createSequentialGroup()
org.jdesktop.layout.GroupLayout main_battlefieldLayout = new org.jdesktop.layout.GroupLayout(main_battlefield);
main_battlefield.setLayout(main_battlefieldLayout);
main_battlefieldLayout.setHorizontalGroup(
main_battlefieldLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_battlefieldLayout.createSequentialGroup()
.addContainerGap()
.add(main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(cbDraftLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(cbGameLogAutoSave, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.add(lblBattlefieldFeedbackColorizingMode)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cbBattlefieldFeedbackColorizingMode, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 278, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
main_gamelogLayout.setVerticalGroup(
main_gamelogLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_gamelogLayout.createSequentialGroup()
.add(cbGameLogAutoSave)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(cbDraftLogAutoSave))
main_battlefieldLayout.setVerticalGroup(
main_battlefieldLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(main_battlefieldLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(lblBattlefieldFeedbackColorizingMode)
.add(cbBattlefieldFeedbackColorizingMode, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
);
org.jdesktop.layout.GroupLayout tabMainLayout = new org.jdesktop.layout.GroupLayout(tabMain);
@ -813,7 +847,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(tabMainLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, main_card, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.TRAILING, main_gamelog, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(main_game, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.add(main_game, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(org.jdesktop.layout.GroupLayout.TRAILING, main_battlefield, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
tabMainLayout.setVerticalGroup(
@ -825,7 +860,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
.add(main_game, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(main_gamelog, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(main_battlefield, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(154, Short.MAX_VALUE))
);
main_card.getAccessibleContext().setAccessibleName("Game panel");
@ -2712,6 +2749,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
save(prefs, dialog.cbDraftLogAutoSave, KEY_DRAFT_LOG_AUTO_SAVE, "true", "false", UPDATE_CACHE_POLICY);
String paramName = KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE;
int paramValue = dialog.cbBattlefieldFeedbackColorizingMode.getSelectedIndex();
int paramDefault = BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR;
if (getCachedValue(paramName, paramDefault) != paramValue) {
prefs.putInt(paramName, paramValue);
if (UPDATE_CACHE_POLICY) {
updateCache(paramName, Integer.toString(paramValue));
}
}
// GUI Size
boolean sizeGUIChanged = false;
if (getCachedValue(KEY_GUI_TABLE_FONT_SIZE, 14) != dialog.sliderFontSize.getValue()) {
@ -3145,6 +3192,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
private void showFullImagePathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showFullImagePathActionPerformed
}//GEN-LAST:event_showFullImagePathActionPerformed
private void cbBattlefieldFeedbackColorizingModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbBattlefieldFeedbackColorizingModeActionPerformed
}//GEN-LAST:event_cbBattlefieldFeedbackColorizingModeActionPerformed
private void showProxySettings() {
Connection.ProxyType proxyType = (Connection.ProxyType) cbProxyType.getSelectedItem();
switch (proxyType) {
@ -3260,6 +3311,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
load(prefs, dialog.cbGameLogAutoSave, KEY_GAME_LOG_AUTO_SAVE, "true");
load(prefs, dialog.cbDraftLogAutoSave, KEY_DRAFT_LOG_AUTO_SAVE, "true");
String feedbackParam = "";
try {
feedbackParam = MageFrame.getPreferences().get(KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE, "2");
int feedbackMode = Integer.parseInt(feedbackParam);
dialog.cbBattlefieldFeedbackColorizingMode.setSelectedIndex(feedbackMode);
} catch (Throwable e) {
logger.error("Can't parse and setup param " + KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE + " = " + feedbackParam, e);
dialog.cbBattlefieldFeedbackColorizingMode.setSelectedIndex(BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR);
}
load(prefs, dialog.checkBoxUpkeepYou, UPKEEP_YOU, "on", "on");
load(prefs, dialog.checkBoxDrawYou, DRAW_YOU, "on", "on");
load(prefs, dialog.checkBoxMainYou, MAIN_YOU, "on", "on");
@ -3759,6 +3820,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
);
}
public static int getBattlefieldFeedbackColorizingMode() {
return PreferencesDialog.getCachedValue(
PreferencesDialog.KEY_BATTLEFIELD_FEEDBACK_COLORIZING_MODE,
BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR);
}
public List<KeyBindButton> getKeybindButtons() {
return Arrays.asList(
keyCancelSkip,
@ -3785,6 +3852,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox cbAllowRequestToShowHandCards;
private javax.swing.JCheckBox cbAskMoveToGraveOrder;
private javax.swing.JCheckBox cbAutoOrderTrigger;
private javax.swing.JComboBox cbBattlefieldFeedbackColorizingMode;
private javax.swing.JCheckBox cbCardRenderHideSetSymbol;
private javax.swing.JCheckBox cbCardRenderImageFallback;
private javax.swing.JCheckBox cbCardRenderShowReminderText;
@ -3905,6 +3973,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JLabel labelToggleRecordMacro;
private javax.swing.JLabel labelTooltipSize;
private javax.swing.JLabel labelYourTurn;
private javax.swing.JLabel lblBattlefieldFeedbackColorizingMode;
private javax.swing.JLabel lblProxyPassword;
private javax.swing.JLabel lblProxyPort;
private javax.swing.JLabel lblProxyServer;
@ -3912,6 +3981,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JLabel lblProxyUserName;
private javax.swing.JLabel lblURLServerList;
private javax.swing.JLabel lebelSkip;
private javax.swing.JPanel main_battlefield;
private javax.swing.JPanel main_card;
private javax.swing.JPanel main_game;
private javax.swing.JPanel main_gamelog;

View file

@ -52,6 +52,7 @@ import static mage.constants.Constants.Option.ORIGINAL_ID;
import static mage.constants.Constants.Option.SECOND_MESSAGE;
import static mage.constants.Constants.Option.SPECIAL_BUTTON;
import mage.constants.PlayerAction;
import mage.constants.TurnPhase;
import org.apache.log4j.Logger;
/**
@ -97,7 +98,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
private void setGUISize() {
}
public void getFeedback(FeedbackMode mode, String message, boolean special, Map<String, Serializable> options, int messageId) {
public void getFeedback(FeedbackMode mode, String message, boolean special, Map<String, Serializable> options,
int messageId, boolean gameNeedUserFeedback, TurnPhase gameTurnPhase) {
synchronized (this) {
if (messageId < this.lastMessageId) {
LOGGER.warn("ignoring message from later source: " + messageId + ", text=" + message);
@ -151,6 +153,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setLinks(btnLeft, btnRight, btnSpecial, btnUndo);
this.helper.setVisible(true);
this.helper.setGameNeedFeedback(gameNeedUserFeedback, gameTurnPhase);
this.helper.autoSizeButtonsAndFeedbackState();
}
private void setButtonState(String leftText, String rightText, FeedbackMode mode) {
@ -211,6 +215,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
if (options.containsKey("dialog")) {
connectedDialog = (MageDialog) options.get("dialog");
}
this.helper.autoSizeButtonsAndFeedbackState();
}
}

View file

@ -52,6 +52,7 @@ import mage.client.util.gui.ArrowBuilder;
import mage.client.util.gui.MageDialogState;
import mage.constants.*;
import mage.game.events.PlayerQueryEvent;
import mage.game.turn.Phase;
import mage.view.*;
import org.apache.log4j.Logger;
import org.mage.card.arcane.CardPanel;
@ -1064,7 +1065,7 @@ public final class GamePanel extends javax.swing.JPanel {
public void ask(String question, GameView gameView, int messageId, Map<String, Serializable> options) {
updateGame(gameView);
this.feedbackPanel.getFeedback(FeedbackMode.QUESTION, question, false, options, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.QUESTION, question, false, options, messageId, true, gameView.getPhase());
}
/**
@ -1113,7 +1114,7 @@ public final class GamePanel extends javax.swing.JPanel {
dialog = showCards(message, cardView, required, options0, popupMenuType);
options0.put("dialog", dialog);
}
this.feedbackPanel.getFeedback(required ? FeedbackMode.INFORM : FeedbackMode.CANCEL, message, gameView.getSpecial(), options0, messageId);
this.feedbackPanel.getFeedback(required ? FeedbackMode.INFORM : FeedbackMode.CANCEL, message, gameView.getSpecial(), options0, messageId, true, gameView.getPhase());
if (dialog != null) {
this.pickTarget.add(dialog); // TODO: 01.01.2018, JayDi85: why feedbackPanel saved to pickTarget list? Need to research
}
@ -1121,11 +1122,11 @@ public final class GamePanel extends javax.swing.JPanel {
public void inform(String information, GameView gameView, int messageId) {
updateGame(gameView);
this.feedbackPanel.getFeedback(FeedbackMode.INFORM, information, gameView.getSpecial(), null, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.INFORM, information, gameView.getSpecial(), null, messageId, false, gameView.getPhase());
}
public void endMessage(String message, int messageId) {
this.feedbackPanel.getFeedback(FeedbackMode.END, message, false, null, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.END, message, false, null, messageId, true, null);
ArrowBuilder.getBuilder().removeAllArrows(gameId);
}
@ -1168,19 +1169,19 @@ public final class GamePanel extends javax.swing.JPanel {
priorityPlayerText = " / priority " + gameView.getPriorityPlayerName();
}
String messageToDisplay = message + FeedbackPanel.getSmallText(activePlayerText + " / " + gameView.getStep().toString() + priorityPlayerText);
this.feedbackPanel.getFeedback(FeedbackMode.SELECT, messageToDisplay, gameView.getSpecial(), panelOptions, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.SELECT, messageToDisplay, gameView.getSpecial(), panelOptions, messageId, true, gameView.getPhase());
}
public void playMana(String message, GameView gameView, Map<String, Serializable> options, int messageId) {
updateGame(gameView);
DialogManager.getManager(gameId).fadeOut();
this.feedbackPanel.getFeedback(FeedbackMode.CANCEL, message, gameView.getSpecial(), options, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.CANCEL, message, gameView.getSpecial(), options, messageId, true, gameView.getPhase());
}
public void playXMana(String message, GameView gameView, int messageId) {
updateGame(gameView);
DialogManager.getManager(gameId).fadeOut();
this.feedbackPanel.getFeedback(FeedbackMode.CONFIRM, message, gameView.getSpecial(), null, messageId);
this.feedbackPanel.getFeedback(FeedbackMode.CONFIRM, message, gameView.getSpecial(), null, messageId, true, gameView.getPhase());
}
public void replayMessage(String message) {

View file

@ -27,17 +27,13 @@
*/
package mage.client.game;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.UUID;
import javax.swing.JButton;
import javax.swing.JMenuItem;
@ -48,14 +44,19 @@ import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import mage.client.SessionHandler;
import mage.client.components.MageTextArea;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.FeedbackPanel.FeedbackMode;
import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
import mage.client.util.GUISizeHelper;
import mage.constants.TurnPhase;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_NO;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_YES;
import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
@ -65,7 +66,7 @@ import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_TEXT_YES;
/**
* Panel with buttons that copy the state of feedback panel.
*
* @author ayrat
* @author ayrat, JayDi85
*/
public class HelperPanel extends JPanel {
@ -77,6 +78,8 @@ public class HelperPanel extends JPanel {
//private javax.swing.JButton btnStopTimer;
private JScrollPane textAreaScrollPane;
private MageTextArea dialogTextArea;
JPanel mainPanel;
JPanel buttonGrid;
JPanel buttonContainer;
private javax.swing.JButton linkLeft;
@ -101,6 +104,8 @@ public class HelperPanel extends JPanel {
private String message;
private UUID gameId;
private boolean gameNeedFeedback = false;
private TurnPhase gameTurnPhase = null;
public HelperPanel() {
initComponents();
@ -129,18 +134,28 @@ public class HelperPanel extends JPanel {
btnSpecial.setFont(GUISizeHelper.gameDialogAreaFont);
btnUndo.setFont(GUISizeHelper.gameDialogAreaFont);
// update text fonts
if (message != null) {
int pos = this.message.indexOf("font-size:");
if (pos > 0) {
String newMessage = this.message.substring(0, pos + 10) + GUISizeHelper.gameDialogAreaFontSizeBig + this.message.substring(pos + 12);
pos = this.message.indexOf("font-size:", pos + 10);
if (pos > 0) {
newMessage = this.message.substring(0, pos + 10) + GUISizeHelper.gameDialogAreaFontSizeSmall + this.message.substring(pos + 12);
int pos1 = this.message.indexOf("font-size:");
if (pos1 > 0) {
int pos2 = this.message.indexOf("font-size:", pos1 + 10);
String newMessage;
if (pos2 > 0) {
// 2 sizes: big + small // TODO: 2 sizes for compatibility only? On 04.02.2018 can't find two size texts (JayDi85)
newMessage = this.message.substring(0, pos1 + 10) + GUISizeHelper.gameDialogAreaFontSizeBig + this.message.substring(pos1 + 12);
newMessage = newMessage.substring(0, pos1 + 10) + GUISizeHelper.gameDialogAreaFontSizeSmall + newMessage.substring(pos1 + 12);
} else {
// 1 size: small
newMessage = this.message.substring(0, pos1 + 10) + GUISizeHelper.gameDialogAreaFontSizeSmall + this.message.substring(pos1 + 12);
}
setBasicMessage(newMessage);
}
}
autoSizeButtonsAndFeedbackState();
GUISizeHelper.changePopupMenuFont(popupMenuAskNo);
GUISizeHelper.changePopupMenuFont(popupMenuAskYes);
revalidate();
@ -149,9 +164,14 @@ public class HelperPanel extends JPanel {
private void initComponents() {
initPopupMenuTriggerOrder();
setBackground(new Color(0, 0, 0, 100));
setLayout(new GridLayout(0, 1));
setOpaque(false);
this.setBorder(new EmptyBorder(5, 5, 5, 5));
this.setLayout(new GridLayout(0, 1));
this.setOpaque(false);
mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(0, 1));
mainPanel.setOpaque(false);
this.add(mainPanel);
dialogTextArea = new MageTextArea();
dialogTextArea.setText("<Empty>");
@ -163,28 +183,32 @@ public class HelperPanel extends JPanel {
textAreaScrollPane.getViewport().setOpaque(false);
textAreaScrollPane.setBorder(null);
textAreaScrollPane.setViewportBorder(null);
add(textAreaScrollPane);
mainPanel.add(textAreaScrollPane);
buttonContainer = new JPanel();
buttonContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 0));
buttonContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
buttonContainer.setOpaque(false);
add(buttonContainer);
mainPanel.add(buttonContainer);
buttonGrid = new JPanel(); // buttons layout auto changes by autoSizeButtonsAndFeedbackState
buttonGrid.setOpaque(false);
buttonContainer.add(buttonGrid);
btnSpecial = new JButton("Special");
btnSpecial.setVisible(false);
buttonContainer.add(btnSpecial);
buttonGrid.add(btnSpecial);
btnLeft = new JButton("OK");
btnLeft.setVisible(false);
buttonContainer.add(btnLeft);
buttonGrid.add(btnLeft);
btnRight = new JButton("Cancel");
btnRight.setVisible(false);
buttonContainer.add(btnRight);
buttonGrid.add(btnRight);
btnUndo = new JButton("Undo");
btnUndo.setVisible(false);
buttonContainer.add(btnUndo);
buttonGrid.add(btnUndo);
MouseListener checkPopupAdapter = new MouseAdapter() {
@Override
@ -280,7 +304,7 @@ public class HelperPanel extends JPanel {
this.btnRight.setActionCommand(mode.toString() + txtRight);
}
}
autoSizeButtonsAndFeedbackState();
}
public void setSpecial(String txtSpecial, boolean specialVisible) {
@ -290,6 +314,7 @@ public class HelperPanel extends JPanel {
public void setUndoEnabled(boolean enabled) {
this.btnUndo.setVisible(enabled);
autoSizeButtonsAndFeedbackState();
}
public void setLeft(String text, boolean visible) {
@ -297,6 +322,7 @@ public class HelperPanel extends JPanel {
if (!text.isEmpty()) {
this.btnLeft.setText(text);
}
autoSizeButtonsAndFeedbackState();
}
public void setRight(String txtRight, boolean rightVisible) {
@ -304,6 +330,111 @@ public class HelperPanel extends JPanel {
if (!txtRight.isEmpty()) {
this.btnRight.setText(txtRight);
}
autoSizeButtonsAndFeedbackState();
}
public void setGameNeedFeedback(boolean need, TurnPhase gameTurnPhase) {
this.gameNeedFeedback = need;
this.gameTurnPhase = gameTurnPhase;
}
public void autoSizeButtonsAndFeedbackState() {
// two mode: same size for small texts (flow), different size for long texts (grid)
// plus colorize feedback panel on player's priority
int BUTTONS_H_GAP = 15;
Color ACTIVE_FEEDBACK_BACKGROUND_COLOR_MAIN = new Color(0, 0, 255, 50);
Color ACTIVE_FEEDBACK_BACKGROUND_COLOR_BATTLE = new Color(255, 0, 0, 50);
Color ACTIVE_FEEDBACK_BACKGROUND_COLOR_OTHER = new Color(0, 255, 0, 50);
int FEEDBACK_COLORIZING_MODE = PreferencesDialog.getBattlefieldFeedbackColorizingMode();
// cleanup current settings to default (flow layout - different sizes)
this.buttonGrid.setLayout(new FlowLayout(FlowLayout.CENTER, BUTTONS_H_GAP, 0));
this.buttonGrid.setPreferredSize(null);
ArrayList<JButton> buttons = new ArrayList<>();
if (this.btnSpecial.isVisible()) { buttons.add(this.btnSpecial); }
if (this.btnLeft.isVisible()) { buttons.add(this.btnLeft); }
if (this.btnRight.isVisible()) { buttons.add(this.btnRight); }
if (this.btnUndo.isVisible()) { buttons.add(this.btnUndo); }
// color panel on player's feedback waiting
if (this.gameNeedFeedback) {
// wait player's action
switch (FEEDBACK_COLORIZING_MODE) {
case Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_DISABLE:
// disabled
this.mainPanel.setOpaque(false);
this.mainPanel.setBorder(null);
break;
case Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_ONE_COLOR:
// one color
this.mainPanel.setOpaque(true);
this.mainPanel.setBackground(ACTIVE_FEEDBACK_BACKGROUND_COLOR_OTHER);
break;
case Constants.BATTLEFIELD_FEEDBACK_COLORIZING_MODE_ENABLE_BY_MULTICOLOR:
// multicolor
this.mainPanel.setOpaque(true);
Color backColor = ACTIVE_FEEDBACK_BACKGROUND_COLOR_OTHER;
if (this.gameTurnPhase != null) {
switch (this.gameTurnPhase) {
case PRECOMBAT_MAIN:
case POSTCOMBAT_MAIN:
backColor = ACTIVE_FEEDBACK_BACKGROUND_COLOR_MAIN;
break;
case COMBAT:
backColor = ACTIVE_FEEDBACK_BACKGROUND_COLOR_BATTLE;
break;
}
}
this.mainPanel.setBackground(backColor);
break;
}
} else {
// inform about other players
this.setOpaque(false);
}
if (buttons.size() == 0) {
return;
}
this.buttonGrid.removeAll();
for (JButton button : buttons) {
this.buttonGrid.add(button);
}
// random text test (click to any objects to change)
/*
Integer i = 1 + RandomUtil.nextInt(50);
String longText = i.toString() + "-";
while (longText.length() < i) {longText += "a";}
this.btnRight.setText(longText);
//*/
// search max preferred size to draw full button's text
int needButtonSizeW = 0;
for (JButton button : buttons) {
needButtonSizeW = Math.max(needButtonSizeW, button.getPreferredSize().width);
}
// search max const size
int constButtonSizeW = GUISizeHelper.gameDialogButtonWidth * 200 / 100;
int constGridSizeW = buttons.size() * constButtonSizeW + BUTTONS_H_GAP * (buttons.size() - 1);
int constGridSizeH = Math.round(GUISizeHelper.gameDialogButtonHeight * 150 / 100);
if (needButtonSizeW < constButtonSizeW) {
// same size mode (grid)
GridLayout gl = new GridLayout(1, buttons.size(), BUTTONS_H_GAP, 0);
this.buttonGrid.setLayout(gl);
this.buttonGrid.setPreferredSize(new Dimension(constGridSizeW, constGridSizeH));
} else {
// different size mode (flow) -- already used by default
//FlowLayout fl = new FlowLayout(FlowLayout.CENTER, BUTTONS_H_GAP, 0);
//this.buttonGrid.setLayout(fl);
}
}
public void setLinks(JButton left, JButton right, JButton special, JButton undo) {

View file

@ -48,7 +48,6 @@ import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.client.MageFrame;
import mage.client.SessionHandler;
@ -72,9 +71,9 @@ import mage.view.RoomUsersView;
import mage.view.TableView;
import mage.view.UserRequestMessage;
import org.apache.log4j.Logger;
import org.ocpsoft.prettytime.Duration;
import org.ocpsoft.prettytime.PrettyTime;
import org.ocpsoft.prettytime.units.JustNow;
import org.ocpsoft.prettytime.Duration;
/**
*
@ -113,7 +112,7 @@ public class TablesPanel extends javax.swing.JPanel {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Date d = (Date)value;
Date d = (Date) value;
label.setText(timeFormater.format(d));
return label;
}
@ -124,12 +123,12 @@ public class TablesPanel extends javax.swing.JPanel {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Long ms = (Long)value;
Long ms = (Long) value;
if(ms != 0){
if (ms != 0) {
Duration dur = timeFormater.approximateDuration(new Date(ms));
label.setText((timeFormater.formatDuration(dur)));
}else{
} else {
label.setText("");
}
return label;
@ -143,10 +142,10 @@ public class TablesPanel extends javax.swing.JPanel {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
Date d = (Date)value;
if(d != null){
Date d = (Date) value;
if (d != null) {
label.setText(datetimeFormater.format(d));
}else{
} else {
label.setText("");
}
@ -194,8 +193,6 @@ public class TablesPanel extends javax.swing.JPanel {
TableUtil.setColumnWidthAndOrder(tableTables, DEFAULT_COLUMNS_WIDTH,
PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH, PreferencesDialog.KEY_TABLES_COLUMNS_ORDER); // TODO: is sort order save and restore after app restart/window open?
// 2. TABLE COMPLETED
completedTablesSorter = new MageTableRowSorter(matchesModel);
tableCompleted.setRowSorter(completedTablesSorter);
@ -650,7 +647,7 @@ public class TablesPanel extends javax.swing.JPanel {
formatFilterList.add(RowFilter.regexFilter("^Constructed - Vintage", TableTableModel.COLUMN_DECK_TYPE));
}
if (btnFormatCommander.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander", TableTableModel.COLUMN_DECK_TYPE));
formatFilterList.add(RowFilter.regexFilter("^Commander|^Duel Commander|^Penny Dreadful Commander|^Freeform Commander|^MTGO 1v1 Commander", TableTableModel.COLUMN_DECK_TYPE));
}
if (btnFormatTinyLeader.isSelected()) {
formatFilterList.add(RowFilter.regexFilter("^Tiny", TableTableModel.COLUMN_DECK_TYPE));
@ -1394,7 +1391,6 @@ class TableTableModel extends AbstractTableModel {
this.fireTableDataChanged();
}
@Override
public int getRowCount() {
return tables.length;
@ -1605,7 +1601,7 @@ class MatchesTableModel extends AbstractTableModel {
this.fireTableDataChanged();
}
MatchesTableModel(){
MatchesTableModel() {
}
@Override

View file

@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 27;
public final static String MAGE_VERSION_MINOR_PATCH = "V2";
public final static String MAGE_VERSION_MINOR_PATCH = "V3";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

@ -21,7 +21,7 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jSplitPane1" alignment="1" max="32767" attributes="0"/>
<Component id="jSplitPane1" alignment="1" pref="521" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@ -70,7 +70,7 @@
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" alignment="0" pref="339" max="32767" attributes="0"/>
<Component id="jScrollPane1" alignment="0" pref="462" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@ -227,7 +227,7 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="jPanel5" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jPanel6" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
@ -239,12 +239,12 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" alignment="0" pref="453" max="32767" attributes="0"/>
<Component id="jScrollPane2" alignment="0" pref="606" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" alignment="0" pref="340" max="32767" attributes="0"/>
<Component id="jScrollPane2" alignment="0" pref="459" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
@ -272,8 +272,12 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jUserName" min="-2" pref="134" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="btnRemoveTable" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
@ -282,8 +286,13 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="btnRemoveTable" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="31" max="32767" attributes="0"/>
<EmptySpace pref="20" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnRemoveTable" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jUserName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@ -297,6 +306,17 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnRemoveTableActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="jUserName">
<Properties>
<Property name="text" type="java.lang.String" value=""/>
<Property name="name" type="java.lang.String" value="Username" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value="Username:"/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>

View file

@ -135,6 +135,8 @@ public class ConsolePanel extends javax.swing.JPanel {
tblTables = new javax.swing.JTable();
jPanel6 = new javax.swing.JPanel();
btnRemoveTable = new javax.swing.JButton();
jUserName = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jSplitPane1.setDividerLocation(250);
jSplitPane1.setResizeWeight(0.5);
@ -145,94 +147,114 @@ public class ConsolePanel extends javax.swing.JPanel {
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE)
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 462, Short.MAX_VALUE)
);
jPanel4.setVerifyInputWhenFocusTarget(false);
btnDisconnect.setText("Disconnect");
btnDisconnect.addActionListener(evt -> btnDisconnectActionPerformed(evt));
btnDisconnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnDisconnectActionPerformed(evt);
}
});
btnEndSession.setText("End session");
btnEndSession.addActionListener(evt -> btnEndSessionActionPerformed(evt));
btnEndSession.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnEndSessionActionPerformed(evt);
}
});
btnMuteUser.setText("Mute user");
btnMuteUser.setActionCommand("Mute 1h");
btnMuteUser.addActionListener(evt -> btnMuteUserActionPerformed(evt));
btnMuteUser.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMuteUserActionPerformed(evt);
}
});
btnDeActivate.setText("(de)activate");
btnDeActivate.setActionCommand("Mute 1h");
btnDeActivate.addActionListener(evt -> btnDeActivateActionPerformed(evt));
btnDeActivate.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnDeActivateActionPerformed(evt);
}
});
btnLockUser.setText("Lock user");
btnLockUser.setActionCommand("Mute 1h");
btnLockUser.addActionListener(evt -> btnLockUserActionPerformed(evt));
btnLockUser.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnLockUserActionPerformed(evt);
}
});
lblMinutes.setText("Minutes");
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addContainerGap()
.addComponent(btnDisconnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(jPanel4Layout.createSequentialGroup()
.addComponent(btnEndSession)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMuteUser))
.addGroup(jPanel4Layout.createSequentialGroup()
.addComponent(btnDeActivate)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnLockUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblMinutes)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addContainerGap()
.addComponent(btnDisconnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(jPanel4Layout.createSequentialGroup()
.addComponent(btnEndSession)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMuteUser))
.addGroup(jPanel4Layout.createSequentialGroup()
.addComponent(btnDeActivate)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnLockUser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lblMinutes)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnDisconnect)
.addComponent(btnEndSession)
.addComponent(btnMuteUser))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnDeActivate)
.addComponent(btnLockUser)))
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(16, 16, 16)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblMinutes)
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnDisconnect)
.addComponent(btnEndSession)
.addComponent(btnMuteUser))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnDeActivate)
.addComponent(btnLockUser)))
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(16, 16, 16)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblMinutes)
.addComponent(spinnerMuteDurationMinutes, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0)
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0))
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0)
.addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0))
);
jSplitPane1.setLeftComponent(jPanel1);
@ -243,46 +265,63 @@ public class ConsolePanel extends javax.swing.JPanel {
javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
jPanel5.setLayout(jPanel5Layout);
jPanel5Layout.setHorizontalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 453, Short.MAX_VALUE)
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 606, Short.MAX_VALUE)
);
jPanel5Layout.setVerticalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 340, Short.MAX_VALUE)
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 459, Short.MAX_VALUE)
);
btnRemoveTable.setText("Remove Table");
btnRemoveTable.addActionListener(evt -> btnRemoveTableActionPerformed(evt));
btnRemoveTable.setLabel("Remove Table");
btnRemoveTable.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnRemoveTableActionPerformed(evt);
}
});
jUserName.setText("");
jUserName.setName("Username"); // NOI18N
jLabel1.setText("Username:");
javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
jPanel6.setLayout(jPanel6Layout);
jPanel6Layout.setHorizontalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addContainerGap()
.addComponent(btnRemoveTable)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jUserName, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(btnRemoveTable)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel6Layout.setVerticalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addComponent(btnRemoveTable)
.addContainerGap(31, Short.MAX_VALUE))
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addContainerGap(20, Short.MAX_VALUE)
.addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnRemoveTable)
.addComponent(jUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addContainerGap())
);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0)
.addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);
jSplitPane1.setRightComponent(jPanel2);
@ -290,12 +329,12 @@ public class ConsolePanel extends javax.swing.JPanel {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING)
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING)
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 521, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
@ -304,11 +343,6 @@ public class ConsolePanel extends javax.swing.JPanel {
ConsoleFrame.getSession().disconnectUser((String) tableUserModel.getValueAt(row, TableUserModel.POS_SESSION_ID));
}//GEN-LAST:event_btnDisconnectActionPerformed
private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed
int row = this.tblTables.convertRowIndexToModel(tblTables.getSelectedRow());
ConsoleFrame.getSession().removeTable((UUID) tableTableModel.getValueAt(row, 7));
}//GEN-LAST:event_btnRemoveTableActionPerformed
private void btnEndSessionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndSessionActionPerformed
int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, TableUserModel.POS_GAME_INFO));
@ -329,6 +363,11 @@ public class ConsolePanel extends javax.swing.JPanel {
ConsoleFrame.getSession().lockUser((String) tableUserModel.getValueAt(row, TableUserModel.POS_USER_NAME), ((Number) spinnerMuteDurationMinutes.getValue()).longValue());
}//GEN-LAST:event_btnLockUserActionPerformed
private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed
int row = this.tblTables.convertRowIndexToModel(tblTables.getSelectedRow());
ConsoleFrame.getSession().removeTable((UUID) tableTableModel.getValueAt(row, 7));
}//GEN-LAST:event_btnRemoveTableActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnDeActivate;
private javax.swing.JButton btnDisconnect;
@ -336,6 +375,7 @@ public class ConsolePanel extends javax.swing.JPanel {
private javax.swing.JButton btnLockUser;
private javax.swing.JButton btnMuteUser;
private javax.swing.JButton btnRemoveTable;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
@ -345,6 +385,7 @@ public class ConsolePanel extends javax.swing.JPanel {
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JSplitPane jSplitPane1;
public javax.swing.JTextField jUserName;
private javax.swing.JLabel lblMinutes;
private javax.swing.JSpinner spinnerMuteDurationMinutes;
private javax.swing.JTable tblTables;
@ -525,6 +566,15 @@ class UpdateUsersTask extends SwingWorker<Void, List<UserView>> {
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
List<UserView> users = session.getUsers();
if (!panel.jUserName.getText().equals("")) {
List<UserView> users2 = new ArrayList<>();
for (UserView user : users) {
if (user.getUserName().toUpperCase().matches(".*" + panel.jUserName.getText().toUpperCase() + ".*")) {
users2.add(user);
}
}
users = users2;
}
if (previousUsers == null || checkUserListChanged(users)) {
logger.debug("Need to update the user list");
@ -600,7 +650,18 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
this.publish(session.getTables(roomId));
Collection<TableView> tableViews = session.getTables(roomId);
if (!panel.jUserName.getText().equals("")) {
Collection<TableView> tableViews2 = new ArrayList<>();
for (TableView table : tableViews) {
if (table.getControllerName().toUpperCase().matches(".*" + panel.jUserName.getText().toUpperCase() + ".*")) {
tableViews2.add(table);
}
}
tableViews = tableViews2;
}
this.publish(tableViews);
Thread.sleep(3000);
}
return null;

View file

@ -29,7 +29,6 @@ package mage.player.ai;
import java.io.Serializable;
import java.util.*;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.Mode;
@ -323,8 +322,11 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
return !target.isRequired(source);
}
Card card = cards.getRandom(game);
target.addTarget(card.getId(), source, game);
return true;
if (card != null) {
target.addTarget(card.getId(), source, game);
return true;
}
return false;
}
@Override

View file

@ -153,7 +153,7 @@ public class HumanPlayer extends PlayerImpl {
// wait response open for answer process
int numTimesWaiting = 0;
while (!responseOpenedForAnswer && canRespond()) {
numTimesWaiting ++;
numTimesWaiting++;
if (numTimesWaiting >= 300) {
// game freezed -- need to report about error and continue to execute
String s = "Game freezed in waitResponseOpen for user " + getName();
@ -406,14 +406,14 @@ public class HumanPlayer extends PlayerImpl {
}
}
updateGameStatePriority("choose(3)", game);
while (!abort) {
while (canRespond()) {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireChooseChoiceEvent(playerId, choice);
}
waitForResponse(game);
String val = response.getString();
if (val != null) {
if (val != null && !val.isEmpty()) {
if (choice.isKeyChoice()) {
choice.setChoiceByKey(val);
} else {

View file

@ -51,7 +51,7 @@ import mage.target.TargetPlayer;
public class Addle extends CardImpl {
public Addle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
// Choose a color. Target player reveals his or her hand and you choose a card of that color from it. That player discards that card.
this.getSpellAbility().addEffect(new AddleEffect());
@ -87,17 +87,14 @@ class AddleEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if(controller != null) {
ChoiceColor choice = new ChoiceColor();
controller.choose(outcome, choice, game);
ChoiceColor choice = new ChoiceColor();
if (controller != null && controller.choose(outcome, choice, game)) {
ObjectColor color = choice.getColor();
if(color != null) {
game.informPlayers(controller.getLogName() + " chooses " + color + '.');
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(color));
Effect effect = new DiscardCardYouChooseTargetEffect(filter);
return effect.apply(game, source);
}
game.informPlayers(controller.getLogName() + " chooses " + color + '.');
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(color));
Effect effect = new DiscardCardYouChooseTargetEffect(filter);
return effect.apply(game, source);
}
return false;
}

View file

@ -25,7 +25,7 @@ public class AmmitEternal extends CardImpl {
// Afflict 3 (Whenever this creature becomes blocked, defending player loses 3 life.)
this.addAbility(new AfflictAbility(3));
// Whenever an opponent casts a spell, put a -1/-1 counter on Ammit Eternal.
this.addAbility(new SpellCastOpponentTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance()), false));
@ -37,6 +37,7 @@ public class AmmitEternal extends CardImpl {
super(ammitEternal);
}
@Override
public AmmitEternal copy() {
return new AmmitEternal(this);
}

View file

@ -56,7 +56,7 @@ import mage.players.Player;
public class AngelicSkirmisher extends CardImpl {
public AngelicSkirmisher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(4);
@ -103,13 +103,8 @@ class AngelicSkirmisherEffect extends OneShotEffect {
abilityChoices.add("Vigilance");
abilityChoices.add("Lifelink");
abilityChoice.setChoices(abilityChoices);
while (!controller.choose(outcome, abilityChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
Ability ability = null;
if (abilityChoice.getChoice() != null) {
if (controller.choose(outcome, abilityChoice, game)) {
Ability ability = null;
switch (abilityChoice.getChoice()) {
case "First strike":
ability = FirstStrikeAbility.getInstance();

View file

@ -157,13 +157,16 @@ class AnimationModuleEffect extends OneShotEffect {
}
choice.setChoices(choices);
choice.setMessage("Choose a counter");
controller.choose(Outcome.Benefit, choice, game);
for (Counter counter : permanent.getCounters(game).values()) {
if (counter.getName().equals(choice.getChoice())) {
Counter newCounter = new Counter(counter.getName());
permanent.addCounters(newCounter, source, game);
break;
if (controller.choose(Outcome.Benefit, choice, game)) {
for (Counter counter : permanent.getCounters(game).values()) {
if (counter.getName().equals(choice.getChoice())) {
Counter newCounter = new Counter(counter.getName());
permanent.addCounters(newCounter, source, game);
break;
}
}
} else {
return false;
}
}
}
@ -184,13 +187,16 @@ class AnimationModuleEffect extends OneShotEffect {
}
choice.setChoices(choices);
choice.setMessage("Choose a counter");
controller.choose(Outcome.Benefit, choice, game);
for (Counter counter : player.getCounters().values()) {
if (counter.getName().equals(choice.getChoice())) {
Counter newCounter = new Counter(counter.getName());
player.addCounters(newCounter, game);
break;
if (controller.choose(Outcome.Benefit, choice, game)) {
for (Counter counter : player.getCounters().values()) {
if (counter.getName().equals(choice.getChoice())) {
Counter newCounter = new Counter(counter.getName());
player.addCounters(newCounter, game);
break;
}
}
} else {
return false;
}
}
}

View file

@ -52,7 +52,7 @@ import mage.target.common.TargetCardInYourGraveyard;
public class AphettoDredging extends CardImpl {
public AphettoDredging(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Return up to three target creature cards of the creature type of your choice from your graveyard to your hand.
Effect effect = new ReturnFromGraveyardToHandTargetEffect();
@ -64,15 +64,9 @@ public class AphettoDredging extends CardImpl {
public void adjustTargets(Ability ability, Game game) {
if (ability instanceof SpellAbility) {
Player controller = game.getPlayer(ability.getControllerId());
if (controller != null) {
Choice typeChoice = new ChoiceCreatureType(game.getObject(ability.getSourceId()));
while (!controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) {
if (!controller.canRespond()) {
return;
}
}
Choice typeChoice = new ChoiceCreatureType(game.getObject(ability.getSourceId()));
if (controller != null && controller.choose(Outcome.PutCreatureInPlay, typeChoice, game)) {
String chosenType = typeChoice.getChoice();
FilterCreatureCard filter = new FilterCreatureCard(chosenType + " cards");
filter.add(new SubtypePredicate(SubType.byDescription(chosenType)));
ability.addTarget(new TargetCardInYourGraveyard(0, 3, filter));

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.a;
import java.util.UUID;
@ -53,6 +52,7 @@ import mage.target.common.TargetControlledPermanent;
* @author Loki
*/
public class ApostlesBlessing extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature you control");
static {
@ -62,8 +62,8 @@ public class ApostlesBlessing extends CardImpl {
}
public ApostlesBlessing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W/P}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W/P}");
// ({W/P} can be paid with either {W} or 2 life.)
// Target artifact or creature you control gains protection from artifacts or from the color of your choice until end of turn.
this.getSpellAbility().addEffect(new ApostlesBlessingEffect());
@ -82,46 +82,41 @@ public class ApostlesBlessing extends CardImpl {
}
class ApostlesBlessingEffect extends OneShotEffect {
public ApostlesBlessingEffect() {
super(Outcome.AddAbility);
this.staticText = "Target artifact or creature you control gains protection from artifacts or from the color of your choice until end of turn";
}
public ApostlesBlessingEffect(final ApostlesBlessingEffect effect) {
super(effect);
}
@Override
public ApostlesBlessingEffect copy() {
return new ApostlesBlessingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceColorOrArtifact choice = new ChoiceColorOrArtifact();
while (!choice.isChosen()) {
if (!controller.canRespond()) {
return false;
if (controller.choose(outcome, choice, game)) {
FilterCard protectionFilter = new FilterCard();
if (choice.isArtifactSelected()) {
protectionFilter.add(new CardTypePredicate(CardType.ARTIFACT));
} else {
protectionFilter.add(new ColorPredicate(choice.getColor()));
}
controller.choose(outcome, choice, game);
protectionFilter.setMessage(choice.getChoice());
ProtectionAbility protectionAbility = new ProtectionAbility(protectionFilter);
ContinuousEffect effect = new GainAbilityTargetEffect(protectionAbility, Duration.EndOfTurn);
effect.setTargetPointer(getTargetPointer());
game.addEffect(effect, source);
return true;
}
FilterCard protectionFilter = new FilterCard();
if (choice.isArtifactSelected()) {
protectionFilter.add(new CardTypePredicate(CardType.ARTIFACT));
} else {
protectionFilter.add(new ColorPredicate(choice.getColor()));
}
protectionFilter.setMessage(choice.getChoice());
ProtectionAbility protectionAbility = new ProtectionAbility(protectionFilter);
ContinuousEffect effect = new GainAbilityTargetEffect(protectionAbility, Duration.EndOfTurn);
effect.setTargetPointer(getTargetPointer());
game.addEffect(effect, source);
return true;
}
}
return false;
}
}

View file

@ -54,7 +54,7 @@ import mage.players.Player;
public class AquamorphEntity extends CardImpl {
public AquamorphEntity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
@ -136,11 +136,9 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl {
choice.getChoices().add(choice15);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
while (!choice.isChosen()) {
controller.choose(Outcome.Neutral, choice, game);
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Neutral, choice, game)) {
discard();
return false;
}
}
int power = 0;

View file

@ -53,20 +53,20 @@ import mage.players.Player;
public class ArchangelOfStrife extends CardImpl {
public ArchangelOfStrife(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}");
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Flying
this.addAbility(FlyingAbility.getInstance());
// As Archangel of Strife enters the battlefield, each player chooses war or peace.
this.addAbility(new EntersBattlefieldAbility(new ArchangelOfStrifeChooseEffect(), "As Archangel of Strife enters the battlefield, each player chooses war or peace."));
// Creatures controlled by players who chose war get +3/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchangelOfStrifeWarEffect()));
// Creatures controlled by players who chose peace get +0/+3.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArchangelOfStrifePeaceEffect()));
}
@ -83,50 +83,43 @@ public class ArchangelOfStrife extends CardImpl {
class ArchangelOfStrifeChooseEffect extends OneShotEffect {
public ArchangelOfStrifeChooseEffect(){
public ArchangelOfStrifeChooseEffect() {
super(Outcome.Neutral);
this.staticText = "each player chooses war or peace.";
}
public ArchangelOfStrifeChooseEffect(ArchangelOfStrifeChooseEffect effect){
public ArchangelOfStrifeChooseEffect(ArchangelOfStrifeChooseEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent == null) {
sourcePermanent = game.getPermanentEntering(source.getSourceId());
}
if (controller != null && sourcePermanent != null) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
Choice choice = new ChoiceImpl(true);
choice.setMessage("Select war or peace");
choice.getChoices().add("war");
choice.getChoices().add("peace");
while (!choice.isChosen()) {
if (!player.canRespond()) {
return false;
}
player.choose(Outcome.Neutral, choice, game);
if (!player.choose(Outcome.Neutral, choice, game)) {
continue;
}
if (choice.isChosen()) {
if (!game.isSimulation()) {
game.informPlayers(sourcePermanent.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice());
}
game.getState().setValue(playerId + "_" + source.getSourceId() + "_modeChoice", choice.getChoice());
sourcePermanent.addInfo("_" + playerId +"_modeChoice", "<font color = 'blue'>" + player.getName() + " chose: " + choice.getChoice() + "</font>", game);
if (!game.isSimulation()) {
game.informPlayers(sourcePermanent.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice());
}
game.getState().setValue(playerId + "_" + source.getSourceId() + "_modeChoice", choice.getChoice());
sourcePermanent.addInfo("_" + playerId + "_modeChoice", "<font color = 'blue'>" + player.getName() + " chose: " + choice.getChoice() + "</font>", game);
}
return true;
}
@ -137,29 +130,30 @@ class ArchangelOfStrifeChooseEffect extends OneShotEffect {
public Effect copy() {
return new ArchangelOfStrifeChooseEffect(this);
}
}
class ArchangelOfStrifeWarEffect extends BoostAllEffect{
class ArchangelOfStrifeWarEffect extends BoostAllEffect {
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Creatures controlled by players who chose war");
public ArchangelOfStrifeWarEffect(){
public ArchangelOfStrifeWarEffect() {
super(3, 0, Duration.WhileOnBattlefield, creaturefilter, false);
}
@Override
protected boolean selectedByRuntimeData(Permanent permanent, Ability source, Game game) {
if (permanent != null){
if (permanent != null) {
UUID controllerId = permanent.getControllerId();
String choosenMode = (String) game.getState().getValue(controllerId + "_" + source.getSourceId() + "_modeChoice");
return creaturefilter.match(permanent, game) && choosenMode != null && choosenMode.equals("war");
return creaturefilter.match(permanent, game) && choosenMode != null && choosenMode.equals("war");
}
return false;
}
public ArchangelOfStrifeWarEffect(ArchangelOfStrifeWarEffect effect) {
super(effect);
}
@ -170,26 +164,27 @@ class ArchangelOfStrifeWarEffect extends BoostAllEffect{
}
}
class ArchangelOfStrifePeaceEffect extends BoostAllEffect{
class ArchangelOfStrifePeaceEffect extends BoostAllEffect {
private static final FilterCreaturePermanent creaturefilter = new FilterCreaturePermanent("Creatures controlled by players who chose peace");
public ArchangelOfStrifePeaceEffect(){
public ArchangelOfStrifePeaceEffect() {
super(0, 3, Duration.WhileOnBattlefield, creaturefilter, false);
}
@Override
protected boolean selectedByRuntimeData(Permanent permanent, Ability source, Game game) {
if (permanent != null){
if (permanent != null) {
UUID controllerId = permanent.getControllerId();
String choosenMode = (String) game.getState().getValue(controllerId + "_" + source.getSourceId() + "_modeChoice");
return creaturefilter.match(permanent, game) && choosenMode != null && choosenMode.equals("peace");
return creaturefilter.match(permanent, game) && choosenMode != null && choosenMode.equals("peace");
}
return false;
}
public ArchangelOfStrifePeaceEffect(ArchangelOfStrifePeaceEffect effect) {
super(effect);
}
@ -198,4 +193,4 @@ class ArchangelOfStrifePeaceEffect extends BoostAllEffect{
public ArchangelOfStrifePeaceEffect copy() {
return new ArchangelOfStrifePeaceEffect(this);
}
}
}

View file

@ -54,9 +54,10 @@ public class ArmageddonClock extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
// At the beginning of your upkeep, put a doom counter on Armageddon Clock.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.DOOM.createInstance(), new StaticValue(1), true, true), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.DOOM.createInstance(), new StaticValue(1), true), TargetController.YOU, false));
// At the beginning of your draw step, Armageddon Clock deals damage equal to the number of doom counters on it to each player.
this.addAbility(new BeginningOfDrawTriggeredAbility(new DamagePlayersEffect(Outcome.Damage, new CountersSourceCount(CounterType.DOOM)), TargetController.YOU, false));
this.addAbility(new BeginningOfDrawTriggeredAbility(new DamagePlayersEffect(Outcome.Damage, new CountersSourceCount(CounterType.DOOM))
.setText("{this} deals damage equal to the number of doom counters on it to each player"), TargetController.YOU, false));
// {4}: Remove a doom counter from Armageddon Clock. Any player may activate this ability but only during any upkeep step.
ActivatedAbilityImpl ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD,
new RemoveCounterSourceEffect(CounterType.DOOM.createInstance()), new ManaCostsImpl("{4}"), new IsStepCondition(PhaseStep.UPKEEP, false),

View file

@ -43,9 +43,9 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -57,9 +57,9 @@ import mage.target.targetpointer.FixedTarget;
* @author LevelX2 & L_J
*/
public class AzorTheLawbringer extends CardImpl {
public AzorTheLawbringer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}{U}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SPHINX);
this.power = new MageInt(6);
@ -70,7 +70,7 @@ public class AzorTheLawbringer extends CardImpl {
// When Azor, the Lawbringer enters the battlefield, each opponent cant cast instant or sorcery spells during that players next turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new AzorTheLawbringerEntersBattlefieldEffect(), false));
// Whenever Azor attacks, you may pay {X}{W}{U}{U}. If you do, you gain X life and draw X cards.
this.addAbility(new AttacksTriggeredAbility(new AzorTheLawbringerAttacksEffect(), false));
}
@ -192,6 +192,7 @@ class AzorTheLawbringerAttacksEffect extends OneShotEffect {
int costX = controller.announceXMana(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source);
cost.add(new GenericManaCost(costX));
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
controller.resetStoredBookmark(game); // otherwise you can undo the payment
controller.gainLife(costX, game);
controller.drawCards(costX, game);
return true;

View file

@ -33,7 +33,6 @@ import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainProtectionFromColorTargetEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -101,25 +100,27 @@ class BatheInLightEffect extends OneShotEffect {
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
if (target != null) {
ChoiceColor colorChoice = new ChoiceColor();
if (controller.choose(Outcome.Benefit, colorChoice, game)) {
game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + colorChoice.getChoice());
game.getState().setValue(target.getId() + "_color", colorChoice.getColor());
ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
if (protectColor != null) {
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
game.addEffect(effect, source);
ObjectColor color = target.getColor(game);
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (permanent != target && permanent.getColor(game).shares(color)) {
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
if (!controller.choose(Outcome.Benefit, colorChoice, game)) {
return false;
}
game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + colorChoice.getChoice());
game.getState().setValue(target.getId() + "_color", colorChoice.getColor());
ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
if (protectColor != null) {
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
game.addEffect(effect, source);
ObjectColor color = target.getColor(game);
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (permanent != target && permanent.getColor(game).shares(color)) {
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
}
}
return true;
return true;
}
}
return false;

View file

@ -106,41 +106,41 @@ class BloodOathEffect extends OneShotEffect {
if (player != null && opponent != null && sourceObject != null) {
Choice choiceImpl = new ChoiceImpl();
choiceImpl.setChoices(choice);
while (player.canRespond() && !player.choose(Outcome.Neutral, choiceImpl, game)) {
}
CardType type = null;
String choosenType = choiceImpl.getChoice();
if (!player.choose(Outcome.Neutral, choiceImpl, game)) {
CardType type = null;
String choosenType = choiceImpl.getChoice();
if (choosenType.equals(CardType.ARTIFACT.toString())) {
type = CardType.ARTIFACT;
} else if (choosenType.equals(CardType.LAND.toString())) {
type = CardType.LAND;
} else if (choosenType.equals(CardType.CREATURE.toString())) {
type = CardType.CREATURE;
} else if (choosenType.equals(CardType.ENCHANTMENT.toString())) {
type = CardType.ENCHANTMENT;
} else if (choosenType.equals(CardType.INSTANT.toString())) {
type = CardType.INSTANT;
} else if (choosenType.equals(CardType.SORCERY.toString())) {
type = CardType.SORCERY;
} else if (choosenType.equals(CardType.PLANESWALKER.toString())) {
type = CardType.PLANESWALKER;
} else if (choosenType.equals(CardType.TRIBAL.toString())) {
type = CardType.TRIBAL;
}
if (type != null) {
Cards hand = opponent.getHand();
opponent.revealCards(sourceObject.getIdName(), hand, game);
Set<Card> cards = hand.getCards(game);
int damageToDeal = 0;
for (Card card : cards) {
if (card != null && card.getCardType().contains(type)) {
damageToDeal += 3;
}
if (choosenType.equals(CardType.ARTIFACT.toString())) {
type = CardType.ARTIFACT;
} else if (choosenType.equals(CardType.LAND.toString())) {
type = CardType.LAND;
} else if (choosenType.equals(CardType.CREATURE.toString())) {
type = CardType.CREATURE;
} else if (choosenType.equals(CardType.ENCHANTMENT.toString())) {
type = CardType.ENCHANTMENT;
} else if (choosenType.equals(CardType.INSTANT.toString())) {
type = CardType.INSTANT;
} else if (choosenType.equals(CardType.SORCERY.toString())) {
type = CardType.SORCERY;
} else if (choosenType.equals(CardType.PLANESWALKER.toString())) {
type = CardType.PLANESWALKER;
} else if (choosenType.equals(CardType.TRIBAL.toString())) {
type = CardType.TRIBAL;
}
if (type != null) {
Cards hand = opponent.getHand();
opponent.revealCards(sourceObject.getIdName(), hand, game);
Set<Card> cards = hand.getCards(game);
int damageToDeal = 0;
for (Card card : cards) {
if (card != null && card.getCardType().contains(type)) {
damageToDeal += 3;
}
}
game.informPlayers(sourceObject.getLogName() + " deals " + (damageToDeal == 0 ? "no" : "" + damageToDeal) + " damage to " + opponent.getLogName());
opponent.damage(damageToDeal, source.getSourceId(), game, false, true);
return true;
}
game.informPlayers(sourceObject.getLogName() + " deals " + (damageToDeal == 0 ? "no" : "" + damageToDeal) + " damage to " + opponent.getLogName());
opponent.damage(damageToDeal, source.getSourceId(), game, false, true);
return true;
}
}
return false;

View file

@ -27,6 +27,7 @@
*/
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@ -45,8 +46,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author fireshoes
@ -96,37 +95,28 @@ class BloodlineShamanEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null) {
// Choose a creature type.
Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
if (typeChoice.getChoice() != null) {
game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
}
Choice typeChoice = new ChoiceCreatureType(sourceObject);
if (controller != null && controller.choose(outcome, typeChoice, game)) {
game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
FilterCard filterSubtype = new FilterCard();
filterSubtype.add(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice())));
// Reveal the top card of your library.
if (controller.getLibrary().hasCards()) {
Card card = controller.getLibrary().getFromTop(game);
Cards cards = new CardsImpl(card);
controller.revealCards(sourceObject.getIdName(), cards, game);
Card card = controller.getLibrary().getFromTop(game);
Cards cards = new CardsImpl(card);
controller.revealCards(sourceObject.getIdName(), cards, game);
if (card != null) {
// If that card is a creature card of the chosen type, put it into your hand.
if (filterSubtype.match(card, game)) {
controller.moveCards(card, Zone.HAND, source, game);
// Otherwise, put it into your graveyard.
} else {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
if (card != null) {
// If that card is a creature card of the chosen type, put it into your hand.
if (filterSubtype.match(card, game)) {
controller.moveCards(card, Zone.HAND, source, game);
// Otherwise, put it into your graveyard.
} else {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
}
}
}
}
return true;
}
return false;

View file

@ -56,13 +56,13 @@ import mage.watchers.Watcher;
public class BoseijuWhoSheltersAll extends CardImpl {
public BoseijuWhoSheltersAll(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.addSuperType(SuperType.LEGENDARY);
// Boseiju, Who Shelters All enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {tap}, Pay 2 life: Add {C} to your mana pool. If that mana is spent on an instant or sorcery spell, that spell can't be countered by spells or abilities.
// {T}, Pay 2 life: Add {C} to your mana pool. If that mana is spent on an instant or sorcery spell, that spell can't be countered by spells or abilities.
Mana mana = Mana.ColorlessMana(1);
mana.setFlag(true); // used to indicate this mana ability
SimpleManaAbility ability = new SimpleManaAbility(Zone.BATTLEFIELD, mana, new TapSourceCost());

View file

@ -52,20 +52,20 @@ import mage.target.common.TargetControlledCreaturePermanent;
* @author Topher
*/
public class BurntOffering extends CardImpl {
public BurntOffering(UUID ownerID, CardSetInfo setInfo) {
super(ownerID, setInfo, new CardType[]{CardType.INSTANT},"{B}");
super(ownerID, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
//As an additional cost to cast Burnt Offering, sacrifice a creature.
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
//Add to your mana pool an amount of {B} and/or {R} equal to the sacrificed creature's converted mana cost.
this.getSpellAbility().addEffect(new BurntOfferingEffect());
}
public BurntOffering(final BurntOffering card) {
super(card);
}
@Override
public BurntOffering copy() {
return new BurntOffering(this);
@ -73,17 +73,17 @@ public class BurntOffering extends CardImpl {
}
class BurntOfferingEffect extends OneShotEffect {
public BurntOfferingEffect() {
super(Outcome.PutManaInPool);
this.staticText = "Add X mana in any combination of {B} and/or {R} to your mana pool,"
+ " where X is the sacrificed creature's converted mana cost";
}
public BurntOfferingEffect(final BurntOfferingEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
@ -94,20 +94,18 @@ class BurntOfferingEffect extends OneShotEffect {
choices.add("Black");
manaChoice.setChoices(choices);
manaChoice.setMessage("Select color of mana to add");
int xValue = getCost(source);
for(int i = 0; i < xValue; i++) {
for (int i = 0; i < xValue; i++) {
Mana mana = new Mana();
while(!player.choose(Outcome.Benefit, manaChoice, game)) {
if(!player.canRespond()) {
return false;
}
}
if(manaChoice.getChoice() == null) { //Can happen if player leaves game
if (!player.choose(Outcome.Benefit, manaChoice, game)) {
return false;
}
switch(manaChoice.getChoice()) {
if (manaChoice.getChoice() == null) { //Can happen if player leaves game
return false;
}
switch (manaChoice.getChoice()) {
case "Red":
mana.increaseRed();
break;
@ -126,18 +124,19 @@ class BurntOfferingEffect extends OneShotEffect {
public Effect copy() {
return new BurntOfferingEffect(this);
}
/**
* Helper method to determine the CMC of the sacrificed creature.
*
* @param sourceAbility
* @return
* @return
*/
private int getCost(Ability sourceAbility) {
for(Cost cost : sourceAbility.getCosts()) {
if(cost instanceof SacrificeTargetCost) {
for (Cost cost : sourceAbility.getCosts()) {
if (cost instanceof SacrificeTargetCost) {
SacrificeTargetCost sacrificeCost = (SacrificeTargetCost) cost;
int totalCMC = 0;
for(Permanent permanent : sacrificeCost.getPermanents()) {
for (Permanent permanent : sacrificeCost.getPermanents()) {
totalCMC += permanent.getConvertedManaCost();
}
return totalCMC;

View file

@ -107,13 +107,10 @@ class ButcherOfTheHordeEffect extends OneShotEffect {
abilities.add(LifelinkAbility.getInstance().getRule());
abilities.add(HasteAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
while (!abilityChoice.isChosen()) {
controller.choose(Outcome.AddAbility, abilityChoice, game);
if (!controller.canRespond()) {
return false;
}
controller.choose(Outcome.AddAbility, abilityChoice, game);
if (!abilityChoice.isChosen()) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;
if (VigilanceAbility.getInstance().getRule().equals(chosen)) {

View file

@ -27,6 +27,7 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -46,8 +47,6 @@ import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author jeffwadsworth
@ -128,13 +127,8 @@ class ChooseCreatureTypeEffect extends OneShotEffect { // code by LevelX2, but t
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
Choice typeChoice = new ChoiceCreatureType(mageObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
Choice typeChoice = new ChoiceCreatureType(mageObject);
if (controller != null && mageObject != null && controller.choose(outcome, typeChoice, game)) {
if (!game.isSimulation()) {
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
}

View file

@ -27,9 +27,7 @@
*/
package mage.cards.c;
import java.util.LinkedHashSet;
import java.util.UUID;
import java.util.stream.Collectors;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
@ -65,7 +63,7 @@ import mage.util.CardUtil;
public class CallousOppressor extends CardImpl {
public CallousOppressor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
this.subtype.add(SubType.CEPHALID);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
@ -97,20 +95,20 @@ public class CallousOppressor extends CardImpl {
}
class CallousOppressorFilter extends FilterCreaturePermanent {
public CallousOppressorFilter() {
super("creature that isn't of the chosen type");
}
public CallousOppressorFilter(final CallousOppressorFilter filter) {
super(filter);
}
@Override
public CallousOppressorFilter copy() {
return new CallousOppressorFilter(this);
}
@Override
public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
if (super.match(permanent, sourceId, playerId, game)) {
@ -122,7 +120,7 @@ class CallousOppressorFilter extends FilterCreaturePermanent {
}
return false;
}
}
class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
@ -156,10 +154,8 @@ class CallousOppressorChooseCreatureTypeEffect extends OneShotEffect {
if (opponent != null && mageObject != null) {
Choice typeChoice = new ChoiceCreatureType(mageObject);
typeChoice.setMessage("Choose creature type");
while (!opponent.choose(outcome, typeChoice, game)) {
if (!opponent.canRespond()) {
return false;
}
if (!opponent.choose(outcome, typeChoice, game)) {
return false;
}
if (typeChoice.getChoice() == null) {
return false;

View file

@ -27,6 +27,7 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@ -47,8 +48,6 @@ import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author Plopman
@ -152,14 +151,8 @@ class CarpetOfFlowersEffect extends ManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceColor choice = new ChoiceColor();
while (!choice.isChosen()) {
controller.choose(Outcome.Benefit, choice, game);
if (!controller.canRespond()) {
return false;
}
}
ChoiceColor choice = new ChoiceColor();
if (controller != null && controller.choose(Outcome.Benefit, choice, game)) {
int count = game.getBattlefield().count(filter, source.getSourceId(), source.getTargets().getFirstTarget(), game);
if (count > 0) {
Mana mana = new Mana();

View file

@ -0,0 +1,74 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
import mage.abilities.effects.common.ExileSourceEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class Carrionette extends CardImpl {
public Carrionette(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
this.subtype.add(SubType.SKELETON);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {2}{B}{B}: Exile Carrionette and target creature unless that creature's controller pays {2}. Activate this ability only if Carrionette is in your graveyard.
DoUnlessTargetPlayerOrTargetsControllerPaysEffect effect = new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new ExileTargetEffect(), new ManaCostsImpl("{2}"));
effect.addEffect(new ExileSourceEffect());
effect.setText("Exile {this} and target creature unless that creature's controller pays {2}. Activate this ability only if {this} is in your graveyard");
Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, effect, new ManaCostsImpl("{2}{B}{B}"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public Carrionette(final Carrionette card) {
super(card);
}
@Override
public Carrionette copy() {
return new Carrionette(this);
}
}

View file

@ -182,12 +182,7 @@ class ChromeMoxManaEffect extends ManaEffect {
if (choice.getChoices().size() == 1) {
choice.setChoice(choice.getChoices().iterator().next());
} else {
while (!player.choose(outcome, choice, game)) {
if (!player.canRespond()) {
return false;
}
}
if (choice.getChoice() == null) {
if (!player.choose(outcome, choice, game)) {
return false;
}
}

View file

@ -56,7 +56,7 @@ import mage.target.targetpointer.FixedTarget;
public class Clockspinning extends CardImpl {
public Clockspinning(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}");
// Buyback {3}
this.addAbility(new BuybackAbility("{3}"));
@ -106,8 +106,12 @@ class ClockspinningAddOrRemoveCounterEffect extends OneShotEffect {
}
choice.setChoices(choices);
choice.setMessage("Choose a counter type to add to " + permanent.getName());
controller.choose(Outcome.Neutral, choice, game);
counterName = choice.getChoice();
if (controller.choose(Outcome.Neutral, choice, game)) {
counterName = choice.getChoice();
} else {
return null;
}
} else {
for (Counter counter : permanent.getCounters(game).values()) {
if (counter.getCount() > 0) {
@ -134,8 +138,11 @@ class ClockspinningAddOrRemoveCounterEffect extends OneShotEffect {
}
choice.setChoices(choices);
choice.setMessage("Choose a counter type to add to " + card.getName());
controller.choose(Outcome.Neutral, choice, game);
counterName = choice.getChoice();
if (controller.choose(Outcome.Neutral, choice, game)) {
counterName = choice.getChoice();
} else {
return null;
}
} else {
for (Counter counter : card.getCounters(game).values()) {
if (counter.getCount() > 0) {

View file

@ -55,7 +55,7 @@ import mage.players.Player;
public class CoalitionRelic extends CardImpl {
public CoalitionRelic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {tap}: Add one mana of any color to your mana pool.
this.addAbility(new AnyColorManaAbility());
@ -101,11 +101,8 @@ class CoalitionRelicEffect extends OneShotEffect {
Mana mana = new Mana();
ChoiceColor choice = new ChoiceColor();
for (int i = 0; i < chargeCounters; i++) {
while (!choice.isChosen()) {
if (!player.canRespond()) {
return false;
}
player.choose(outcome, choice, game);
if (!player.choose(outcome, choice, game)) {
return false;
}
choice.increaseMana(mana);
choice.clearChoice();

View file

@ -102,10 +102,8 @@ class ConundrumSphinxEffect extends OneShotEffect {
if (player.getLibrary().hasCards()) {
cardChoice.clearChoice();
cardChoice.setMessage("Name a card");
while (!player.choose(Outcome.DrawCard, cardChoice, game) && player.canRespond()) {
if (!player.canRespond()) {
continue Players;
}
if (!player.choose(Outcome.DrawCard, cardChoice, game) && player.canRespond()) {
continue Players;
}
String cardName = cardChoice.getChoice();
game.informPlayers(sourceObject.getLogName() + ", player: " + player.getLogName() + ", named: [" + cardName + ']');

View file

@ -138,37 +138,34 @@ class CorruptedGrafstoneManaEffect extends ManaEffect {
}
if (!choice.getChoices().isEmpty()) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
if (choice.getChoices().size() == 1) {
choice.setChoice(choice.getChoices().iterator().next());
} else {
player.choose(outcome, choice, game);
}
if (choice.getChoice() != null) {
Mana computedMana = new Mana();
switch (choice.getChoice()) {
case "Black":
computedMana.setBlack(1);
break;
case "Blue":
computedMana.setBlue(1);
break;
case "Red":
computedMana.setRed(1);
break;
case "Green":
computedMana.setGreen(1);
break;
case "White":
computedMana.setWhite(1);
break;
if (!player.choose(outcome, choice, game)) {
return false;
}
checkToFirePossibleEvents(computedMana, game, source);
player.getManaPool().addMana(computedMana, game, source);
} else {
return false;
}
Mana computedManaHere = new Mana();
switch (choice.getChoice()) {
case "Black":
computedManaHere.setBlack(1);
break;
case "Blue":
computedManaHere.setBlue(1);
break;
case "Red":
computedManaHere.setRed(1);
break;
case "Green":
computedManaHere.setGreen(1);
break;
case "White":
computedManaHere.setWhite(1);
break;
}
checkToFirePossibleEvents(computedManaHere, game, source);
player.getManaPool().addMana(computedManaHere, game, source);
}
}
return true;

View file

@ -61,9 +61,10 @@ public class CovetedPeacock extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Coveted Peacock attacks, you may goad target creature defending player controls.
Ability ability = new AttacksTriggeredAbility(new GoadTargetEffect(), true, "Whenever {this} attacks, you may goad target creature defending player controls");
Ability ability = new AttacksTriggeredAbility(new GoadTargetEffect(), true, "Whenever {this} attacks, you may goad target creature defending player controls.");
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls")));
originalId = ability.getOriginalId();
this.addAbility(ability);
}
public CovetedPeacock(final CovetedPeacock card) {

View file

@ -27,6 +27,7 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
@ -43,8 +44,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
@ -52,7 +51,7 @@ import java.util.UUID;
public class CranialExtraction extends CardImpl {
public CranialExtraction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
this.subtype.add(SubType.ARCANE);
/* Name a nonland card. Search target player's graveyard, hand, and library for
@ -92,10 +91,8 @@ class CranialExtractionEffect extends SearchTargetGraveyardHandLibraryForCardNam
cardChoice.clearChoice();
cardChoice.setMessage("Name a nonland card");
while (!controller.choose(Outcome.Exile, cardChoice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Exile, cardChoice, game)) {
return false;
}
String cardName = cardChoice.getChoice();
MageObject sourceObject = game.getObject(source.getSourceId());

View file

@ -51,8 +51,7 @@ import mage.players.Player;
public class CreepingRenaissance extends CardImpl {
public CreepingRenaissance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}");
// Choose a permanent type. Return all cards of the chosen type from your graveyard to your hand.
this.getSpellAbility().addEffect(new CreepingRenaissanceEffect());
@ -95,25 +94,24 @@ class CreepingRenaissanceEffect extends OneShotEffect {
typeChoice.getChoices().add(CardType.LAND.toString());
typeChoice.getChoices().add(CardType.PLANESWALKER.toString());
while (controller.canRespond() && !controller.choose(Outcome.ReturnToHand, typeChoice, game)) {
}
String typeName = typeChoice.getChoice();
CardType chosenType = null;
for (CardType cardType : CardType.values()) {
if (cardType.toString().equals(typeName)) {
chosenType = cardType;
}
}
if (chosenType != null) {
for (Card card : controller.getGraveyard().getCards(game)) {
if (card.getCardType().contains(chosenType)) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
if (controller.choose(Outcome.ReturnToHand, typeChoice, game)) {
String typeName = typeChoice.getChoice();
CardType chosenType = null;
for (CardType cardType : CardType.values()) {
if (cardType.toString().equals(typeName)) {
chosenType = cardType;
}
}
return true;
if (chosenType != null) {
for (Card card : controller.getGraveyard().getCards(game)) {
if (card.getCardType().contains(chosenType)) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
}
}
return true;
}
}
}
}
return false;
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -43,8 +42,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
@ -54,12 +53,12 @@ import mage.players.Player;
/**
*
* @author LoneFox
*
*/
public class CrosisThePurger extends CardImpl {
public CrosisThePurger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{B}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.DRAGON);
this.power = new MageInt(6);
@ -69,7 +68,7 @@ public class CrosisThePurger extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Crosis, the Purger deals combat damage to a player, you may pay {2}{B}. If you do, choose a color, then that player reveals his or her hand and discards all cards of that color.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DoIfCostPaid(new CrosisThePurgerEffect(),
new ManaCostsImpl("{2}{B}")), false, true));
new ManaCostsImpl("{2}{B}")), false, true));
}
public CrosisThePurger(final CrosisThePurger card) {
@ -101,23 +100,23 @@ class CrosisThePurgerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if(player != null) {
if (player != null) {
ChoiceColor choice = new ChoiceColor();
player.choose(outcome, choice, game);
if(choice.getColor() != null) {
if (choice.isChosen()) {
game.informPlayers(new StringBuilder(player.getLogName()).append(" chooses ").append(choice.getColor()).toString());
Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
damagedPlayer.revealCards("hand of " + damagedPlayer.getName(), damagedPlayer.getHand(), game);
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(choice.getColor()));
List<Card> toDiscard = new ArrayList<>();
for(UUID cardId : damagedPlayer.getHand()) {
for (UUID cardId : damagedPlayer.getHand()) {
Card card = game.getCard(cardId);
if(filter.match(card, game)) {
if (filter.match(card, game)) {
toDiscard.add(card);
}
}
for(Card card: toDiscard) {
for (Card card : toDiscard) {
damagedPlayer.discard(card, source, game);
}
return true;

View file

@ -52,7 +52,7 @@ import mage.target.common.TargetCreatureOrPlayer;
public class CursedScroll extends CardImpl {
public CursedScroll(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {3}, {T}: Name a card. Reveal a card at random from your hand. If it's the named card, Cursed Scroll deals 2 damage to target creature or player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new NameACardEffect(NameACardEffect.TypeOfName.ALL), new ManaCostsImpl("{3}"));
@ -92,6 +92,9 @@ class CursedScrollEffect extends OneShotEffect {
if (!controller.getHand().isEmpty()) {
Cards revealed = new CardsImpl();
Card card = controller.getHand().getRandom(game);
if (card == null) {
return false;
}
revealed.add(card);
controller.revealCards(sourceObject.getIdName(), revealed, game);
if (card.getName().equals(cardName)) {

View file

@ -39,8 +39,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ColorPredicate;
@ -54,7 +54,7 @@ import mage.players.Player;
public class DarigaazTheIgniter extends CardImpl {
public DarigaazTheIgniter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{R}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}{G}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.DRAGON);
this.power = new MageInt(6);
@ -98,30 +98,20 @@ class DarigaazTheIgniterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceColor choice = new ChoiceColor(true);
while (!choice.isChosen()) {
controller.choose(outcome, choice, game);
if (!controller.canRespond()) {
return false;
}
}
if (choice.getColor() != null) {
game.informPlayers(controller.getLogName() + " chooses " + choice.getColor());
Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (damagedPlayer != null) {
damagedPlayer.revealCards("hand of " + damagedPlayer.getName(), damagedPlayer.getHand(), game);
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(choice.getColor()));
int damage = damagedPlayer.getHand().count(filter, source.getSourceId(), source.getControllerId(), game);
if (damage > 0) {
damagedPlayer.damage(damage, source.getSourceId(), game, false, true);
}
ChoiceColor choice = new ChoiceColor(true);
if (controller != null && controller.choose(outcome, choice, game)) {
game.informPlayers(controller.getLogName() + " chooses " + choice.getColor());
Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (damagedPlayer != null) {
damagedPlayer.revealCards("hand of " + damagedPlayer.getName(), damagedPlayer.getHand(), game);
FilterCard filter = new FilterCard();
filter.add(new ColorPredicate(choice.getColor()));
int damage = damagedPlayer.getHand().count(filter, source.getSourceId(), source.getControllerId(), game);
if (damage > 0) {
damagedPlayer.damage(damage, source.getSourceId(), game, false, true);
}
}
return true;
}
return false;
}

View file

@ -38,8 +38,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -135,10 +135,8 @@ class DawnsReflectionManaEffect extends ManaEffect {
Mana mana = new Mana();
for (int i = 0; i < x; i++) {
ChoiceColor choiceColor = new ChoiceColor();
while (!controller.choose(Outcome.Benefit, choiceColor, game)) {
if (!controller.isInGame()) {
return false;
}
if (!controller.choose(Outcome.Benefit, choiceColor, game)) {
return false;
}
choiceColor.increaseMana(mana);
}

View file

@ -43,13 +43,13 @@ import mage.constants.SubType;
public class DeadbridgeGoliath extends CardImpl {
public DeadbridgeGoliath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.INSECT);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Scavenge {4}{G}{G}
// Scavenge {4}{G}{G} ({4}{G}{G} , Exile this card from your graveyard: Put a number of +1/+1 counter's equal to this card's power on target creature. Scavenge only as a sorcery.)
this.addAbility(new ScavengeAbility(new ManaCostsImpl("{4}{G}{G}")));
}

View file

@ -48,7 +48,7 @@ import mage.players.Player;
public class DemonicConsultation extends CardImpl {
public DemonicConsultation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
// Name a card. Exile the top six cards of your library, then reveal cards from the top of your library until you reveal the named card. Put that card into your hand and exile all other cards revealed this way.
this.getSpellAbility().addEffect(new DemonicConsultationEffect());
@ -88,10 +88,8 @@ class DemonicConsultationEffect extends OneShotEffect {
// Name a card.
Choice choice = new ChoiceImpl();
choice.setChoices(CardRepository.instance.getNames());
while (!controller.choose(Outcome.Benefit, choice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Benefit, choice, game)) {
return false;
}
String name = choice.getChoice();
game.informPlayers("Card named: " + name);

View file

@ -47,7 +47,7 @@ import mage.target.TargetCard;
public class DeployTheGatewatch extends CardImpl {
public DeployTheGatewatch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{W}{W}");
// Look at the top seven cards of your library. Put up to two planeswalker cards from among them onto the battlefield.
// Put the rest on the bottom of your library in a random order.
@ -90,15 +90,15 @@ class DeployTheGatewatchEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
// Look at the top seven cards of your library.
Cards cards = new CardsImpl();
boolean planeswalkerIncluded = false;
for (int i = 0; i < 7; i++) {
Card card = player.getLibrary().removeFromTop(game);
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
if (filter.match(card, game)) {
@ -106,26 +106,20 @@ class DeployTheGatewatchEffect extends OneShotEffect {
}
}
}
player.lookAtCards("Deploy the Gatewatch", cards, game);
controller.lookAtCards("Deploy the Gatewatch", cards, game);
// Put up to two planeswalker cards from among them onto the battlefield.
if (planeswalkerIncluded) {
TargetCard target = new TargetCard(0, 2, Zone.LIBRARY, filter);
if (player.choose(Outcome.DrawCard, cards, target, game)) {
if (controller.choose(Outcome.DrawCard, cards, target, game)) {
Cards pickedCards = new CardsImpl(target.getTargets());
cards.removeAll(pickedCards);
player.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game);
controller.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game);
}
}
// Put the rest on the bottom of your library in a random order
while (!cards.isEmpty()) {
Card card = cards.getRandom(game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
}

View file

@ -27,6 +27,7 @@
*/
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
@ -43,8 +44,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author emerald000
@ -52,8 +51,7 @@ import java.util.UUID;
public class DistantMelody extends CardImpl {
public DistantMelody(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}");
// Choose a creature type. Draw a card for each permanent you control of that type.
this.getSpellAbility().addEffect(new DistantMelodyEffect());
@ -70,31 +68,26 @@ public class DistantMelody extends CardImpl {
}
class DistantMelodyEffect extends OneShotEffect {
DistantMelodyEffect() {
super(Outcome.DrawCard);
this.staticText = "Choose a creature type. Draw a card for each permanent you control of that type";
}
DistantMelodyEffect(final DistantMelodyEffect effect) {
super(effect);
}
@Override
public DistantMelodyEffect copy() {
return new DistantMelodyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;
}
}
Player controller = game.getPlayer(source.getControllerId());
Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
if (controller != null && controller.choose(Outcome.BoostCreature, typeChoice, game)) {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
filter.add(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice())));
return new DrawCardSourceControllerEffect(new PermanentsOnBattlefieldCount(filter)).apply(game, source);

View file

@ -41,8 +41,8 @@ import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
@ -56,7 +56,7 @@ public class DiviningWitch extends CardImpl {
public DiviningWitch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SPELLSHAPER);
this.power = new MageInt(1);
@ -78,7 +78,7 @@ public class DiviningWitch extends CardImpl {
return new DiviningWitch(this);
}
private static class DiviningWitchEffect extends OneShotEffect {
private static class DiviningWitchEffect extends OneShotEffect {
DiviningWitchEffect() {
super(Outcome.Benefit);
@ -102,10 +102,8 @@ public class DiviningWitch extends CardImpl {
// Name a card.
Choice choice = new ChoiceImpl();
choice.setChoices(CardRepository.instance.getNames());
while (!controller.choose(Outcome.Benefit, choice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Benefit, choice, game)) {
return false;
}
String name = choice.getChoice();
game.informPlayers("Card named: " + name);
@ -137,5 +135,3 @@ public class DiviningWitch extends CardImpl {
}
}
}

View file

@ -44,6 +44,7 @@ import mage.game.stack.StackObject;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.game.permanent.Permanent;
/**
*
@ -98,9 +99,16 @@ class DjinnIlluminatusGainReplicateEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Permanent djinn = game.getPermanent(source.getSourceId());
if (djinn == null) {
return false;
}
for (StackObject stackObject : game.getStack()) {
// only spells cast, so no copies of spells
if ((stackObject instanceof Spell) && !stackObject.isCopy() && stackObject.getControllerId().equals(source.getControllerId())) {
if ((stackObject instanceof Spell)
&& !stackObject.isCopy()
&& stackObject.getControllerId().equals(source.getControllerId())
&& djinn.getControllerId().equals(source.getControllerId())) { // verify that the controller of the djinn cast that spell
Spell spell = (Spell) stackObject;
if (filter.match(stackObject, game)) {
ReplicateAbility replicateAbility = replicateAbilities.computeIfAbsent(spell.getId(), k -> new ReplicateAbility(spell.getCard(), spell.getSpellAbility().getManaCosts().getText()));

View file

@ -41,9 +41,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -109,8 +109,7 @@ class BecomesColorOrColorsEnchantedEffect extends OneShotEffect {
}
}
ChoiceColor choiceColor = new ChoiceColor();
controller.choose(Outcome.Benefit, choiceColor, game);
if (!controller.canRespond()) {
if (!controller.choose(Outcome.Benefit, choiceColor, game)) {
return false;
}
if (!game.isSimulation()) {

View file

@ -40,8 +40,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
@ -55,7 +55,7 @@ import mage.players.Player;
public class DromarTheBanisher extends CardImpl {
public DromarTheBanisher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{U}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{U}{B}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.DRAGON);
@ -100,8 +100,7 @@ class DromarTheBanisherEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
ChoiceColor choice = new ChoiceColor();
player.choose(outcome, choice, game);
if (choice.getColor() != null) {
if (player.choose(outcome, choice, game)) {
game.informPlayers(player.getLogName() + " chooses " + choice.getChoice());
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new ColorPredicate(choice.getColor()));

View file

@ -27,6 +27,9 @@
*/
package mage.cards.d;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -41,8 +44,8 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
@ -51,10 +54,6 @@ import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LoneFox
@ -62,7 +61,7 @@ import java.util.UUID;
public class DwarvenArmorer extends CardImpl {
public DwarvenArmorer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.DWARF);
this.power = new MageInt(0);
this.toughness = new MageInt(2);
@ -95,8 +94,8 @@ class DwarvenArmorerEffect extends OneShotEffect {
}
public DwarvenArmorerEffect() {
super(Outcome.Benefit);
staticText = "Put a +0/+1 counter or a +1/+0 counter on target creature.";
super(Outcome.Benefit);
staticText = "Put a +0/+1 counter or a +1/+0 counter on target creature.";
}
public DwarvenArmorerEffect(final DwarvenArmorerEffect effect) {
@ -111,19 +110,16 @@ class DwarvenArmorerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if(controller != null) {
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose type of counter to add");
choice.setChoices(choices);
while(!controller.choose(outcome, choice, game)) {
if(controller.canRespond()) {
return false;
}
if (controller.choose(outcome, choice, game)) {
Counter counter = choice.getChoice().equals("+0/+1") ? CounterType.P0P1.createInstance() : CounterType.P1P0.createInstance();
Effect effect = new AddCountersTargetEffect(counter);
effect.setTargetPointer(new FixedTarget(this.getTargetPointer().getFirst(game, source)));
return effect.apply(game, source);
}
Counter counter = choice.getChoice().equals("+0/+1") ? CounterType.P0P1.createInstance() : CounterType.P1P0.createInstance();
Effect effect = new AddCountersTargetEffect(counter);
effect.setTargetPointer(new FixedTarget(this.getTargetPointer().getFirst(game, source)));
return effect.apply(game, source);
}
return false;
}

View file

@ -31,23 +31,23 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
import mage.Mana;
import mage.constants.SubType;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfPreCombatMainTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
/**
*
@ -125,13 +125,10 @@ class ElementalResonanceEffect extends OneShotEffect {
Choice choice = new ChoiceImpl();
choice.setMessage("Choose a mana combination");
choice.getChoices().addAll(manaOptions);
while (!choice.isChosen()) {
controller.choose(Outcome.PutManaInPool, choice, game);
if (!controller.canRespond()) {
return false;
}
manaToAdd = choice.getChoice();
if (!controller.choose(Outcome.PutManaInPool, choice, game)) {
return false;
}
manaToAdd = choice.getChoice();
} else if (manaOptions.size() == 1) {
manaToAdd = manaOptions.get(0);
}

View file

@ -79,7 +79,7 @@ class ElsewhereFlaskEffect extends OneShotEffect {
public ElsewhereFlaskEffect() {
super(Outcome.Neutral);
this.staticText = "Choose a basic land type. Each land you control becomes that type until end of turn";
this.staticText = "Choose a basic land type. Each land you control becomes that type until end of turn";
}
public ElsewhereFlaskEffect(final ElsewhereFlaskEffect effect) {
@ -94,11 +94,9 @@ class ElsewhereFlaskEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
Choice choice = new ChoiceBasicLandType();
if (player.choose(Outcome.Neutral, choice, game)) {
game.getState().setValue(source.getSourceId().toString() + "_ElsewhereFlask", choice.getChoice());
}
Choice choice = new ChoiceBasicLandType();
if (player != null && player.choose(Outcome.Neutral, choice, game)) {
game.getState().setValue(source.getSourceId().toString() + "_ElsewhereFlask", choice.getChoice());
game.addEffect(new ElsewhereFlaskContinuousEffect(), source);
return true;
}

View file

@ -54,7 +54,7 @@ import mage.players.Player;
public class ElvishSoultiller extends CardImpl {
public ElvishSoultiller(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.MUTANT);
this.power = new MageInt(5);
@ -95,13 +95,8 @@ class ElvishSoultillerEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
Choice typeChoice = new ChoiceCreatureType(mageObject);
while (!controller.choose(outcome, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
Choice typeChoice = new ChoiceCreatureType(mageObject);
if (controller != null && mageObject != null && controller.choose(outcome, typeChoice, game)) {
if (!game.isSimulation()) {
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice());
}

View file

@ -28,14 +28,18 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.condition.common.CitysBlessingCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.keyword.AscendEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.designations.DesignationType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetNonlandPermanent;
/**
@ -51,12 +55,7 @@ public class ExpelFromOrazca extends CardImpl {
this.getSpellAbility().addEffect(new AscendEffect());
// Return target nonland permanent to its owner's hand. If you have the city's blessing, you may put that permanent on top of its owner's library instead.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new PutOnLibraryTargetEffect(true),
new ReturnToHandTargetEffect(),
CitysBlessingCondition.instance,
"Return target nonland permanent to its owner's hand. If you have the city's blessing, you may put that permanent on top of its owner's library instead"
));
this.getSpellAbility().addEffect(new ExpelFromOrazcaEffect());
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
}
@ -69,3 +68,39 @@ public class ExpelFromOrazca extends CardImpl {
return new ExpelFromOrazca(this);
}
}
class ExpelFromOrazcaEffect extends OneShotEffect {
public ExpelFromOrazcaEffect() {
super(Outcome.ReturnToHand);
this.staticText = "Return target nonland permanent to its owner's hand. If you have the city's blessing, you may put that permanent on top of its owner's library instead";
}
public ExpelFromOrazcaEffect(final ExpelFromOrazcaEffect effect) {
super(effect);
}
@Override
public ExpelFromOrazcaEffect copy() {
return new ExpelFromOrazcaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetPermanent != null) {
if (controller.hasDesignation(DesignationType.CITYS_BLESSING)
&& controller.chooseUse(outcome, "Put " + targetPermanent.getIdName() + " on top of its owner's library instead?", source, game)) {
controller.moveCards(targetPermanent, Zone.LIBRARY, source, game);
} else {
controller.moveCards(targetPermanent, Zone.HAND, source, game);
}
}
return true;
}
return false;
}
}

View file

@ -51,7 +51,7 @@ import mage.players.Player;
public class Extinction extends CardImpl {
public Extinction(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Destroy all creatures of the creature type of your choice.
this.getSpellAbility().addEffect(new ExtinctionEffect());
@ -82,16 +82,9 @@ class ExtinctionEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (player != null) {
Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(outcome, typeChoice, game)) {
if (!player.canRespond()) {
return false;
}
}
if (typeChoice.getChoice() != null) {
game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
}
Choice typeChoice = new ChoiceCreatureType(sourceObject);
if (player != null && player.choose(outcome, typeChoice, game)) {
game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice());
FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent();
filterCreaturePermanent.add(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice())));
for (Permanent creature : game.getBattlefield().getActivePermanents(filterCreaturePermanent, source.getSourceId(), game)) {

View file

@ -92,11 +92,8 @@ class FaithsShieldEffect extends OneShotEffect {
if (controller != null && mageObject != null) {
if (FatefulHourCondition.instance.apply(game, source)) {
ChoiceColor choice = new ChoiceColor();
while (!choice.isChosen()) {
controller.choose(Outcome.Protect, choice, game);
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Protect, choice, game)) {
return false;
}
if (choice.getColor() != null) {
game.informPlayers(mageObject.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice());

View file

@ -27,6 +27,9 @@
*/
package mage.cards.f;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@ -42,10 +45,6 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LoneFox
@ -53,7 +52,7 @@ import java.util.UUID;
public class Fatespinner extends CardImpl {
public Fatespinner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
@ -105,10 +104,8 @@ class FatespinnerChooseEffect extends OneShotEffect {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose phase or step to skip");
choice.setChoices(choices);
while (!player.choose(outcome, choice, game)) {
if (!player.canRespond()) {
return false;
}
if (!player.choose(outcome, choice, game)) {
return false;
}
String chosenPhase = choice.getChoice();
game.informPlayers(player.getLogName() + " has chosen to skip " + chosenPhase.toLowerCase() + '.');

View file

@ -27,6 +27,9 @@
*/
package mage.cards.f;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -43,18 +46,14 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LoneFox
@ -62,7 +61,7 @@ import java.util.UUID;
public class FlowstoneSculpture extends CardImpl {
public FlowstoneSculpture(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{6}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}");
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
@ -100,7 +99,7 @@ class FlowstoneSculptureEffect extends OneShotEffect {
}
public FlowstoneSculptureEffect(final FlowstoneSculptureEffect effect) {
super(effect);
super(effect);
}
@Override
@ -111,36 +110,33 @@ class FlowstoneSculptureEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if(controller != null) {
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose ability to add");
choice.setChoices(choices);
while(!controller.choose(outcome, choice, game)) {
if(controller.canRespond()) {
return false;
}
}
if (!controller.choose(outcome, choice, game)) {
return false;
}
String chosen = choice.getChoice();
if(chosen.equals("+1/+1 counter")) {
return new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source);
}
else {
Ability gainedAbility;
switch (chosen) {
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "First strike":
gainedAbility = FirstStrikeAbility.getInstance();
break;
default:
gainedAbility = TrampleAbility.getInstance();
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield), source);
return true;
}
String chosen = choice.getChoice();
if (chosen.equals("+1/+1 counter")) {
return new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source);
} else {
Ability gainedAbility;
switch (chosen) {
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "First strike":
gainedAbility = FirstStrikeAbility.getInstance();
break;
default:
gainedAbility = TrampleAbility.getInstance();
break;
}
game.addEffect(new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield), source);
return true;
}
}
return false;

View file

@ -51,7 +51,7 @@ import mage.util.CardUtil;
public class Fluctuator extends CardImpl {
public Fluctuator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Cycling abilities you activate cost you up to {2} less to activate.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new FluctuatorEffect()));
@ -112,7 +112,8 @@ class FluctuatorEffect extends CostModificationEffectImpl {
if (controller.choose(Outcome.Benefit, choice, game)) {
reduce = Integer.parseInt(choice.getChoice());
} else {
return false;
}
}
CardUtil.reduceCost(abilityToModify, reduce);

View file

@ -56,7 +56,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class FoodChain extends CardImpl {
public FoodChain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
// Exile a creature you control: Add X mana of any one color to your mana pool, where X is the exiled creature's converted mana cost plus one. Spend this mana only to cast creature spells.
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new FoodChainManaEffect(), new ExileTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature you control"), true)));
@ -114,8 +114,7 @@ class FoodChainManaEffect extends ManaEffect {
}
}
ChoiceColor choice = new ChoiceColor();
controller.choose(Outcome.PutManaInPool, choice, game);
if (choice.getColor() == null) {
if (!controller.choose(Outcome.PutManaInPool, choice, game)) {
return false;
}
Mana chosen = choice.getMana(manaCostExiled + 1);

View file

@ -46,7 +46,7 @@ import mage.target.common.TargetCreaturePermanent;
public class FriendlyFire extends CardImpl {
public FriendlyFire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}");
// Target creature's controller reveals a card at random from his or her hand. Friendly Fire deals damage to that creature and that player equal to the revealed card's converted mana cost.
this.getSpellAbility().addEffect(new FriendlyFireEffect());
@ -92,12 +92,14 @@ class FriendlyFireEffect extends OneShotEffect {
if (!controllerOfTargetCreature.getHand().isEmpty()) {
Cards cards = new CardsImpl();
Card card = controllerOfTargetCreature.getHand().getRandom(game);
cards.add(card);
controllerOfTargetCreature.revealCards(sourceObject.getName(), cards, game);
int damage = card.getConvertedManaCost();
targetCreature.damage(damage, source.getSourceId(), game, false, true);
controllerOfTargetCreature.damage(damage, source.getSourceId(), game, false, true);
return true;
if (card != null) {
cards.add(card);
controllerOfTargetCreature.revealCards(sourceObject.getName(), cards, game);
int damage = card.getConvertedManaCost();
targetCreature.damage(damage, source.getSourceId(), game, false, true);
controllerOfTargetCreature.damage(damage, source.getSourceId(), game, false, true);
return true;
}
}
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author spjspj
*/
public class FruitcakeElemental extends CardImpl {
public FruitcakeElemental(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(7);
this.toughness = new MageInt(7);
// Fruitcake Elemental is indestructible.
this.addAbility(IndestructibleAbility.getInstance());
// At the end of your turn, Fruitcake Elemental deals 7 damage to you.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new DamageControllerEffect(7), TargetController.YOU, false));
// {3}: Target player gains control of Fruitcake Elemental.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new FruitcakeElementalEffect(), new ManaCostsImpl("{3}"));
ability.addTarget(new TargetPlayer(1, 1, false));
this.addAbility(ability);
}
public FruitcakeElemental(final FruitcakeElemental card) {
super(card);
}
@Override
public FruitcakeElemental copy() {
return new FruitcakeElemental(this);
}
}
class FruitcakeElementalEffect extends OneShotEffect {
public FruitcakeElementalEffect() {
super(Outcome.Discard);
this.staticText = "Target player gains control of {this}.";
}
public FruitcakeElementalEffect(final FruitcakeElementalEffect effect) {
super(effect);
}
@Override
public FruitcakeElementalEffect copy() {
return new FruitcakeElementalEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null && permanent != null) {
ContinuousEffect effect = new FruitcakeElementalControlSourceEffect();
game.addEffect(effect, source);
game.informPlayers(permanent.getName() + " is now controlled by " + player.getLogName());
return true;
}
return false;
}
}
class FruitcakeElementalControlSourceEffect extends ContinuousEffectImpl {
public FruitcakeElementalControlSourceEffect() {
super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
}
public FruitcakeElementalControlSourceEffect(final FruitcakeElementalControlSourceEffect effect) {
super(effect);
}
@Override
public FruitcakeElementalControlSourceEffect copy() {
return new FruitcakeElementalControlSourceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null && player != null) {
permanent.changeControllerId(player.getId(), game);
} else {
// no valid target exists, effect can be discarded
discard();
}
return true;
}
}

View file

@ -74,7 +74,7 @@ public class GabrielAngelfire extends CardImpl {
}
class GabrielAngelfireGainAbilityEffect extends GainAbilitySourceEffect {
private static final Set<String> choices = new LinkedHashSet<>();
private boolean sameStep = true;
@ -112,6 +112,7 @@ class GabrielAngelfireGainAbilityEffect extends GainAbilitySourceEffect {
return false;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
Player controller = game.getPlayer(source.getControllerId());
@ -121,9 +122,6 @@ class GabrielAngelfireGainAbilityEffect extends GainAbilitySourceEffect {
choice.setChoices(choices);
if (controller.choose(outcome, choice, game)) {
switch (choice.getChoice()) {
// case "Flying":
// ability = FlyingAbility.getInstance();
// break;
case "First strike":
ability = FirstStrikeAbility.getInstance();
break;
@ -137,6 +135,8 @@ class GabrielAngelfireGainAbilityEffect extends GainAbilitySourceEffect {
ability = FlyingAbility.getInstance();
break;
}
} else {
discard();
}
}
}

View file

@ -57,20 +57,20 @@ import mage.target.common.TargetControlledPermanent;
public class GoblinClearcutter extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Forest");
static {
static {
filter.add(new SubtypePredicate(SubType.FOREST));
}
public GoblinClearcutter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.GOBLIN);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G} to your mana pool.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinClearCutterEffect(), new TapSourceCost());
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinClearCutterEffect(), new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
}
@ -85,7 +85,6 @@ public class GoblinClearcutter extends CardImpl {
}
}
class GoblinClearCutterEffect extends OneShotEffect {
public GoblinClearCutterEffect() {
@ -105,7 +104,7 @@ class GoblinClearCutterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null){
if (player != null) {
Choice manaChoice = new ChoiceImpl();
Set<String> choices = new LinkedHashSet<>();
choices.add("Red");
@ -113,14 +112,9 @@ class GoblinClearCutterEffect extends OneShotEffect {
manaChoice.setChoices(choices);
manaChoice.setMessage("Select color of mana to add");
for (int i = 0; i < 3; i++){
for (int i = 0; i < 3; i++) {
Mana mana = new Mana();
while (!player.choose(Outcome.Benefit, manaChoice, game)) {
if (!player.canRespond()) {
return false;
}
}
if (manaChoice.getChoice() == null) { // can happen if player leaves game
if (!player.choose(Outcome.Benefit, manaChoice, game)) {
return false;
}
switch (manaChoice.getChoice()) {

View file

@ -46,9 +46,9 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
@ -114,7 +114,9 @@ class GolemArtisanEffect extends OneShotEffect {
abilities.add(TrampleAbility.getInstance().getRule());
abilities.add(HasteAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
playerControls.choose(Outcome.AddAbility, abilityChoice, game);
if (!playerControls.choose(Outcome.AddAbility, abilityChoice, game)) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;

View file

@ -142,11 +142,7 @@ class GontiLordOfLuxuryEffect extends OneShotEffect {
}
}
// then put the rest on the bottom of that library in a random order
while (!topCards.isEmpty() && controller.isInGame()) {
Card libCard = topCards.getRandom(game);
topCards.remove(libCard);
controller.moveCardToLibraryWithInfo(libCard, source.getSourceId(), game, Zone.LIBRARY, false, false);
}
controller.putCardsOnBottomOfLibrary(topCards, game, source, false);
return true;
}

View file

@ -66,7 +66,7 @@ public class GremlinMine extends CardImpl {
}
public GremlinMine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {1}, {tap}, Sacrifice Gremlin Mine: Gremlin Mine deals 4 damage to target artifact creature.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(4), new ManaCostsImpl("{1}"));
@ -110,20 +110,17 @@ class GremlinMineEffect extends OneShotEffect {
if (player != null && permanent != null) {
int existingCount = permanent.getCounters(game).getCount(CounterType.CHARGE);
if (existingCount > 0) {
Choice choice = new ChoiceImpl();
choice.setMessage("Select number of charge counters to remove:");
for (Integer i = 0; i <= existingCount; i++) {
choice.getChoices().add(i.toString());
}
int amount = 0;
if (player.choose(Outcome.Detriment, choice, game)) {
amount = Integer.parseInt(choice.getChoice());
permanent.removeCounters(CounterType.CHARGE.getName(), Integer.parseInt(choice.getChoice()), game);
return true;
}
permanent.removeCounters(CounterType.CHARGE.getName(), amount, game);
return false;
}
return true;
}

View file

@ -99,11 +99,9 @@ class HallOfGemstoneEffect extends ReplacementEffectImpl {
MageObject mageObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (player != null && mageObject != null) {
ChoiceColor choice = new ChoiceColor();
while (!choice.isChosen()) {
player.choose(outcome, choice, game);
if (!player.canRespond()) {
return;
}
if (!player.choose(outcome, choice, game)) {
discard();
return;
}
if (!game.isSimulation()) {
game.informPlayers(mageObject.getLogName() + ": " + player.getLogName() + " has chosen " + choice.getChoice());

View file

@ -55,7 +55,7 @@ import mage.players.Player;
public class HarshMercy extends CardImpl {
public HarshMercy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}");
// Each player chooses a creature type. Destroy all creatures that aren't of a type chosen this way. They can't be regenerated.
this.getSpellAbility().addEffect(new HarshMercyEffect());
@ -97,10 +97,8 @@ class HarshMercyEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!player.choose(Outcome.DestroyPermanent, typeChoice, game)) {
if (!player.canRespond()) {
continue PlayerIteration;
}
if (!player.choose(Outcome.DestroyPermanent, typeChoice, game)) {
continue PlayerIteration;
}
String chosenType = typeChoice.getChoice();
if (chosenType != null) {

View file

@ -28,6 +28,7 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -58,9 +59,9 @@ public class HeroesPodium extends CardImpl {
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
}
public HeroesPodium(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
addSuperType(SuperType.LEGENDARY);
// Each legendary creature you control gets +1/+1 for each other legendary creature you control.
@ -88,6 +89,7 @@ public class HeroesPodium extends CardImpl {
class HeroesPodiumLegendaryCount implements DynamicValue {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other legendary creature you control");
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
}
@ -120,6 +122,7 @@ class HeroesPodiumLegendaryCount implements DynamicValue {
class HeroesPodiumEffect extends OneShotEffect {
private static final FilterCreatureCard filter = new FilterCreatureCard("a legendary creature card");
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
}
@ -140,54 +143,36 @@ class HeroesPodiumEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller == null || sourceObject == null) {
return false;
}
Cards cards = new CardsImpl();
int count = source.getManaCostsToPay().getX();
count = Math.min(player.getLibrary().size(), count);
boolean legendaryIncluded = false;
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
if (filter.match(card, game)) {
legendaryIncluded = true;
}
}
}
player.lookAtCards("Heroes' Podium", cards, game);
cards.addAll(controller.getLibrary().getTopCards(game, source.getManaCostsToPay().getX()));
boolean legendaryIncluded = cards.count(filter, game) > 0;
controller.lookAtCards(sourceObject.getIdName(), cards, game);
// You may reveal a legendary creature card from among them and put it into your hand.
if (!cards.isEmpty() && legendaryIncluded && player.chooseUse(outcome, "Put a legendary creature card into your hand?", source, game)) {
if (!cards.isEmpty() && legendaryIncluded && controller.chooseUse(outcome, "Put a legendary creature card into your hand?", source, game)) {
if (cards.size() == 1) {
Card card = cards.getRandom(game);
cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
controller.moveCards(cards, Zone.HAND, source, game);
return true;
} else {
TargetCard target = new TargetCard(Zone.LIBRARY, filter);
if (player.choose(outcome, cards, target, game)) {
if (controller.choose(outcome, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
controller.moveCards(card, Zone.HAND, source, game);
}
}
}
}
// Put the rest on the bottom of your library in a random order
while (!cards.isEmpty()) {
Card card = cards.getRandom(game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false);
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
}

View file

@ -73,7 +73,7 @@ class IgniteMemoriesEffect extends OneShotEffect {
public IgniteMemoriesEffect() {
super(Outcome.Damage);
staticText = "Target player reveals a card at random from his or her hand. Ignite Memories deals damage to that player equal to that card's converted mana cost";
staticText = "Target player reveals a card at random from his or her hand. {this} deals damage to that player equal to that card's converted mana cost";
}
public IgniteMemoriesEffect(final IgniteMemoriesEffect effect) {
@ -88,10 +88,13 @@ class IgniteMemoriesEffect extends OneShotEffect {
if (!controller.getHand().isEmpty()) {
Cards revealed = new CardsImpl();
Card card = controller.getHand().getRandom(game);
revealed.add(card);
controller.revealCards(sourceObject.getIdName(), revealed, game);
controller.damage(card.getConvertedManaCost(), source.getSourceId(), game, false, true);
if (card != null) {
revealed.add(card);
controller.revealCards(sourceObject.getIdName(), revealed, game);
controller.damage(card.getConvertedManaCost(), source.getSourceId(), game, false, true);
return true;
}
return false;
}
return true;
}

View file

@ -132,7 +132,7 @@ class InducedAmnesiaReturnEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && sourcePermanent != null) {
UUID exileId = CardUtil.getCardExileZoneId(game, source);
UUID exileId = CardUtil.getCardExileZoneId(game, source.getSourceId(), true);
int numberOfCards = 0;
ExileZone exileZone = game.getExile().getExileZone(exileId);
if (exileZone != null) {

View file

@ -50,7 +50,7 @@ import mage.target.common.TargetOpponent;
public class InfiniteObliteration extends CardImpl {
public InfiniteObliteration(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}");
// Name a creature card. Search target opponent's graveyard, hand, and library
// for any number of cards with that name and exile them. Then that player shuffles his or her library.
@ -88,10 +88,8 @@ class InfiniteObliterationEffect extends SearchTargetGraveyardHandLibraryForCard
cardChoice.clearChoice();
cardChoice.setMessage("Name a creature card");
while (!controller.choose(Outcome.Exile, cardChoice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Exile, cardChoice, game)) {
return false;
}
String cardName;
cardName = cardChoice.getChoice();

View file

@ -45,7 +45,9 @@ import mage.constants.Zone;
public class IzzetSignet extends CardImpl {
public IzzetSignet(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// {1}, {T}: Add {U}{R} to your mana pool.
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(1, 0, 1, 0, 0, 0, 0, 0), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
this.addAbility(ability);

View file

@ -41,9 +41,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColorOrArtifact;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledLandPermanent;
@ -60,16 +60,16 @@ import mage.target.common.TargetControlledPermanent;
public class JeweledSpirit extends CardImpl {
public JeweledSpirit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Sacrifice two lands: Jeweled Spirit gains protection from artifacts or from the color of your choice until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new JeweledSpiritEffect(),
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new JeweledSpiritEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("two lands"), true))));
}
@ -84,34 +84,27 @@ public class JeweledSpirit extends CardImpl {
}
class JeweledSpiritEffect extends OneShotEffect {
public JeweledSpiritEffect() {
super(Outcome.AddAbility);
this.staticText = "{this} gains protection from artifacts or from the color of your choice until end of turn";
}
public JeweledSpiritEffect(final JeweledSpiritEffect effect) {
super(effect);
}
@Override
public JeweledSpiritEffect copy() {
return new JeweledSpiritEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ChoiceColorOrArtifact choice = new ChoiceColorOrArtifact();
while (!choice.isChosen()) {
if (!controller.canRespond()) {
return false;
}
controller.choose(outcome, choice, game);
}
FilterCard protectionFilter = new FilterCard();
ChoiceColorOrArtifact choice = new ChoiceColorOrArtifact();
if (controller != null && controller.choose(outcome, choice, game)) {
FilterCard protectionFilter = new FilterCard();
if (choice.isArtifactSelected()) {
protectionFilter.add(new CardTypePredicate(CardType.ARTIFACT));
} else {
@ -122,7 +115,7 @@ class JeweledSpiritEffect extends OneShotEffect {
ContinuousEffect effect = new GainAbilitySourceEffect(protectionAbility, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
}
return false;
}
}

View file

@ -27,6 +27,9 @@
*/
package mage.cards.j;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
@ -47,10 +50,6 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author Styxo
@ -127,6 +126,8 @@ class JodahsAvengerEffect extends ContinuousEffectImpl {
gainedAbility = ProtectionAbility.from(ObjectColor.RED);
break;
}
} else {
discard();
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.j;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author L_J
*/
public class JohnnyComboPlayer extends CardImpl {
public JohnnyComboPlayer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.GAMER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {4}: Search your library for a card, put that card into your hand, then shuffle your library.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterCard("a card")), false, true), new ManaCostsImpl("{4}")));
}
public JohnnyComboPlayer(final JohnnyComboPlayer card) {
super(card);
}
@Override
public JohnnyComboPlayer copy() {
return new JohnnyComboPlayer(this);
}
}

View file

@ -153,10 +153,8 @@ class KaronaFalseGodEffect extends OneShotEffect {
MageObject sourceObject = game.getObject(source.getSourceId());
if (sourceObject != null && controller != null) {
Choice typeChoice = new ChoiceCreatureType(sourceObject);
while (!controller.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.BoostCreature, typeChoice, game)) {
return false;
}
String typeChosen = typeChoice.getChoice();
if (!typeChosen.isEmpty()) {

View file

@ -83,7 +83,7 @@ public class KeeperOfTheDead extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// {B}, {tap}: Choose target opponent who had at least two fewer creature cards in his or her graveyard than you did as you activated this ability. Destroy target nonblack creature he or she controls.
// {B}, {T}: Choose target opponent who had at least two fewer creature cards in his or her graveyard than you did as you activated this ability. Destroy target nonblack creature he or she controls.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new KeeperOfTheDeadEffect(), new TapSourceCost());
ability.addCost(new ManaCostsImpl("{B}"));
ability.addTarget(new TargetPlayer(1, 1, false, filter));
@ -136,10 +136,10 @@ class KeeperOfDeadPredicate implements ObjectSourcePlayerPredicate<ObjectSourceP
class KeeperOfTheDeadCreatureTarget extends TargetPermanent {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature");
private static final FilterCreaturePermanent nonblackCreaturefilter = new FilterCreaturePermanent("nonblack creature");
static {
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
nonblackCreaturefilter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
}
public KeeperOfTheDeadCreatureTarget() {
@ -179,7 +179,7 @@ class KeeperOfTheDeadCreatureTarget extends TargetPermanent {
UUID playerId = ((StackObject) object).getStackAbility().getFirstTarget();
for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null && filter.match(permanent, game) && permanent.getControllerId().equals(playerId)) {
if (permanent != null && nonblackCreaturefilter.match(permanent, game) && permanent.getControllerId().equals(playerId)) {
possibleTargets.add(targetId);
}
}

View file

@ -0,0 +1,139 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.k;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterOpponent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author stevemarkham81
*/
public class KeeperOfTheLight extends CardImpl {
public KeeperOfTheLight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// {W}, {T}: Choose target opponent who had more life than you did as you activated this ability. You gain 3 life.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new GainLifeEffect(3).setText("Choose target opponent who had more life than you did as you activated this ability. You gain 3 life."),
new ManaCostsImpl("{W}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new KeeperOfTheLightTarget());
this.addAbility(ability);
}
public KeeperOfTheLight(final KeeperOfTheLight card) {
super(card);
}
@Override
public KeeperOfTheLight copy() {
return new KeeperOfTheLight(this);
}
}
class KeeperOfTheLightTarget extends TargetPlayer {
public KeeperOfTheLightTarget() {
super(1, 1, false, new FilterOpponent("opponent that has more life than you"));
}
public KeeperOfTheLightTarget(final KeeperOfTheLightTarget target) {
super(target);
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>();
int lifeController = game.getPlayer(sourceControllerId).getLife();
for (UUID targetId : availablePossibleTargets) {
Player opponent = game.getPlayer(targetId);
if (opponent != null) {
int lifeOpponent = opponent.getLife();
if (lifeOpponent > lifeController) {
possibleTargets.add(targetId);
}
}
}
return possibleTargets;
}
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
int count = 0;
MageObject targetSource = game.getObject(sourceId);
Player controller = game.getPlayer(sourceControllerId);
if (controller != null) {
for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
Player player = game.getPlayer(playerId);
if (player != null
&& controller.getLife() < player.getLife()
&& !player.hasLeft()
&& filter.match(player, sourceId, sourceControllerId, game)
&& player.canBeTargetedBy(targetSource, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
}
return false;
}
@Override
public KeeperOfTheLightTarget copy() {
return new KeeperOfTheLightTarget(this);
}
}

View file

@ -28,17 +28,16 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseCreatureTypeEffect;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceCreatureType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
@ -55,7 +54,6 @@ public class KindredDominance extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}");
// Choose a creature type. Destroy all creatures that are not the chosen type.
this.getSpellAbility().addEffect(new ChooseCreatureTypeEffect(Outcome.DestroyPermanent));
this.getSpellAbility().addEffect(new KindredDominanceEffect());
}
@ -73,7 +71,7 @@ class KindredDominanceEffect extends OneShotEffect {
public KindredDominanceEffect() {
super(Outcome.DestroyPermanent);
this.staticText = "Destroy all creatures that are not the chosen type.";
this.staticText = "Choose a creature type. Destroy all creatures that are not the chosen type.";
}
public KindredDominanceEffect(final KindredDominanceEffect effect) {
@ -88,14 +86,12 @@ class KindredDominanceEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null & mageObject != null) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game);
if (subType != null) {
FilterPermanent filter = new FilterCreaturePermanent("creatures");
filter.add(Predicates.not(new SubtypePredicate(subType)));
return new DestroyAllEffect(filter).apply(game, source);
}
Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
if (controller != null && controller.choose(outcome, typeChoice, game)) {
game.informPlayers(controller.getLogName() + " has chosen " + typeChoice.getChoice());
FilterCreaturePermanent filter = new FilterCreaturePermanent("All creatures not of the chosen type");
filter.add(Predicates.not(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice()))));
return new DestroyAllEffect(filter).apply(game, source);
}
return false;
}

View file

@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,12 +20,11 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.l;
import java.util.UUID;
@ -47,21 +46,19 @@ import mage.filter.predicate.mageobject.CardTypePredicate;
*/
public class LeylineOfAnticipation extends CardImpl {
private static final FilterCard filter = new FilterCard("nonland cards");
private static final FilterCard filter = new FilterCard("spells");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
}
public LeylineOfAnticipation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
// If Leyline of Anticipation is in your opening hand, you may begin the game with it on the battlefield.
this.addAbility(LeylineAbility.getInstance());
// You may cast nonland cards as though they had flash. (You may cast them any time you could cast an instant.)
// You may cast spells as though they had flash. (You may cast them any time you could cast an instant.)
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CastAsThoughItHadFlashAllEffect(Duration.WhileOnBattlefield, filter)));
}

View file

@ -54,8 +54,8 @@ import mage.target.common.TargetOpponent;
public class LiarsPendulum extends CardImpl {
public LiarsPendulum(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {2}, {T}: Choose a card name. Target opponent guesses whether a card with that name is in your hand. You may reveal your hand. If you do and your opponent guessed wrong, draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LiarsPendulumEffect(), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
@ -73,7 +73,6 @@ public class LiarsPendulum extends CardImpl {
}
}
class LiarsPendulumEffect extends OneShotEffect {
public LiarsPendulumEffect() {
@ -99,27 +98,24 @@ class LiarsPendulumEffect extends OneShotEffect {
Choice choice = new ChoiceImpl();
choice.setChoices(CardRepository.instance.getNames());
choice.setMessage("Choose a card name");
while (!controller.choose(Outcome.Benefit, choice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Benefit, choice, game)) {
return false;
}
String cardName = choice.getChoice();
game.informPlayers("Card named: " + cardName);
boolean opponentGuess = false;
if (opponent.chooseUse(Outcome.Neutral, "Is the chosen card (" + cardName + ") in " + controller.getLogName() + "'s hand?", source, game)) {
opponentGuess = true;
}
boolean rightGuess = !opponentGuess;
for (Card card : controller.getHand().getCards(game)) {
if (card.isSplitCard()){
if (card.isSplitCard()) {
SplitCard splitCard = (SplitCard) card;
if (splitCard.getLeftHalfCard().getName().equals(cardName)){
if (splitCard.getLeftHalfCard().getName().equals(cardName)) {
rightGuess = opponentGuess;
}
else if (splitCard.getRightHalfCard().getName().equals(cardName)){
} else if (splitCard.getRightHalfCard().getName().equals(cardName)) {
rightGuess = opponentGuess;
}
}
@ -128,7 +124,7 @@ class LiarsPendulumEffect extends OneShotEffect {
}
}
game.informPlayers(opponent.getLogName() + " guesses that " + cardName + " is " + (opponentGuess ? "" : "not") + " in " + controller.getLogName() + "'s hand");
if (controller.chooseUse(outcome, "Reveal your hand?", source, game)) {
controller.revealCards("hand of " + controller.getName(), controller.getHand(), game);
if (!rightGuess) {

View file

@ -0,0 +1,176 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.l;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterBasicLandCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInGraveyard;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author ThomasLerner, LevelX2 & L_J
*/
public class LodestoneBauble extends CardImpl {
public LodestoneBauble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{0}");
// {1}, {T}, Sacrifice Lodestone Bauble: Put up to four target basic land cards from a player's graveyard on top of his or her library in any order. That player draws a card at the beginning of the next turn's upkeep.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LodestoneBaubleEffect(), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
ability.addEffect(new LodestoneBaubleDrawEffect());
ability.addTarget(new TargetPlayer(1, 1, true));
ability.addTarget(new LodestoneBaubleTarget());
this.addAbility(ability);
}
public LodestoneBauble(final LodestoneBauble card) {
super(card);
}
@Override
public LodestoneBauble copy() {
return new LodestoneBauble(this);
}
}
class LodestoneBaubleTarget extends TargetCardInGraveyard {
public LodestoneBaubleTarget() {
super(0, 4, new FilterBasicLandCard("basic land cards from a player's graveyard"));
}
public LodestoneBaubleTarget(final LodestoneBaubleTarget target) {
super(target);
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
Card card = game.getCard(id);
if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) {
UUID firstTarget = source.getFirstTarget();
if (firstTarget != null && game.getPlayer(firstTarget).getGraveyard().contains(id)) {
return filter.match(card, game);
}
}
return false;
}
@Override
public LodestoneBaubleTarget copy() {
return new LodestoneBaubleTarget(this);
}
}
class LodestoneBaubleEffect extends OneShotEffect {
LodestoneBaubleEffect() {
super(Outcome.Detriment);
this.staticText = "Put up to four target basic land cards from a player's graveyard on top of his or her library in any order";
}
LodestoneBaubleEffect(final LodestoneBaubleEffect effect) {
super(effect);
}
@Override
public LodestoneBaubleEffect copy() {
return new LodestoneBaubleEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
List<UUID> targets = source.getTargets().get(1).getTargets();
if (targets != null && targets.size() > 0) {
Cards cards = new CardsImpl(targets);
controller.putCardsOnTopOfLibrary(cards, game, source, true);
}
return true;
}
return false;
}
}
class LodestoneBaubleDrawEffect extends OneShotEffect {
public LodestoneBaubleDrawEffect() {
super(Outcome.DrawCard);
staticText = "That player draws a card at the beginning of the next turn's upkeep";
}
public LodestoneBaubleDrawEffect(final LodestoneBaubleDrawEffect effect) {
super(effect);
}
@Override
public LodestoneBaubleDrawEffect copy() {
return new LodestoneBaubleDrawEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID targetId = this.getTargetPointer().getFirst(game, source);
Player targetPlayer = game.getPlayer(targetId);
if (targetPlayer != null) {
Effect effect = new DrawCardTargetEffect(new StaticValue(1), false);
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
DelayedTriggeredAbility ability = new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(effect);
game.addDelayedTriggeredAbility(ability, source);
return true;
}
return false;
}
}

View file

@ -27,6 +27,7 @@
*/
package mage.cards.l;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.OneShotEffect;
@ -43,8 +44,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author michael.napoleon@gmail.com
@ -52,8 +51,8 @@ import java.util.UUID;
public class LuminescentRain extends CardImpl {
public LuminescentRain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
// Choose a creature type. You gain 2 life for each permanent you control of that type.
this.getSpellAbility().addEffect(new LuminescentRainEffect());
}
@ -68,36 +67,31 @@ public class LuminescentRain extends CardImpl {
}
}
class LuminescentRainEffect extends OneShotEffect {
class LuminescentRainEffect extends OneShotEffect {
LuminescentRainEffect() {
super(Outcome.GainLife);
this.staticText = "Choose a creature type. You gain 2 life for each permanent you control of that type.";
}
LuminescentRainEffect() {
super(Outcome.GainLife);
this.staticText = "Choose a creature type. You gain 2 life for each permanent you control of that type.";
}
LuminescentRainEffect(final LuminescentRainEffect effect) {
super(effect);
}
@Override
public LuminescentRainEffect copy() {
return new LuminescentRainEffect(this);
}
LuminescentRainEffect(final LuminescentRainEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
@Override
public LuminescentRainEffect copy() {
return new LuminescentRainEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
while (!player.choose(Outcome.BoostCreature, typeChoice, game)) {
if (!player.canRespond()) {
return false;
}
}
Choice typeChoice = new ChoiceCreatureType(game.getObject(source.getSourceId()));
if (player != null && player.choose(Outcome.BoostCreature, typeChoice, game)) {
FilterControlledPermanent filter = new FilterControlledPermanent();
filter.add(new SubtypePredicate(SubType.byDescription(typeChoice.getChoice())));
return new GainLifeEffect(new PermanentsOnBattlefieldCount(filter, 2)).apply(game, source);
}
return false;
}
}
}

View file

@ -27,6 +27,9 @@
*/
package mage.cards.l;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -42,18 +45,14 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LoneFox
@ -61,7 +60,7 @@ import java.util.UUID;
public class LunarAvenger extends CardImpl {
public LunarAvenger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
@ -114,12 +113,9 @@ class LunarAvengerEffect extends OneShotEffect {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose ability to add");
choice.setChoices(choices);
while (!controller.choose(outcome, choice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(outcome, choice, game)) {
return false;
}
Ability gainedAbility;
String chosen = choice.getChoice();
switch (chosen) {

View file

@ -27,7 +27,6 @@
*/
package mage.cards.m;
import java.util.List;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
@ -109,15 +108,12 @@ class MadScienceFairManaEffect extends ManaEffect {
controller.getManaPool().addMana(Mana.ColorlessMana(1), game, source);
} else {
ChoiceColor choice = new ChoiceColor();
controller.choose(Outcome.PutManaInPool, choice, game);
if (choice.getColor() == null) {
return false;
}
Mana chosen = choice.getMana(1);
if (chosen != null) {
if (controller.choose(Outcome.PutManaInPool, choice, game)) {
Mana chosen = choice.getMana(1);
checkToFirePossibleEvents(chosen, game, source);
controller.getManaPool().addMana(chosen, game, source);
return true;
} else {
return false;
}
}
return true;

View file

@ -49,7 +49,7 @@ import mage.players.Player;
public class MadcapExperiment extends CardImpl {
public MadcapExperiment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Reveal cards from the top of your library until you reveal an artifact card. Put that card onto the battlefield and the rest on the bottom of your library in a random order. Madcap Experiment deals damage to you equal to the number of cards revealed this way.
this.getSpellAbility().addEffect(new MadcapExperimentEffect());
@ -107,13 +107,7 @@ class MadcapExperimentEffect extends OneShotEffect {
cards.remove(card);
}
// Put the rest on the bottom of your library in a random order
while (!cards.isEmpty()) {
card = cards.getRandom(game);
if (card != null) {
cards.remove(card);
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.HAND, false, false);
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
controller.damage(revealed, source.getSourceId(), game, false, true);
return true;
}

View file

@ -42,8 +42,8 @@ import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -101,6 +101,9 @@ class MagusOfTheScrollEffect extends OneShotEffect {
if (!you.getHand().isEmpty()) {
Cards revealed = new CardsImpl();
Card card = you.getHand().getRandom(game);
if (card == null) {
return false;
}
revealed.add(card);
you.revealCards(sourceObject.getName(), revealed, game);
if (card.getName().equals(cardName)) {

View file

@ -27,6 +27,9 @@
*/
package mage.cards.m;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -40,8 +43,8 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
@ -50,10 +53,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author Styxo
@ -67,7 +66,7 @@ public class MaintenanceDroid extends CardImpl {
}
public MaintenanceDroid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{W}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}{U}");
this.subtype.add(SubType.DROID);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
@ -121,10 +120,8 @@ class MaintenanceDroidEffect extends OneShotEffect {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose mode");
choice.setChoices(choices);
while (!controller.choose(outcome, choice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(outcome, choice, game)) {
return false;
}
String chosen = choice.getChoice();

View file

@ -47,8 +47,7 @@ import mage.players.Player;
public class MakeAWish extends CardImpl {
public MakeAWish(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Return two cards at random from your graveyard to your hand.
this.getSpellAbility().addEffect(new MakeAWishEffect());
@ -91,6 +90,8 @@ class MakeAWishEffect extends OneShotEffect {
card.moveToZone(Zone.HAND, source.getSourceId(), game, true);
cards.remove(card);
game.informPlayers(card.getName() + " returned to the hand of " + player.getLogName());
} else {
return false;
}
}
return true;

View file

@ -41,8 +41,8 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
@ -54,7 +54,7 @@ import mage.players.Player;
public class ManaforgeCinder extends CardImpl {
public ManaforgeCinder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B/R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B/R}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(1);
@ -62,7 +62,7 @@ public class ManaforgeCinder extends CardImpl {
// {1}: Add {B} or {R} to your mana pool. Activate this ability no more than three times each turn.
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new ManaforgeCinderManaEffect(), new ManaCostsImpl("{1}"), 3));
}
public ManaforgeCinder(final ManaforgeCinder card) {
@ -75,8 +75,6 @@ public class ManaforgeCinder extends CardImpl {
}
}
class ManaforgeCinderManaEffect extends OneShotEffect {
public ManaforgeCinderManaEffect() {
@ -104,10 +102,8 @@ class ManaforgeCinderManaEffect extends OneShotEffect {
manaChoice.setChoices(choices);
manaChoice.setMessage("Select black or red mana to add to your mana pool");
Mana mana = new Mana();
while (!controller.choose(Outcome.Benefit, manaChoice, game)) {
if (!controller.canRespond()) {
return false;
}
if (!controller.choose(Outcome.Benefit, manaChoice, game)) {
return false;
}
if (manaChoice.getChoice() == null) {
return false;

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