diff --git a/Mage.Client/serverlist.txt b/Mage.Client/serverlist.txt
index cff928b3be7..db223b403ff 100644
--- a/Mage.Client/serverlist.txt
+++ b/Mage.Client/serverlist.txt
@@ -1,6 +1,6 @@
XMage.de 1 (Europe/Germany) fast :xmage.de:17171
woogerworks (North America/USA) :xmage.woogerworks.info:17171
XMage.info 1 (Europe/France) new network code -> see forum :176.31.186.181:17171
-IceMage (Europe/Netherlands) :ring0.cc:17171
+XMage BR (South America/Brazil) :ec2-54-233-67-0.sa-east-1.compute.amazonaws.com:17171
Seedds Server (Asia) :115.29.203.80:17171
localhost -> connect to your local server (must be started):localhost:17171
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
index b15bbcdd6aa..8008ce940d9 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form
@@ -25,13 +25,13 @@
-
+
-
+
@@ -69,8 +69,11 @@
-
+
+
+
+
@@ -200,18 +203,18 @@
-
-
+
-
-
-
+
+
+
+
-
+
@@ -335,9 +338,9 @@
-
-
-
+
+
+
@@ -528,7 +531,7 @@
-
+
@@ -730,11 +733,11 @@
-
+
-
-
+
+
@@ -769,29 +772,34 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
-
+
@@ -899,36 +907,37 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1206,120 +1215,54 @@
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
@@ -1329,41 +1272,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1377,17 +1305,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1401,17 +1338,59 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1425,17 +1404,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1449,29 +1437,30 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
@@ -1481,17 +1470,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1505,17 +1503,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1529,17 +1536,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1553,17 +1569,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1577,17 +1602,26 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -1601,17 +1635,419 @@
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1634,19 +2070,18 @@
-
+
-
-
+
+
+
-
-
-
+
-
+
@@ -1662,7 +2097,7 @@
-
+
@@ -1859,7 +2294,7 @@
-
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
index d655432110c..c8f314e4a80 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
@@ -42,9 +42,7 @@ import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.BorderFactory;
@@ -63,6 +61,9 @@ import mage.client.MageFrame;
import mage.client.util.Config;
import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
+import static mage.constants.Constants.DEFAULT_AVATAR_ID;
+import static mage.constants.Constants.MAX_AVATAR_ID;
+import static mage.constants.Constants.MIN_AVATAR_ID;
import mage.players.net.UserData;
import mage.players.net.UserGroup;
import mage.players.net.UserSkipPrioritySteps;
@@ -264,29 +265,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static String PHASE_ON = "on";
public static String PHASE_OFF = "off";
- public static final int DEFAULT_AVATAR_ID = 51;
- private static int selectedAvatarId = DEFAULT_AVATAR_ID;
- private static final Set available_avatars = new HashSet<>();
private static final Map panels = new HashMap<>();
private static final Border GREEN_BORDER = BorderFactory.createLineBorder(Color.GREEN, 3);
private static final Border BLACK_BORDER = BorderFactory.createLineBorder(Color.BLACK, 3);
- static {
- available_avatars.add(51);
- available_avatars.add(13);
- available_avatars.add(9);
- available_avatars.add(53);
- available_avatars.add(10);
- available_avatars.add(39);
- available_avatars.add(19);
- available_avatars.add(30);
- available_avatars.add(25);
-
- available_avatars.add(22);
- available_avatars.add(77);
- available_avatars.add(62);
- }
+ private static int selectedAvatarId = DEFAULT_AVATAR_ID;
private final JFileChooser fc = new JFileChooser();
@@ -433,20 +417,30 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabAvatars = new javax.swing.JPanel();
avatarPane = new javax.swing.JScrollPane();
avatarPanel = new javax.swing.JPanel();
- jLabel12 = new javax.swing.JLabel();
jPanel10 = new javax.swing.JPanel();
- jPanel13 = new javax.swing.JPanel();
jPanel11 = new javax.swing.JPanel();
jPanel12 = new javax.swing.JPanel();
+ jPanel13 = new javax.swing.JPanel();
jPanel14 = new javax.swing.JPanel();
jPanel15 = new javax.swing.JPanel();
- jLabel13 = new javax.swing.JLabel();
jPanel16 = new javax.swing.JPanel();
jPanel17 = new javax.swing.JPanel();
jPanel18 = new javax.swing.JPanel();
jPanel19 = new javax.swing.JPanel();
jPanel20 = new javax.swing.JPanel();
jPanel21 = new javax.swing.JPanel();
+ jPanel22 = new javax.swing.JPanel();
+ jPanel23 = new javax.swing.JPanel();
+ jPanel24 = new javax.swing.JPanel();
+ jPanel25 = new javax.swing.JPanel();
+ jPanel26 = new javax.swing.JPanel();
+ jPanel27 = new javax.swing.JPanel();
+ jPanel28 = new javax.swing.JPanel();
+ jPanel29 = new javax.swing.JPanel();
+ jPanel30 = new javax.swing.JPanel();
+ jPanel31 = new javax.swing.JPanel();
+ jPanel32 = new javax.swing.JPanel();
+ jPanel33 = new javax.swing.JPanel();
tabConnection = new javax.swing.JPanel();
lblProxyType = new javax.swing.JLabel();
cbProxyType = new javax.swing.JComboBox();
@@ -608,16 +602,16 @@ public class PreferencesDialog extends javax.swing.JDialog {
main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(main_gameLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(cbAllowRequestToShowHandCards, javax.swing.GroupLayout.PREFERRED_SIZE, 546, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(showPlayerNamesPermanently, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(nonLandPermanentsInOnePile, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(showAbilityPickerForced, javax.swing.GroupLayout.Alignment.LEADING))
- .addComponent(cbShowStormCounter, javax.swing.GroupLayout.PREFERRED_SIZE, 546, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(cbConfirmEmptyManaPool, javax.swing.GroupLayout.PREFERRED_SIZE, 546, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(cbAskMoveToGraveOrder, javax.swing.GroupLayout.PREFERRED_SIZE, 546, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(cbConfirmEmptyManaPool, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE)
+ .addComponent(cbAllowRequestToShowHandCards, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(cbShowStormCounter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(cbAskMoveToGraveOrder, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap(7, Short.MAX_VALUE))
);
main_gameLayout.setVerticalGroup(
main_gameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -666,9 +660,9 @@ public class PreferencesDialog extends javax.swing.JDialog {
main_gamelogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(main_gamelogLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(main_gamelogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(cbGameLogAutoSave, javax.swing.GroupLayout.PREFERRED_SIZE, 528, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(cbDraftLogAutoSave, javax.swing.GroupLayout.PREFERRED_SIZE, 528, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(main_gamelogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(cbDraftLogAutoSave, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(cbGameLogAutoSave, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
main_gamelogLayout.setVerticalGroup(
@@ -687,8 +681,10 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addContainerGap()
.addGroup(tabMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(main_card, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(main_game, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(main_gamelog, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(main_gamelog, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(tabMainLayout.createSequentialGroup()
+ .addComponent(main_game, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
tabMainLayout.setVerticalGroup(
@@ -915,7 +911,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(jLabelEndOfTurn)
.addComponent(checkBoxEndTurnOthers))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(phases_stopSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(phases_stopSettings, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE)
.addContainerGap())
);
@@ -962,24 +958,27 @@ public class PreferencesDialog extends javax.swing.JDialog {
panelCardImages.setLayout(panelCardImagesLayout);
panelCardImagesLayout.setHorizontalGroup(
panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(panelCardImagesLayout.createSequentialGroup()
- .addGap(24, 24, 24)
- .addComponent(txtImageFolderPath)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnBrowseImageLocation))
.addGroup(panelCardImagesLayout.createSequentialGroup()
.addGroup(panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(cbUseDefaultImageFolder)
- .addComponent(cbCheckForNewImages)
.addGroup(panelCardImagesLayout.createSequentialGroup()
- .addGroup(panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, panelCardImagesLayout.createSequentialGroup()
- .addContainerGap()
- .addComponent(labelPreferedImageLanguage))
- .addComponent(cbSaveToZipFiles, javax.swing.GroupLayout.Alignment.LEADING))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(cbPreferedImageLanguage, javax.swing.GroupLayout.PREFERRED_SIZE, 153, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(cbUseDefaultImageFolder)
+ .addComponent(cbCheckForNewImages)
+ .addGroup(panelCardImagesLayout.createSequentialGroup()
+ .addGroup(panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, panelCardImagesLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(labelPreferedImageLanguage))
+ .addComponent(cbSaveToZipFiles, javax.swing.GroupLayout.Alignment.LEADING))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(cbPreferedImageLanguage, javax.swing.GroupLayout.PREFERRED_SIZE, 153, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addGap(0, 190, Short.MAX_VALUE))
+ .addGroup(panelCardImagesLayout.createSequentialGroup()
+ .addGap(24, 24, 24)
+ .addComponent(txtImageFolderPath)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnBrowseImageLocation)))
+ .addContainerGap())
);
panelCardImagesLayout.setVerticalGroup(
panelCardImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -1061,32 +1060,29 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGroup(panelBackgroundImagesLayout.createSequentialGroup()
.addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelBackgroundImagesLayout.createSequentialGroup()
- .addGap(19, 19, 19)
- .addComponent(jLabel14))
- .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
- .addGap(25, 25, 25)
- .addComponent(jLabel15)))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
- .addComponent(txtBattlefieldImagePath, javax.swing.GroupLayout.PREFERRED_SIZE, 336, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
+ .addGap(19, 19, 19)
+ .addComponent(jLabel14))
+ .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
+ .addGap(25, 25, 25)
+ .addComponent(jLabel15)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnBrowseBattlefieldImage))
- .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
- .addComponent(txtBackgroundImagePath, javax.swing.GroupLayout.PREFERRED_SIZE, 332, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtBackgroundImagePath)
+ .addComponent(txtBattlefieldImagePath))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnBrowseBackgroundImage)))
- .addGap(0, 0, Short.MAX_VALUE))
- .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
- .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(cbUseRandomBattleImage)
- .addComponent(cbUseDefaultBattleImage)
- .addComponent(cbUseDefaultBackground))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(btnBrowseBackgroundImage, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(btnBrowseBattlefieldImage, javax.swing.GroupLayout.Alignment.TRAILING)))
+ .addGroup(panelBackgroundImagesLayout.createSequentialGroup()
+ .addGroup(panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(cbUseRandomBattleImage)
+ .addComponent(cbUseDefaultBattleImage)
+ .addComponent(cbUseDefaultBackground))
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
);
-
- panelBackgroundImagesLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {txtBackgroundImagePath, txtBattlefieldImagePath});
-
panelBackgroundImagesLayout.setVerticalGroup(
panelBackgroundImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelBackgroundImagesLayout.createSequentialGroup()
@@ -1115,8 +1111,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addGroup(tabImagesLayout.createSequentialGroup()
.addContainerGap()
.addGroup(tabImagesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(panelCardImages, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(panelBackgroundImages, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(panelCardImages, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelBackgroundImages, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
tabImagesLayout.setVerticalGroup(
@@ -1248,249 +1244,459 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Sounds", tabSounds);
- jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
- jLabel12.setText("Choose your avatar:");
+ avatarPane.setMaximumSize(new java.awt.Dimension(508, 772));
+ avatarPane.setMinimumSize(new java.awt.Dimension(508, 772));
+ avatarPane.setPreferredSize(new java.awt.Dimension(508, 772));
+
+ avatarPanel.setMaximumSize(new java.awt.Dimension(508, 772));
+ avatarPanel.setMinimumSize(new java.awt.Dimension(508, 772));
+ avatarPanel.setPreferredSize(new java.awt.Dimension(508, 772));
+ avatarPanel.setLayout(new java.awt.GridLayout(6, 4, 20, 20));
jPanel10.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel10.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel10.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel10.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10);
jPanel10.setLayout(jPanel10Layout);
jPanel10Layout.setHorizontalGroup(
jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel10Layout.setVerticalGroup(
jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
- jPanel13.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
-
- javax.swing.GroupLayout jPanel13Layout = new javax.swing.GroupLayout(jPanel13);
- jPanel13.setLayout(jPanel13Layout);
- jPanel13Layout.setHorizontalGroup(
- jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
- );
- jPanel13Layout.setVerticalGroup(
- jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
- );
+ avatarPanel.add(jPanel10);
jPanel11.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel11.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel11.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel11.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel11Layout = new javax.swing.GroupLayout(jPanel11);
jPanel11.setLayout(jPanel11Layout);
jPanel11Layout.setHorizontalGroup(
jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel11Layout.setVerticalGroup(
jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel11);
+
jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel12.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel12.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel12.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel12Layout = new javax.swing.GroupLayout(jPanel12);
jPanel12.setLayout(jPanel12Layout);
jPanel12Layout.setHorizontalGroup(
jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel12Layout.setVerticalGroup(
jPanel12Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel12);
+
+ jPanel13.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel13.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel13.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel13.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel13Layout = new javax.swing.GroupLayout(jPanel13);
+ jPanel13.setLayout(jPanel13Layout);
+ jPanel13Layout.setHorizontalGroup(
+ jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel13Layout.setVerticalGroup(
+ jPanel13Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel13);
+
jPanel14.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel14.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel14.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel14.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel14Layout = new javax.swing.GroupLayout(jPanel14);
jPanel14.setLayout(jPanel14Layout);
jPanel14Layout.setHorizontalGroup(
jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel14Layout.setVerticalGroup(
jPanel14Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel14);
+
jPanel15.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel15.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel15.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel15.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel15Layout = new javax.swing.GroupLayout(jPanel15);
jPanel15.setLayout(jPanel15Layout);
jPanel15Layout.setHorizontalGroup(
jPanel15Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel15Layout.setVerticalGroup(
jPanel15Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
- jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
- jLabel13.setText("New avatars:");
+ avatarPanel.add(jPanel15);
jPanel16.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel16.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel16.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel16.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel16Layout = new javax.swing.GroupLayout(jPanel16);
jPanel16.setLayout(jPanel16Layout);
jPanel16Layout.setHorizontalGroup(
jPanel16Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel16Layout.setVerticalGroup(
jPanel16Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel16);
+
jPanel17.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel17.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel17.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel17.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel17Layout = new javax.swing.GroupLayout(jPanel17);
jPanel17.setLayout(jPanel17Layout);
jPanel17Layout.setHorizontalGroup(
jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel17Layout.setVerticalGroup(
jPanel17Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel17);
+
jPanel18.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel18.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel18.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel18.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel18Layout = new javax.swing.GroupLayout(jPanel18);
jPanel18.setLayout(jPanel18Layout);
jPanel18Layout.setHorizontalGroup(
jPanel18Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel18Layout.setVerticalGroup(
jPanel18Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel18);
+
jPanel19.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel19.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel19.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel19.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel19Layout = new javax.swing.GroupLayout(jPanel19);
jPanel19.setLayout(jPanel19Layout);
jPanel19Layout.setHorizontalGroup(
jPanel19Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel19Layout.setVerticalGroup(
jPanel19Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel19);
+
jPanel20.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel20.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel20.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel20.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel20Layout = new javax.swing.GroupLayout(jPanel20);
jPanel20.setLayout(jPanel20Layout);
jPanel20Layout.setHorizontalGroup(
jPanel20Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel20Layout.setVerticalGroup(
jPanel20Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel20);
+
jPanel21.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel21.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel21.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel21.setPreferredSize(new java.awt.Dimension(102, 102));
javax.swing.GroupLayout jPanel21Layout = new javax.swing.GroupLayout(jPanel21);
jPanel21.setLayout(jPanel21Layout);
jPanel21Layout.setHorizontalGroup(
jPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
jPanel21Layout.setVerticalGroup(
jPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGap(0, 100, Short.MAX_VALUE)
+ .addGap(0, 110, Short.MAX_VALUE)
);
- javax.swing.GroupLayout avatarPanelLayout = new javax.swing.GroupLayout(avatarPanel);
- avatarPanel.setLayout(avatarPanelLayout);
- avatarPanelLayout.setHorizontalGroup(
- avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addContainerGap()
- .addComponent(jLabel12))
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addGap(30, 30, 30)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel19, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(33, 33, 33)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addContainerGap()
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addGap(20, 20, 20)
- .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(33, 33, 33)
- .addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(jLabel13))))
- .addGap(32, 32, 32)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ avatarPanel.add(jPanel21);
+
+ jPanel22.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel22.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel22.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel22.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel22Layout = new javax.swing.GroupLayout(jPanel22);
+ jPanel22.setLayout(jPanel22Layout);
+ jPanel22Layout.setHorizontalGroup(
+ jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
);
- avatarPanelLayout.setVerticalGroup(
- avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addContainerGap()
- .addComponent(jLabel12)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(26, 26, 26)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel15, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel12, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel14, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(23, 23, 23)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jPanel19, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel20, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel21, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(18, 18, 18)
- .addGroup(avatarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addGroup(avatarPanelLayout.createSequentialGroup()
- .addComponent(jLabel13)
- .addGap(18, 18, 18)
- .addComponent(jPanel16, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(jPanel17, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(jPanel18, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addGap(25, 25, 25))
+ jPanel22Layout.setVerticalGroup(
+ jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
);
+ avatarPanel.add(jPanel22);
+
+ jPanel23.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel23.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel23.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel23.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel23Layout = new javax.swing.GroupLayout(jPanel23);
+ jPanel23.setLayout(jPanel23Layout);
+ jPanel23Layout.setHorizontalGroup(
+ jPanel23Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel23Layout.setVerticalGroup(
+ jPanel23Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel23);
+
+ jPanel24.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel24.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel24.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel24.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel24Layout = new javax.swing.GroupLayout(jPanel24);
+ jPanel24.setLayout(jPanel24Layout);
+ jPanel24Layout.setHorizontalGroup(
+ jPanel24Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel24Layout.setVerticalGroup(
+ jPanel24Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel24);
+
+ jPanel25.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel25.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel25.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel25.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel25Layout = new javax.swing.GroupLayout(jPanel25);
+ jPanel25.setLayout(jPanel25Layout);
+ jPanel25Layout.setHorizontalGroup(
+ jPanel25Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel25Layout.setVerticalGroup(
+ jPanel25Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel25);
+
+ jPanel26.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel26.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel26.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel26.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel26Layout = new javax.swing.GroupLayout(jPanel26);
+ jPanel26.setLayout(jPanel26Layout);
+ jPanel26Layout.setHorizontalGroup(
+ jPanel26Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel26Layout.setVerticalGroup(
+ jPanel26Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel26);
+
+ jPanel27.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel27.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel27.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel27.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel27Layout = new javax.swing.GroupLayout(jPanel27);
+ jPanel27.setLayout(jPanel27Layout);
+ jPanel27Layout.setHorizontalGroup(
+ jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel27Layout.setVerticalGroup(
+ jPanel27Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel27);
+
+ jPanel28.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel28.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel28.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel28.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel28Layout = new javax.swing.GroupLayout(jPanel28);
+ jPanel28.setLayout(jPanel28Layout);
+ jPanel28Layout.setHorizontalGroup(
+ jPanel28Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel28Layout.setVerticalGroup(
+ jPanel28Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel28);
+
+ jPanel29.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel29.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel29.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel29.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel29Layout = new javax.swing.GroupLayout(jPanel29);
+ jPanel29.setLayout(jPanel29Layout);
+ jPanel29Layout.setHorizontalGroup(
+ jPanel29Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel29Layout.setVerticalGroup(
+ jPanel29Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel29);
+
+ jPanel30.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel30.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel30.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel30.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel30Layout = new javax.swing.GroupLayout(jPanel30);
+ jPanel30.setLayout(jPanel30Layout);
+ jPanel30Layout.setHorizontalGroup(
+ jPanel30Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel30Layout.setVerticalGroup(
+ jPanel30Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel30);
+
+ jPanel31.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel31.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel31.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel31.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel31Layout = new javax.swing.GroupLayout(jPanel31);
+ jPanel31.setLayout(jPanel31Layout);
+ jPanel31Layout.setHorizontalGroup(
+ jPanel31Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel31Layout.setVerticalGroup(
+ jPanel31Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel31);
+
+ jPanel32.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel32.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel32.setMinimumSize(new java.awt.Dimension(102, 102));
+ jPanel32.setPreferredSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel32Layout = new javax.swing.GroupLayout(jPanel32);
+ jPanel32.setLayout(jPanel32Layout);
+ jPanel32Layout.setHorizontalGroup(
+ jPanel32Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel32Layout.setVerticalGroup(
+ jPanel32Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel32);
+
+ jPanel33.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true));
+ jPanel33.setMaximumSize(new java.awt.Dimension(102, 102));
+ jPanel33.setMinimumSize(new java.awt.Dimension(102, 102));
+
+ javax.swing.GroupLayout jPanel33Layout = new javax.swing.GroupLayout(jPanel33);
+ jPanel33.setLayout(jPanel33Layout);
+ jPanel33Layout.setHorizontalGroup(
+ jPanel33Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+ jPanel33Layout.setVerticalGroup(
+ jPanel33Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 110, Short.MAX_VALUE)
+ );
+
+ avatarPanel.add(jPanel33);
+
avatarPane.setViewportView(avatarPanel);
javax.swing.GroupLayout tabAvatarsLayout = new javax.swing.GroupLayout(tabAvatars);
tabAvatars.setLayout(tabAvatarsLayout);
tabAvatarsLayout.setHorizontalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 590, Short.MAX_VALUE)
+ .addGroup(tabAvatarsLayout.createSequentialGroup()
+ .addComponent(avatarPane, javax.swing.GroupLayout.PREFERRED_SIZE, 527, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, Short.MAX_VALUE))
);
tabAvatarsLayout.setVerticalGroup(
tabAvatarsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(avatarPane, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE)
+ .addComponent(avatarPane, javax.swing.GroupLayout.PREFERRED_SIZE, 418, Short.MAX_VALUE)
);
tabsPanel.addTab("Avatars", tabAvatars);
@@ -1629,7 +1835,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addContainerGap()
.addComponent(lblURLServerList, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(txtURLServerList, javax.swing.GroupLayout.PREFERRED_SIZE, 421, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(txtURLServerList, javax.swing.GroupLayout.PREFERRED_SIZE, 370, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(connection_serversLayout.createSequentialGroup()
.addGap(141, 141, 141)
.addComponent(jLabel17)))
@@ -1651,15 +1857,14 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabConnectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tabConnectionLayout.createSequentialGroup()
.addContainerGap()
- .addGroup(tabConnectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(tabConnectionLayout.createSequentialGroup()
+ .addGroup(tabConnectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(pnlProxySettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, tabConnectionLayout.createSequentialGroup()
.addComponent(lblProxyType)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(cbProxyType, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(0, 0, Short.MAX_VALUE))
- .addComponent(pnlProxySettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(cbProxyType, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(connection_servers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addContainerGap())
+ .addContainerGap(16, Short.MAX_VALUE))
);
tabConnectionLayout.setVerticalGroup(
tabConnectionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -1672,7 +1877,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
.addComponent(cbProxyType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addComponent(pnlProxySettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addContainerGap(90, Short.MAX_VALUE))
+ .addContainerGap(107, Short.MAX_VALUE))
);
pnlProxySettings.getAccessibleContext().setAccessibleDescription("");
@@ -1700,12 +1905,12 @@ public class PreferencesDialog extends javax.swing.JDialog {
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap(405, Short.MAX_VALUE)
.addComponent(saveButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(exitButton, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
- .addComponent(tabsPanel)
+ .addComponent(tabsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -1795,10 +2000,11 @@ public class PreferencesDialog extends javax.swing.JDialog {
save(prefs, dialog.txtURLServerList, KEY_CONNECTION_URL_SERVER_LIST);
// Avatar
- if (available_avatars.contains(selectedAvatarId)) {
- prefs.put(KEY_AVATAR, String.valueOf(selectedAvatarId));
- updateCache(KEY_AVATAR, String.valueOf(selectedAvatarId));
+ if (selectedAvatarId < MIN_AVATAR_ID || selectedAvatarId > MAX_AVATAR_ID) {
+ selectedAvatarId = DEFAULT_AVATAR_ID;
}
+ prefs.put(KEY_AVATAR, String.valueOf(selectedAvatarId));
+ updateCache(KEY_AVATAR, String.valueOf(selectedAvatarId));
try {
MageFrame.getSession().updatePreferencesForServer(getUserData());
@@ -2275,7 +2481,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
} catch (NumberFormatException n) {
selectedAvatarId = DEFAULT_AVATAR_ID;
} finally {
- if (!available_avatars.contains(selectedAvatarId)) {
+ if (selectedAvatarId < MIN_AVATAR_ID || selectedAvatarId > MAX_AVATAR_ID) {
selectedAvatarId = DEFAULT_AVATAR_ID;
}
}
@@ -2441,26 +2647,37 @@ public class PreferencesDialog extends javax.swing.JDialog {
private void addAvatars() {
try {
- addAvatar(jPanel10, 51, true, false);
+ addAvatar(jPanel10, 10, true, false);
+ addAvatar(jPanel11, 11, false, false);
+ addAvatar(jPanel12, 12, false, false);
addAvatar(jPanel13, 13, false, false);
- addAvatar(jPanel11, 9, false, false);
- addAvatar(jPanel12, 53, false, false);
- addAvatar(jPanel14, 10, false, false);
- addAvatar(jPanel15, 39, false, false);
+ addAvatar(jPanel14, 14, false, false);
+ addAvatar(jPanel15, 15, false, false);
+ addAvatar(jPanel16, 16, false, false);
+ addAvatar(jPanel17, 17, false, false);
+ addAvatar(jPanel18, 18, false, false);
addAvatar(jPanel19, 19, false, false);
- addAvatar(jPanel20, 30, false, false);
- addAvatar(jPanel21, 25, false, false);
+ addAvatar(jPanel20, 20, false, false);
+ addAvatar(jPanel21, 21, false, false);
+ addAvatar(jPanel22, 22, false, false);
+ addAvatar(jPanel23, 23, false, false);
+ addAvatar(jPanel24, 24, false, false);
+ addAvatar(jPanel25, 25, false, false);
+ addAvatar(jPanel26, 26, false, false);
+ addAvatar(jPanel27, 27, false, false);
+ addAvatar(jPanel28, 28, false, false);
+ addAvatar(jPanel29, 29, false, false);
+ addAvatar(jPanel30, 30, false, false);
+ addAvatar(jPanel31, 31, false, false);
+ addAvatar(jPanel32, 32, false, false);
- addAvatar(jPanel16, 22, false, false);
- addAvatar(jPanel17, 77, false, false);
- addAvatar(jPanel18, 62, false, false);
} catch (Exception e) {
log.error(e, e);
}
}
public void setSelectedId(int id) {
- if (available_avatars.contains(id)) {
+ if (id >= MIN_AVATAR_ID && id <= MAX_AVATAR_ID) {
for (JPanel panel : panels.values()) {
panel.setBorder(BLACK_BORDER);
}
@@ -2473,7 +2690,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
String path = "/avatars/" + String.valueOf(id) + ".jpg";
panels.put(id, jPanel);
Image image = ImageHelper.getImageFromResources(path);
- Rectangle r = new Rectangle(90, 90);
+
+ Rectangle r = new Rectangle(jPanel.getWidth() - 5, jPanel.getHeight() - 5);
BufferedImage bufferedImage;
if (!locked) {
bufferedImage = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB);
@@ -2571,8 +2789,6 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JCheckBox displayBigCardsInHand;
private javax.swing.JButton exitButton;
private javax.swing.JLabel jLabel11;
- private javax.swing.JLabel jLabel12;
- private javax.swing.JLabel jLabel13;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel15;
private javax.swing.JLabel jLabel16;
@@ -2599,6 +2815,18 @@ public class PreferencesDialog extends javax.swing.JDialog {
private javax.swing.JPanel jPanel19;
private javax.swing.JPanel jPanel20;
private javax.swing.JPanel jPanel21;
+ private javax.swing.JPanel jPanel22;
+ private javax.swing.JPanel jPanel23;
+ private javax.swing.JPanel jPanel24;
+ private javax.swing.JPanel jPanel25;
+ private javax.swing.JPanel jPanel26;
+ private javax.swing.JPanel jPanel27;
+ private javax.swing.JPanel jPanel28;
+ private javax.swing.JPanel jPanel29;
+ private javax.swing.JPanel jPanel30;
+ private javax.swing.JPanel jPanel31;
+ private javax.swing.JPanel jPanel32;
+ private javax.swing.JPanel jPanel33;
private javax.swing.JLabel labelPreferedImageLanguage;
private javax.swing.JLabel lblProxyPassword;
private javax.swing.JLabel lblProxyPort;
diff --git a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
index 01ffad75880..ff350409715 100644
--- a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
+++ b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
@@ -69,6 +69,9 @@ import mage.client.util.ImageHelper;
import mage.client.util.gui.BufferedImageBuilder;
import mage.client.util.gui.countryBox.CountryUtil;
import mage.components.ImagePanel;
+import static mage.constants.Constants.DEFAULT_AVATAR_ID;
+import static mage.constants.Constants.MAX_AVATAR_ID;
+import static mage.constants.Constants.MIN_AVATAR_ID;
import mage.constants.ManaType;
import mage.remote.Session;
import mage.utils.timer.PriorityTimer;
@@ -92,7 +95,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
private static final int AVATAR_COUNT = 77;
- private static final String DEFAULT_AVATAR_PATH = "/avatars/51.jpg";
+ private static final String DEFAULT_AVATAR_PATH = "/avatars/" + DEFAULT_AVATAR_ID + ".jpg";
private static final int PANEL_WIDTH = 94;
private static final int PANEL_HEIGHT = 242;
@@ -238,8 +241,8 @@ public class PlayerPanelExt extends javax.swing.JPanel {
if (!MageFrame.isLite()) {
int id = player.getUserData().getAvatarId();
- if (id <= 0) {
- id = PreferencesDialog.DEFAULT_AVATAR_ID;
+ if (!(id >= 1000) && (id <= 0 || (id <= MIN_AVATAR_ID && id > MAX_AVATAR_ID))) {
+ id = DEFAULT_AVATAR_ID;
}
if (id != avatarId) {
avatarId = id;
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java
index 33cbb1a7dbe..6389c70ecff 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java
@@ -25,8 +25,8 @@ import org.mage.plugins.card.utils.CardImageUtils;
/**
* This class stores ALL card images in a cache with soft values. this means
- * that the images may be garbage collected when they are not needed any more, but will
- * be kept as long as possible.
+ * that the images may be garbage collected when they are not needed any more,
+ * but will be kept as long as possible.
*
* Key format: "####"
*
@@ -46,8 +46,7 @@ public class ImageCache {
private static final Map imageCache;
/**
- * Common pattern for keys.
- * Format: "##"
+ * Common pattern for keys. Format: "##"
*/
private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)");
@@ -104,16 +103,16 @@ public class ImageCache {
thumbnailFile = new TFile(thumbnailPath);
} catch (Exception ex) {
}
- boolean exists =false;
+ boolean exists = false;
if (thumbnailFile != null) {
try {
exists = thumbnailFile.exists();
- } catch(Exception ex) {
+ } catch (Exception ex) {
exists = false;
}
}
if (exists) {
- log.debug("loading thumbnail for " + key + ", path="+thumbnailPath);
+ log.debug("loading thumbnail for " + key + ", path=" + thumbnailPath);
return loadImage(thumbnailFile);
} else {
BufferedImage image = loadImage(file);
@@ -187,30 +186,15 @@ public class ImageCache {
}
public static BufferedImage getThumbnail(CardView card) {
- String key = getKey(card) + "#thumb";
- if (card.getUsesVariousArt()) {
- key += "#usesVariousArt";
- }
- // log.debug("#key: " + key);
- return getImage(key);
+ return getImage(getKey(card, card.getName(), "#thumb"));
}
public static BufferedImage getImageOriginal(CardView card) {
- String key = getKey(card);
- if (card.getUsesVariousArt()) {
- key += "#usesVariousArt";
- }
- // log.warn("#key: " + key);
- return getImage(key);
+ return getImage(getKey(card, card.getName(), ""));
}
public static BufferedImage getImageOriginalAlternateName(CardView card) {
- String key = getKeyAlternateName(card, card.getAlternateName());
- if (card.getUsesVariousArt()) {
- key += "#usesVariousArt";
- }
- // log.warn("#key: " + key);
- return getImage(key);
+ return getImage(getKey(card, card.getAlternateName(), ""));
}
/**
@@ -230,7 +214,7 @@ public class ImageCache {
if (ex.getCause() instanceof NullPointerException) {
return null;
}
- log.error(ex,ex);
+ log.error(ex, ex);
return null;
}
}
@@ -238,32 +222,25 @@ public class ImageCache {
/**
* Returns the map key for a card, without any suffixes for the image size.
*/
- private static String getKey(CardView card) {
- StringBuilder sb = new StringBuilder(card.getName()).append("#");
- sb.append(card.getExpansionSetCode()).append("#");
- sb.append(card.getType()).append("#");
- sb.append(card.getCardNumber()).append("#");
- sb.append(card.getTokenSetCode() == null ? "":card.getTokenSetCode());
- return sb.toString();
- }
-
- /**
- * Returns the map key for the flip image of a card, without any suffixes for the image size.
- */
- private static String getKeyAlternateName(CardView card, String alternateName) {
- StringBuilder sb = new StringBuilder(alternateName).append("#");
- sb.append(card.getExpansionSetCode()).append("#");
- sb.append(card.getType()).append("#");
- sb.append(card.getCardNumber()).append("#");
- sb.append(card.getTokenSetCode() == null ? "":card.getTokenSetCode());
- return sb.toString();
+ private static String getKey(CardView card, String name, String suffix) {
+ return name + "#" + card.getExpansionSetCode() + "#" + card.getType() + "#" + card.getCardNumber() + "#"
+ + (card.getTokenSetCode() == null ? "" : card.getTokenSetCode())
+ + suffix
+ + (card.getUsesVariousArt() ? "#usesVariousArt" : "");
+
}
+// /**
+// * Returns the map key for the flip image of a card, without any suffixes for the image size.
+// */
+// private static String getKeyAlternateName(CardView card, String alternateName) {
+// return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#"
+// + (card.getTokenSetCode() == null ? "":card.getTokenSetCode());
+// }
/**
* Load image from file
*
- * @param file
- * file to load image from
+ * @param file file to load image from
* @return {@link BufferedImage}
*/
public static BufferedImage loadImage(TFile file) {
@@ -297,7 +274,7 @@ public class ImageCache {
ImageIO.write(image, "jpg", outputStream);
}
} catch (IOException e) {
- log.error(e,e);
+ log.error(e, e);
imageFile.delete();
}
return image;
@@ -305,6 +282,7 @@ public class ImageCache {
/**
* Returns an image scaled to the size given
+ *
* @param original
* @return
*/
@@ -344,6 +322,7 @@ public class ImageCache {
/**
* Returns an image scaled to the size appropriate for the card picture
* panel
+ *
* @param original
* @param sizeNeed
* @return
@@ -356,6 +335,7 @@ public class ImageCache {
/**
* Returns the image appropriate to display the card in the picture panel
+ *
* @param card
* @param width
* @param height
@@ -365,11 +345,7 @@ public class ImageCache {
if (Constants.THUMBNAIL_SIZE_FULL.width + 10 > width) {
return getThumbnail(card);
}
- String key = getKey(card);
- if (card.getUsesVariousArt()) {
- key += "#usesVariousArt";
- }
- // log.warn("getImage: " + key);
+ String key = getKey(card, card.getName(), "");
BufferedImage original = getImage(key);
if (original == null) {
log.debug(key + " not found");
diff --git a/Mage.Client/src/main/resources/avatars/10.jpg b/Mage.Client/src/main/resources/avatars/10.jpg
index fb5b2744649..7ce97fc81e3 100644
Binary files a/Mage.Client/src/main/resources/avatars/10.jpg and b/Mage.Client/src/main/resources/avatars/10.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/11.jpg b/Mage.Client/src/main/resources/avatars/11.jpg
new file mode 100644
index 00000000000..2b665f235a2
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/11.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/12.jpg b/Mage.Client/src/main/resources/avatars/12.jpg
new file mode 100644
index 00000000000..d57f3963ee1
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/12.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/13.jpg b/Mage.Client/src/main/resources/avatars/13.jpg
index 2b665f235a2..b08ae1c24ab 100644
Binary files a/Mage.Client/src/main/resources/avatars/13.jpg and b/Mage.Client/src/main/resources/avatars/13.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/14.jpg b/Mage.Client/src/main/resources/avatars/14.jpg
index d57f3963ee1..e45b888a9ea 100644
Binary files a/Mage.Client/src/main/resources/avatars/14.jpg and b/Mage.Client/src/main/resources/avatars/14.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/15.jpg b/Mage.Client/src/main/resources/avatars/15.jpg
new file mode 100644
index 00000000000..d7fcc94512b
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/15.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/16.jpg b/Mage.Client/src/main/resources/avatars/16.jpg
new file mode 100644
index 00000000000..75b41b0ce63
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/16.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/17.jpg b/Mage.Client/src/main/resources/avatars/17.jpg
new file mode 100644
index 00000000000..12905b63ec3
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/17.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/18.jpg b/Mage.Client/src/main/resources/avatars/18.jpg
new file mode 100644
index 00000000000..d02ccd4c29d
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/18.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/19.jpg b/Mage.Client/src/main/resources/avatars/19.jpg
index b08ae1c24ab..bbffc049eea 100644
Binary files a/Mage.Client/src/main/resources/avatars/19.jpg and b/Mage.Client/src/main/resources/avatars/19.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/48.jpg b/Mage.Client/src/main/resources/avatars/20.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/48.jpg
rename to Mage.Client/src/main/resources/avatars/20.jpg
diff --git a/Mage.Client/src/main/resources/avatars/21.jpg b/Mage.Client/src/main/resources/avatars/21.jpg
new file mode 100644
index 00000000000..fb5b2744649
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/21.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/22.jpg b/Mage.Client/src/main/resources/avatars/22.jpg
index e45b888a9ea..12c2a87b7bf 100644
Binary files a/Mage.Client/src/main/resources/avatars/22.jpg and b/Mage.Client/src/main/resources/avatars/22.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/23.jpg b/Mage.Client/src/main/resources/avatars/23.jpg
index d7fcc94512b..64459f61716 100644
Binary files a/Mage.Client/src/main/resources/avatars/23.jpg and b/Mage.Client/src/main/resources/avatars/23.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/57.jpg b/Mage.Client/src/main/resources/avatars/24.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/57.jpg
rename to Mage.Client/src/main/resources/avatars/24.jpg
diff --git a/Mage.Client/src/main/resources/avatars/25.jpg b/Mage.Client/src/main/resources/avatars/25.jpg
index 75b41b0ce63..68b2b338648 100644
Binary files a/Mage.Client/src/main/resources/avatars/25.jpg and b/Mage.Client/src/main/resources/avatars/25.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/62.jpg b/Mage.Client/src/main/resources/avatars/26.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/62.jpg
rename to Mage.Client/src/main/resources/avatars/26.jpg
diff --git a/Mage.Client/src/main/resources/avatars/66.jpg b/Mage.Client/src/main/resources/avatars/27.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/66.jpg
rename to Mage.Client/src/main/resources/avatars/27.jpg
diff --git a/Mage.Client/src/main/resources/avatars/71.jpg b/Mage.Client/src/main/resources/avatars/28.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/71.jpg
rename to Mage.Client/src/main/resources/avatars/28.jpg
diff --git a/Mage.Client/src/main/resources/avatars/29.jpg b/Mage.Client/src/main/resources/avatars/29.jpg
index 12905b63ec3..ee79324b94d 100644
Binary files a/Mage.Client/src/main/resources/avatars/29.jpg and b/Mage.Client/src/main/resources/avatars/29.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/30.jpg b/Mage.Client/src/main/resources/avatars/30.jpg
index d02ccd4c29d..cf70d9b85e8 100644
Binary files a/Mage.Client/src/main/resources/avatars/30.jpg and b/Mage.Client/src/main/resources/avatars/30.jpg differ
diff --git a/Mage.Client/src/main/resources/avatars/77.jpg b/Mage.Client/src/main/resources/avatars/31.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/77.jpg
rename to Mage.Client/src/main/resources/avatars/31.jpg
diff --git a/Mage.Client/src/main/resources/avatars/9.jpg b/Mage.Client/src/main/resources/avatars/32.jpg
similarity index 100%
rename from Mage.Client/src/main/resources/avatars/9.jpg
rename to Mage.Client/src/main/resources/avatars/32.jpg
diff --git a/Mage.Client/src/main/resources/avatars/39.jpg b/Mage.Client/src/main/resources/avatars/39.jpg
deleted file mode 100644
index bbffc049eea..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/39.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/51.jpg b/Mage.Client/src/main/resources/avatars/51.jpg
deleted file mode 100644
index 7ce97fc81e3..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/51.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/52.jpg b/Mage.Client/src/main/resources/avatars/52.jpg
deleted file mode 100644
index 12c2a87b7bf..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/52.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/53.jpg b/Mage.Client/src/main/resources/avatars/53.jpg
deleted file mode 100644
index 64459f61716..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/53.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/6.jpg b/Mage.Client/src/main/resources/avatars/6.jpg
deleted file mode 100644
index 68b2b338648..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/6.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/72.jpg b/Mage.Client/src/main/resources/avatars/72.jpg
deleted file mode 100644
index ee79324b94d..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/72.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/75.jpg b/Mage.Client/src/main/resources/avatars/75.jpg
deleted file mode 100644
index cf70d9b85e8..00000000000
Binary files a/Mage.Client/src/main/resources/avatars/75.jpg and /dev/null differ
diff --git a/Mage.Client/src/main/resources/avatars/special/21.gif b/Mage.Client/src/main/resources/avatars/special/21.gif
new file mode 100644
index 00000000000..5de3fb6134a
Binary files /dev/null and b/Mage.Client/src/main/resources/avatars/special/21.gif differ
diff --git a/Mage.Common/src/mage/constants/Constants.java b/Mage.Common/src/mage/constants/Constants.java
index 965346f2819..fd8bf95052c 100644
--- a/Mage.Common/src/mage/constants/Constants.java
+++ b/Mage.Common/src/mage/constants/Constants.java
@@ -67,6 +67,10 @@ public final class Constants {
public static final double SCALE_FACTOR = 0.5;
+ public static final int MIN_AVATAR_ID = 10;
+ public static final int MAX_AVATAR_ID = 32;
+ public static final int DEFAULT_AVATAR_ID = 10;
+
/**
* Time each player has during the game to play using his\her priority.
*/
diff --git a/Mage.Common/src/mage/utils/MageVersion.java b/Mage.Common/src/mage/utils/MageVersion.java
index b1adde18b0b..c28ce7ebc7b 100644
--- a/Mage.Common/src/mage/utils/MageVersion.java
+++ b/Mage.Common/src/mage/utils/MageVersion.java
@@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable {
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 4;
- public final static String MAGE_VERSION_MINOR_PATCH = "v4";
+ public final static String MAGE_VERSION_MINOR_PATCH = "v7";
public final static String MAGE_VERSION_INFO = "";
private final int major;
diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java
index c705ffd740a..16b1da7e510 100644
--- a/Mage.Server/src/main/java/mage/server/Session.java
+++ b/Mage.Server/src/main/java/mage/server/Session.java
@@ -36,6 +36,7 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mage.MageException;
+import mage.constants.Constants;
import mage.interfaces.callback.ClientCallback;
import mage.players.net.UserData;
import mage.players.net.UserGroup;
@@ -157,7 +158,11 @@ public class Session {
} else {
user.getUserData().update(userData);
}
- if (user.getUserData().getAvatarId() == 51) {
+ if (user.getUserData().getAvatarId() < Constants.MIN_AVATAR_ID
+ || user.getUserData().getAvatarId() > Constants.MAX_AVATAR_ID) {
+ user.getUserData().setAvatarId(Constants.DEFAULT_AVATAR_ID);
+ }
+ if (user.getUserData().getAvatarId() == 11) {
user.getUserData().setAvatarId(updateAvatar(user.getName()));
}
return true;
@@ -169,22 +174,16 @@ public class Session {
//TODO: move to separate class
//TODO: add for checking for private key
switch (userName) {
- case "nantuko":
- return 1000;
case "North":
return 1006;
case "BetaSteward":
return 1008;
- case "loki":
- return 1012;
- case "Ayrat":
- return 1018;
case "Bandit":
return 1020;
- case "Wehk":
- return 66;
+ case "fireshoes":
+ return 1021;
}
- return 51;
+ return 11;
}
public String getId() {
diff --git a/Mage.Sets/src/mage/sets/alarareborn/FieldmistBorderpost.java b/Mage.Sets/src/mage/sets/alarareborn/FieldmistBorderpost.java
index fd91cace663..2db77ebb0ef 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/FieldmistBorderpost.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/FieldmistBorderpost.java
@@ -34,7 +34,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.WhiteManaAbility;
@@ -64,7 +64,7 @@ public class FieldmistBorderpost extends CardImpl {
// You may pay {1} and return a basic land you control to its owner's hand rather than pay Fieldmist Borderpost's mana cost.
Ability ability = new AlternativeCostSourceAbility(new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
// Fieldmist Borderpost enters the battlefield tapped.
diff --git a/Mage.Sets/src/mage/sets/alarareborn/FirewildBorderpost.java b/Mage.Sets/src/mage/sets/alarareborn/FirewildBorderpost.java
index 586307655c0..e0464f950e2 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/FirewildBorderpost.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/FirewildBorderpost.java
@@ -32,7 +32,7 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
@@ -64,7 +64,7 @@ public class FirewildBorderpost extends CardImpl {
// You may pay {1} and return a basic land you control to its owner's hand rather than pay Firewild Borderpost's mana cost.
Ability ability = new AlternativeCostSourceAbility(new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
// Veinfire Firewild enters the battlefield tapped.
diff --git a/Mage.Sets/src/mage/sets/alarareborn/MistveinBorderpost.java b/Mage.Sets/src/mage/sets/alarareborn/MistveinBorderpost.java
index dc01e983b54..050cda79a5d 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/MistveinBorderpost.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/MistveinBorderpost.java
@@ -34,7 +34,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
@@ -64,7 +64,7 @@ public class MistveinBorderpost extends CardImpl {
// You may pay {1} and return a basic land you control to its owner's hand rather than pay Mistvein Borderpost's mana cost.
Ability ability = new AlternativeCostSourceAbility(new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
// Mistvein Borderpost enters the battlefield tapped.
diff --git a/Mage.Sets/src/mage/sets/alarareborn/VeinfireBorderpost.java b/Mage.Sets/src/mage/sets/alarareborn/VeinfireBorderpost.java
index 29ca354d0c0..82c2243a1cb 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/VeinfireBorderpost.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/VeinfireBorderpost.java
@@ -34,7 +34,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.RedManaAbility;
@@ -64,7 +64,7 @@ public class VeinfireBorderpost extends CardImpl {
// You may pay {1} and return a basic land you control to its owner's hand rather than pay Veinfire Borderpost's mana cost.
Ability ability = new AlternativeCostSourceAbility(new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
// Veinfire Borderpost enters the battlefield tapped.
diff --git a/Mage.Sets/src/mage/sets/alarareborn/WildfieldBorderpost.java b/Mage.Sets/src/mage/sets/alarareborn/WildfieldBorderpost.java
index 2015f45f10a..f167e516df3 100644
--- a/Mage.Sets/src/mage/sets/alarareborn/WildfieldBorderpost.java
+++ b/Mage.Sets/src/mage/sets/alarareborn/WildfieldBorderpost.java
@@ -34,7 +34,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.WhiteManaAbility;
@@ -64,7 +64,7 @@ public class WildfieldBorderpost extends CardImpl {
// You may pay {1} and return a basic land you control to its owner's hand rather than pay Wildfield Borderpost's mana cost.
Ability ability = new AlternativeCostSourceAbility(new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
// Wildfield Borderpost enters the battlefield tapped.
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/CommandersAuthority.java b/Mage.Sets/src/mage/sets/avacynrestored/CommandersAuthority.java
index 7ec41d11dad..a408d0b7fe4 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/CommandersAuthority.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/CommandersAuthority.java
@@ -28,8 +28,6 @@
package mage.sets.avacynrestored;
import java.util.UUID;
-
-import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -38,6 +36,13 @@ import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.game.permanent.token.HumanToken;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DemonicRising.java b/Mage.Sets/src/mage/sets/avacynrestored/DemonicRising.java
index b3f1f6ee608..c320fa32841 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/DemonicRising.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/DemonicRising.java
@@ -29,7 +29,6 @@ package mage.sets.avacynrestored;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
@@ -38,7 +37,7 @@ import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.DemonToken;
import java.util.UUID;
@@ -53,7 +52,6 @@ public class DemonicRising extends CardImpl {
super(ownerId, 94, "Demonic Rising", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
this.expansionSetCode = "AVR";
-
// At the beginning of your end step, if you control exactly one creature, put a 5/5 black Demon creature token with flying onto the battlefield.
TriggeredAbility ability = new BeginningOfYourEndStepTriggeredAbility(new CreateTokenEffect(new DemonToken()), false);
this.addAbility(new ConditionalTriggeredAbility(ability, OneControlledCreatureCondition.getInstance(), ruleText));
@@ -68,15 +66,3 @@ public class DemonicRising extends CardImpl {
return new DemonicRising(this);
}
}
-
-class DemonToken extends Token {
- public DemonToken() {
- super("Demon", "a 5/5 black Demon creature token with flying");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Demon");
- power = new MageInt(5);
- toughness = new MageInt(5);
- addAbility(FlyingAbility.getInstance());
- }
-}
diff --git a/Mage.Sets/src/mage/sets/avacynrestored/VoiceOfTheProvinces.java b/Mage.Sets/src/mage/sets/avacynrestored/VoiceOfTheProvinces.java
index 552e5d59c41..4cb50e37fe1 100644
--- a/Mage.Sets/src/mage/sets/avacynrestored/VoiceOfTheProvinces.java
+++ b/Mage.Sets/src/mage/sets/avacynrestored/VoiceOfTheProvinces.java
@@ -36,7 +36,7 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.HumanToken;
/**
*
@@ -66,15 +66,3 @@ public class VoiceOfTheProvinces extends CardImpl {
return new VoiceOfTheProvinces(this);
}
}
-
-class HumanToken extends Token {
- public HumanToken() {
- super("Human", "1/1 white Human creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Human");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java
index eb6e52d3e8d..9da9eacd178 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java
@@ -60,7 +60,7 @@ public class GideonAllyOfZendikar extends CardImpl {
super(ownerId, 29, "Gideon, Ally of Zendikar", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{W}{W}");
this.expansionSetCode = "BFZ";
this.subtype.add("Gideon");
-
+
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false));
// +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.
@@ -69,7 +69,7 @@ public class GideonAllyOfZendikar extends CardImpl {
effect.setText("Prevent all damage that would be dealt to him this turn");
ability.addEffect(effect);
this.addAbility(ability);
-
+
// 0: Put a 2/2 white Knight Ally creature token onto the battlefield.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new KnightAllyToken()), 0));
@@ -94,6 +94,7 @@ class GideonAllyOfZendikarEmblem extends Emblem {
BoostControlledEffect effect = new BoostControlledEffect(1, 1, Duration.EndOfGame);
Ability ability = new SimpleStaticAbility(Zone.COMMAND, effect);
this.getAbilities().add(ability);
+ this.setExpansionSetCodeForImage("BFZ");
}
}
@@ -107,8 +108,8 @@ class GideonAllyOfZendikarToken extends Token {
subtype.add("Ally");
power = new MageInt(5);
toughness = new MageInt(5);
-
- addAbility(IndestructibleAbility.getInstance());
+
+ addAbility(IndestructibleAbility.getInstance());
}
}
@@ -123,4 +124,4 @@ class KnightAllyToken extends Token {
power = new MageInt(2);
toughness = new MageInt(2);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/InfuseWithTheElements.java b/Mage.Sets/src/mage/sets/battleforzendikar/InfuseWithTheElements.java
index 080658ef9cb..5f30903dbf6 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/InfuseWithTheElements.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/InfuseWithTheElements.java
@@ -53,7 +53,7 @@ public class InfuseWithTheElements extends CardImpl {
// Converge - Put X +1/+1 counters on target creature, where X is the number of colors of mana spent to cast Infuse with the Elements.
this.getSpellAbility().setAbilityWord(AbilityWord.CONVERGE);
- Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance());
+ Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), ColorsOfManaSpentToCastCount.getInstance());
effect.setText("Put X +1/+1 counters on target creature, where X is the number of colors of mana spent to cast {this}");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
index 2cabb3005db..557c17be929 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java
@@ -150,17 +150,16 @@ class KioraRevealEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
+ Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
- if (sourceObject != null && player != null) {
- Cards cards = new CardsImpl(Zone.PICK);
+ if (sourceObject != null && controller != null) {
+ Cards cards = new CardsImpl(Zone.LIBRARY);
+ cards.addAll(controller.getLibrary().getTopCards(game, 4));
boolean creatureCardFound = false;
boolean landCardFound = false;
- int count = Math.min(player.getLibrary().size(), 4);
- for (int i = 0; i < count; i++) {
- Card card = player.getLibrary().removeFromTop(game);
+ for (UUID cardId : cards) {
+ Card card = game.getCard(cardId);
if (card != null) {
- game.setZone(card.getId(), Zone.PICK);
cards.add(card);
if (card.getCardType().contains(CardType.CREATURE)) {
creatureCardFound = true;
@@ -172,30 +171,30 @@ class KioraRevealEffect extends OneShotEffect {
}
if (!cards.isEmpty()) {
- player.revealCards(sourceObject.getName(), cards, game);
- if ((creatureCardFound || landCardFound)
- && player.chooseUse(Outcome.DrawCard,
+ controller.revealCards(sourceObject.getName(), cards, game);
+ if ((creatureCardFound || landCardFound)
+ && controller.chooseUse(Outcome.DrawCard,
"Put a creature card and/or a land card into your hand?", source, game)) {
TargetCard target = new TargetCard(Zone.PICK, new FilterCreatureCard("creature card to put into your hand"));
- if (creatureCardFound && player.choose(Outcome.DrawCard, cards, target, game)) {
+ if (creatureCardFound && controller.chooseTarget(Outcome.DrawCard, cards, target, source, 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, null, Zone.HAND, source, game);
}
}
- target = new TargetCard(Zone.PICK, new FilterLandCard("land card to put into your hand"));
- if (landCardFound && player.choose(Outcome.DrawCard, cards, target, game)) {
+ target = new TargetCard(Zone.LIBRARY, new FilterLandCard("land card to put into your hand"));
+ if (landCardFound && controller.chooseTarget(Outcome.DrawCard, cards, target, source, 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, null, Zone.HAND, source, game);
}
}
}
}
- player.moveCards(cards, Zone.PICK, Zone.GRAVEYARD, source, game);
+ controller.moveCards(cards, null, Zone.GRAVEYARD, source, game);
return true;
}
return false;
@@ -208,12 +207,13 @@ class KioraMasterOfTheDepthsEmblem extends Emblem {
public KioraMasterOfTheDepthsEmblem() {
this.setName("EMBLEM: Kiora, Master of the Depths");
-
+
Ability ability = new EntersBattlefieldControlledTriggeredAbility(Zone.COMMAND,
new KioraFightEffect(), filter, true, SetTargetPointer.PERMANENT,
"Whenever a creature enters the battlefield under your control, you may have it fight target creature.");
ability.addTarget(new TargetCreaturePermanent());
this.getAbilities().add(ability);
+ this.setExpansionSetCodeForImage("BFZ");
}
}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java
index 036ce0ccb58..419aaba047a 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java
@@ -100,6 +100,7 @@ class ObNixilisReignitedEmblem extends Emblem {
setName("EMBLEM: Ob Nixilis Reignited");
this.getAbilities().add(new ObNixilisEmblemTriggeredAbility(new LoseLifeSourceControllerEffect(2), false));
+ this.setExpansionSetCodeForImage("BFZ");
}
}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/SlabHammer.java b/Mage.Sets/src/mage/sets/battleforzendikar/SlabHammer.java
index 31b09aed229..98e97a9e68e 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/SlabHammer.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/SlabHammer.java
@@ -30,7 +30,7 @@ package mage.sets.battleforzendikar;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAttachedTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@@ -41,7 +41,6 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledLandPermanent;
-import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
/**
@@ -58,9 +57,8 @@ public class SlabHammer extends CardImpl {
// Whenever equipped creature attacks, you may return a land you control to its owner's hand. If you do, the creature gets +2/+2 until end of turn.
Ability ability = new AttacksAttachedTriggeredAbility(
new DoIfCostPaid(new BoostEquippedEffect(2, 2, Duration.EndOfTurn),
- new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent())),
+ new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent())),
"Return a land you control to its owner's hand? (giving +2/+2 to the equipped creature)"));
- ability.addTarget(new TargetPermanent());
this.addAbility(ability);
// Equip {2}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/SunkenHollow.java b/Mage.Sets/src/mage/sets/battleforzendikar/SunkenHollow.java
index 654009000d4..0f9edc0a55a 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/SunkenHollow.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/SunkenHollow.java
@@ -47,9 +47,9 @@ import mage.filter.predicate.mageobject.SupertypePredicate;
* @author fireshoes
*/
public class SunkenHollow extends CardImpl {
-
+
private static final FilterLandPermanent filter = new FilterLandPermanent();
-
+
static {
filter.add(new SupertypePredicate("Basic"));
}
diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java
index 2e2648a2024..e34ac40666b 100644
--- a/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java
+++ b/Mage.Sets/src/mage/sets/battleforzendikar/ZadaHedronGrinder.java
@@ -102,12 +102,15 @@ class ZadaHedronGrinderTriggeredAbility extends TriggeredAbilityImpl {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (isControlledInstantOrSorcery(spell)) {
boolean targetsSource = false;
- for (Target target : spell.getSpellAbility().getTargets()) {
- for (UUID targetId : target.getTargets()) {
- if (targetId.equals(getSourceId())) {
- targetsSource = true;
- } else {
- return false;
+ for (UUID modeId : spell.getSpellAbility().getModes().getSelectedModes()) {
+ spell.getSpellAbility().getModes().setActiveMode(modeId);
+ for (Target target : spell.getSpellAbility().getTargets()) {
+ for (UUID targetId : target.getTargets()) {
+ if (targetId.equals(getSourceId())) {
+ targetsSource = true;
+ } else {
+ return false;
+ }
}
}
}
@@ -157,10 +160,15 @@ class ZadaHedronGrinderEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (spell != null && controller != null) {
Target usedTarget = null;
- for (Target target : spell.getSpellAbility().getTargets()) {
- if (target.getFirstTarget().equals(source.getSourceId())) {
- usedTarget = target.copy();
- usedTarget.clearChosen();
+ setUsedTarget:
+ for (UUID modeId : spell.getSpellAbility().getModes().getSelectedModes()) {
+ spell.getSpellAbility().getModes().setActiveMode(modeId);
+ for (Target target : spell.getSpellAbility().getTargets()) {
+ if (target.getFirstTarget().equals(source.getSourceId())) {
+ usedTarget = target.copy();
+ usedTarget.clearChosen();
+ break setUsedTarget;
+ }
}
}
if (usedTarget == null) {
@@ -169,11 +177,15 @@ class ZadaHedronGrinderEffect extends OneShotEffect {
for (Permanent creature : game.getState().getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) {
if (!creature.getId().equals(source.getSourceId()) && usedTarget.canTarget(source.getControllerId(), creature.getId(), source, game)) {
Spell copy = spell.copySpell();
- for (Target target : spell.getSpellAbility().getTargets()) {
- if (target.getClass().equals(usedTarget.getClass()) && target.getMessage().equals(usedTarget.getMessage())) {
- target.clearChosen();
- target.add(creature.getId(), game);
- break;
+ setTarget:
+ for (UUID modeId : spell.getSpellAbility().getModes().getSelectedModes()) {
+ copy.getSpellAbility().getModes().setActiveMode(modeId);
+ for (Target target : copy.getSpellAbility().getTargets()) {
+ if (target.getClass().equals(usedTarget.getClass()) && target.getMessage().equals(usedTarget.getMessage())) {
+ target.clearChosen();
+ target.add(creature.getId(), game);
+ break setTarget;
+ }
}
}
copy.setControllerId(source.getControllerId());
diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/Floodbringer.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/Floodbringer.java
index fa8a52c1232..cc2eab2da77 100644
--- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/Floodbringer.java
+++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/Floodbringer.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -64,7 +64,7 @@ public class Floodbringer extends CardImpl {
// {2}, Return a land you control to its owner's hand: Tap target land.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new GenericManaCost(2));
- ReturnToHandTargetPermanentCost cost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter));
+ ReturnToHandChosenControlledPermanentCost cost = new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter));
cost.setText("Return a land you control to its owner's hand");
ability.addCost(cost);
ability.addTarget(new TargetLandPermanent());
diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/FumikoTheLowblood.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/FumikoTheLowblood.java
index aa93e4cf8d5..02af73fe030 100644
--- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/FumikoTheLowblood.java
+++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/FumikoTheLowblood.java
@@ -40,6 +40,7 @@ import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
@@ -63,7 +64,7 @@ public class FumikoTheLowblood extends CardImpl {
// Creatures your opponents control attack each turn if able.
FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures your opponents control");
filter.add(new ControllerPredicate(TargetController.OPPONENT));
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AttacksIfAbleAllEffect(filter)));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AttacksIfAbleAllEffect(filter)), new AttackedThisTurnWatcher());
}
diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java
index 87999170a71..c30dfb512fe 100644
--- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java
+++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java
@@ -70,7 +70,6 @@ public class GoryosVengeance extends CardImpl {
this.expansionSetCode = "BOK";
this.subtype.add("Arcane");
-
// Return target legendary creature card from your graveyard to the battlefield. That creature gains haste. Exile it at the beginning of the next end step.
this.getSpellAbility().addEffect(new GoryosVengeanceEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter));
@@ -119,8 +118,8 @@ class GoryosVengeanceEffect extends OneShotEffect {
effect.setTargetPointer(new FixedTarget(permanent.getId()));
game.addEffect(effect, source);
// Exile it at end of turn
- Effect exileEffect = new ExileTargetEffect(new StringBuilder("Exile ").append(permanent.getName()).append(" at the beginning of the next end step").toString());
- exileEffect.setTargetPointer(new FixedTarget(card.getId()));
+ Effect exileEffect = new ExileTargetEffect("Exile " + permanent.getName() + " at the beginning of the next end step");
+ exileEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/SoratamiMindsweeper.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/SoratamiMindsweeper.java
index 141dfacf5e8..d3905fda60b 100644
--- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/SoratamiMindsweeper.java
+++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/SoratamiMindsweeper.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -66,7 +66,7 @@ public class SoratamiMindsweeper extends CardImpl {
// {2}, Return a land you control to its owner's hand: Target player puts the top two cards of his or her library into his or her graveyard.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,new PutLibraryIntoGraveTargetEffect(2), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetPlayer());
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java
index c0184c3793c..7b4c81b3575 100644
--- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java
+++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/VeilOfSecrecy.java
@@ -29,7 +29,7 @@ package mage.sets.betrayersofkamigawa;
import java.util.UUID;
import mage.ObjectColor;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
@@ -71,7 +71,7 @@ public class VeilOfSecrecy extends CardImpl {
this.getSpellAbility().addEffect(effect);
// Splice onto Arcane-Return a blue creature you control to its owner's hand.
- this.addAbility(new SpliceOntoArcaneAbility(new ReturnToHandTargetPermanentCost(new TargetControlledCreaturePermanent(filter))));
+ this.addAbility(new SpliceOntoArcaneAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledCreaturePermanent(filter))));
}
public VeilOfSecrecy(final VeilOfSecrecy card) {
diff --git a/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java b/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java
index 0fcebf1fd79..16e5cd91835 100644
--- a/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java
+++ b/Mage.Sets/src/mage/sets/bornofthegods/FloodtideSerpent.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.combat.CantAttackBlockUnlessPaysSourceEffect;
@@ -71,7 +71,7 @@ public class FloodtideSerpent extends CardImpl {
// Floodtide Serpent can't attack unless you return an enchantment you control to its owner's hand (This cost is paid as attackers are declared.)
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockUnlessPaysSourceEffect(
- new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)), PayCostToAttackBlockEffectImpl.RestrictType.ATTACK)));
+ new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)), PayCostToAttackBlockEffectImpl.RestrictType.ATTACK)));
}
@@ -106,7 +106,7 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl {
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(event.getPlayerId());
if (player != null) {
- ReturnToHandTargetPermanentCost attackCost = new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter));
+ ReturnToHandChosenControlledPermanentCost attackCost = new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter));
if (attackCost.canPay(source, source.getSourceId(), event.getPlayerId(), game)
&& player.chooseUse(Outcome.Neutral, "Return an enchantment you control to hand to attack?", source, game)) {
if (attackCost.pay(source, game, source.getSourceId(), event.getPlayerId(), true)) {
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MelokuTheCloudedMirror.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MelokuTheCloudedMirror.java
index d4e8b1e5690..f1678c2c14c 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/MelokuTheCloudedMirror.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MelokuTheCloudedMirror.java
@@ -35,7 +35,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -66,7 +66,7 @@ public class MelokuTheCloudedMirror extends CardImpl {
// {1}, Return a land you control to its owner's hand: Put a 1/1 blue Illusion creature token with flying onto the battlefield.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new MelokuTheCloudedMirrorToken(), 1), new GenericManaCost(1));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiCloudskater.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiCloudskater.java
index bbcd6a5665e..4832aa5cd82 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiCloudskater.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiCloudskater.java
@@ -25,21 +25,20 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.sets.championsofkamigawa;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.target.common.TargetControlledPermanent;
@@ -65,7 +64,7 @@ public class SoratamiCloudskater extends CardImpl {
// {2}, Return a land you control to its owner's hand: Draw a card, then discard a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardControllerEffect(), new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(1, 1, filter, true)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorGuard.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorGuard.java
index c429582b1d1..f06f9b1ef96 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorGuard.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorGuard.java
@@ -35,7 +35,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -74,7 +74,7 @@ public class SoratamiMirrorGuard extends CardImpl {
// {2}, Return a land you control to its owner's hand: Target creature with power 2 or less can't be blocked this turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedTargetEffect(), new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetCreaturePermanent(filterCreature));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorMage.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorMage.java
index 458fdc8a00c..e93013bedc7 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorMage.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiMirrorMage.java
@@ -25,21 +25,20 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.sets.championsofkamigawa;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.target.common.TargetControlledPermanent;
@@ -66,7 +65,7 @@ public class SoratamiMirrorMage extends CardImpl {
// {3}, Return three lands you control to their owner's hand: Return target creature to its owner's hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new GenericManaCost(3));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(3, 3, filter, false)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(3, 3, filter, true)));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiRainshaper.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiRainshaper.java
index 7f32cbe86db..3d0e59bc518 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiRainshaper.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiRainshaper.java
@@ -35,7 +35,7 @@ import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -69,7 +69,7 @@ public class SoratamiRainshaper extends CardImpl {
// {3}, Return a land you control to its owner's hand: Target creature you control gains shroud until end of turn. (It can't be the target of spells or abilities.)
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), new GenericManaCost(3));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSavant.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSavant.java
index 1060fdd8b36..9d479f7d85e 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSavant.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSavant.java
@@ -35,7 +35,7 @@ import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CounterUnlessPaysEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -67,7 +67,7 @@ public class SoratamiSavant extends CardImpl {
// {3}, Return a land you control to its owner's hand: Counter target spell unless its controller pays {3}.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterUnlessPaysEffect(new GenericManaCost(3)), new GenericManaCost(3));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetSpell());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSeer.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSeer.java
index 344923e03db..9887cb743b1 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSeer.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SoratamiSeer.java
@@ -36,7 +36,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -70,7 +70,7 @@ public class SoratamiSeer extends CardImpl {
// {4}, Return two lands you control to their owner's hand: Discard all the cards in your hand, then draw that many cards.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SoratamiSeerEffect(), new GenericManaCost(4));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(2, 2, filter, false)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(2, 2, filter, false)));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/UyoSilentProphet.java b/Mage.Sets/src/mage/sets/championsofkamigawa/UyoSilentProphet.java
index 9b0b414d4ae..e3f4928b4fa 100644
--- a/Mage.Sets/src/mage/sets/championsofkamigawa/UyoSilentProphet.java
+++ b/Mage.Sets/src/mage/sets/championsofkamigawa/UyoSilentProphet.java
@@ -34,7 +34,7 @@ import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CopyTargetSpellEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -75,7 +75,7 @@ public class UyoSilentProphet extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {2}, Return two lands you control to their owner's hand: Copy target instant or sorcery spell. You may choose new targets for the copy.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CopyTargetSpellEffect(), new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), false)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), false)));
ability.addTarget(new TargetSpell(filter));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/commander/AvatarOfSlaughter.java b/Mage.Sets/src/mage/sets/commander/AvatarOfSlaughter.java
index bfe50914d20..da89c528bdd 100644
--- a/Mage.Sets/src/mage/sets/commander/AvatarOfSlaughter.java
+++ b/Mage.Sets/src/mage/sets/commander/AvatarOfSlaughter.java
@@ -41,6 +41,7 @@ import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
@@ -62,7 +63,7 @@ public class AvatarOfSlaughter extends CardImpl {
effect = new AttacksIfAbleAllEffect(new FilterCreaturePermanent("creatures"));
effect.setText("and attack each turn if able");
ability.addEffect(effect);
- this.addAbility(ability);
+ this.addAbility(ability, new AttackedThisTurnWatcher());
}
public AvatarOfSlaughter(final AvatarOfSlaughter card) {
diff --git a/Mage.Sets/src/mage/sets/commander2013/SpringjackPasture.java b/Mage.Sets/src/mage/sets/commander2013/SpringjackPasture.java
index 8fafdc13ef2..d4873e2dd16 100644
--- a/Mage.Sets/src/mage/sets/commander2013/SpringjackPasture.java
+++ b/Mage.Sets/src/mage/sets/commander2013/SpringjackPasture.java
@@ -50,7 +50,7 @@ import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.GoatToken;
import mage.players.Player;
/**
@@ -136,17 +136,3 @@ class SpringjackPastureEffect extends OneShotEffect {
return new SpringjackPastureEffect(this);
}
}
-
-class GoatToken extends Token {
-
- public GoatToken() {
- super("Goat", "0/1 white Goat creature token");
- setOriginalExpansionSetCode("EVE");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Goat");
- power = new MageInt(0);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java b/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java
index 5cc2d1a4c95..92b4f50836f 100644
--- a/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java
+++ b/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java
@@ -32,14 +32,14 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ExileTargetEffect;
-import mage.abilities.effects.common.ReturnToHandTargetEffect;
+import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.common.TargetCardInGraveyard;
-import mage.target.common.TargetControlledCreaturePermanent;
/**
*
@@ -60,8 +60,8 @@ public class Stonecloaker extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Stonecloaker enters the battlefield, return a creature you control to its owner's hand.
- Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false);
- ability.addTarget(new TargetControlledCreaturePermanent());
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(new FilterControlledCreaturePermanent()), true);
+
this.addAbility(ability);
// When Stonecloaker enters the battlefield, exile target card from a graveyard.
ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect(), false);
diff --git a/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java b/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java
index e684acd3028..608f28407cd 100644
--- a/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java
+++ b/Mage.Sets/src/mage/sets/commander2013/TemptWithDiscovery.java
@@ -27,6 +27,8 @@
*/
package mage.sets.commander2013;
+import java.util.LinkedHashSet;
+import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@@ -51,7 +53,6 @@ public class TemptWithDiscovery extends CardImpl {
super(ownerId, 174, "Tempt with Discovery", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{G}");
this.expansionSetCode = "C13";
-
// Tempting offer - Search your library for a land card and put it onto the battlefield.
// Each opponent may search his or her library for a land card and put it onto the battlefield.
// For each opponent who searches a library this way, search your library for a land card and put it onto the battlefield.
@@ -89,12 +90,14 @@ class TemptWithDiscoveryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
+ Set playersShuffle = new LinkedHashSet<>();
+ playersShuffle.add(controller.getId());
TargetCardInLibrary target = new TargetCardInLibrary(new FilterLandCard());
if (controller.searchLibrary(target, game)) {
- for (UUID cardId: target.getTargets()) {
+ for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
- card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), controller.getId());
+ controller.moveCards(card, null, Zone.BATTLEFIELD, source, game);
}
}
}
@@ -105,11 +108,12 @@ class TemptWithDiscoveryEffect extends OneShotEffect {
if (opponent.chooseUse(outcome, "Search your library for a land card and put it onto the battlefield?", source, game)) {
target.clearChosen();
opponentsUsedSearch++;
+ playersShuffle.add(playerId);
if (opponent.searchLibrary(target, game)) {
- for (UUID cardId: target.getTargets()) {
+ for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
- card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), opponent.getId());
+ opponent.moveCards(card, null, Zone.BATTLEFIELD, source, game);
}
}
}
@@ -119,17 +123,23 @@ class TemptWithDiscoveryEffect extends OneShotEffect {
if (opponentsUsedSearch > 0) {
target = new TargetCardInLibrary(0, opponentsUsedSearch, new FilterLandCard());
if (controller.searchLibrary(target, game)) {
- for (UUID cardId: target.getTargets()) {
+ for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
- card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), controller.getId());
+ controller.moveCards(card, null, Zone.BATTLEFIELD, source, game);
}
}
}
}
+ for (UUID playerId : playersShuffle) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ player.shuffleLibrary(game);
+ }
+ }
return true;
}
-
+
return false;
}
}
diff --git a/Mage.Sets/src/mage/sets/commander2014/CoralAtoll.java b/Mage.Sets/src/mage/sets/commander2014/CoralAtoll.java
index d2a186eb83c..3785405c2c3 100644
--- a/Mage.Sets/src/mage/sets/commander2014/CoralAtoll.java
+++ b/Mage.Sets/src/mage/sets/commander2014/CoralAtoll.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.SimpleManaAbility;
@@ -66,7 +66,7 @@ public class CoralAtoll extends CardImpl {
// Coral Atoll enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// When Coral Atoll enters the battlefield, sacrifice it unless you return an untapped Island you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {1}{U} to your mana pool.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 1, 0, 0, 1,0 ), new TapSourceCost()));
diff --git a/Mage.Sets/src/mage/sets/commander2014/DormantVolcano.java b/Mage.Sets/src/mage/sets/commander2014/DormantVolcano.java
index 800f515fca7..c4b046863bd 100644
--- a/Mage.Sets/src/mage/sets/commander2014/DormantVolcano.java
+++ b/Mage.Sets/src/mage/sets/commander2014/DormantVolcano.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.SimpleManaAbility;
@@ -66,7 +66,7 @@ public class DormantVolcano extends CardImpl {
this.addAbility(new EntersBattlefieldTappedAbility());
// When Dormant Volcano enters the battlefield, sacrifice it unless you return an untapped Mountain you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {1}{R} to your mana pool.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(1, 0, 0, 0, 0, 1,0 ), new TapSourceCost()));
diff --git a/Mage.Sets/src/mage/sets/commander2014/Everglades.java b/Mage.Sets/src/mage/sets/commander2014/Everglades.java
index 7cf1f874132..e9693d66a88 100644
--- a/Mage.Sets/src/mage/sets/commander2014/Everglades.java
+++ b/Mage.Sets/src/mage/sets/commander2014/Everglades.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.SimpleManaAbility;
@@ -53,7 +53,7 @@ public class Everglades extends CardImpl {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("an untapped Swamp");
- static{
+ static {
filter.add(new SubtypePredicate("Swamp"));
filter.add(Predicates.not(new TappedPredicate()));
}
@@ -66,10 +66,10 @@ public class Everglades extends CardImpl {
this.addAbility(new EntersBattlefieldTappedAbility());
// When Everglades enters the battlefield, sacrifice it unless you return an untapped Swamp you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(1, 1, filter, true)))));
// {tap}: Add {1}{B} to your mana pool.
- this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 0, 1, 1,0 ), new TapSourceCost()));
+ this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 0, 1, 1, 0), new TapSourceCost()));
}
diff --git a/Mage.Sets/src/mage/sets/commander2014/JungleBasin.java b/Mage.Sets/src/mage/sets/commander2014/JungleBasin.java
index c90e7f0e107..dfa53c525a9 100644
--- a/Mage.Sets/src/mage/sets/commander2014/JungleBasin.java
+++ b/Mage.Sets/src/mage/sets/commander2014/JungleBasin.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.SimpleManaAbility;
@@ -66,7 +66,7 @@ public class JungleBasin extends CardImpl {
this.addAbility(new EntersBattlefieldTappedAbility());
// When Jungle Basin enters the battlefield, sacrifice it unless you return an untapped Forest you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {1}{G} to your mana pool.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 1, 0, 0, 0, 1,0 ), new TapSourceCost()));
diff --git a/Mage.Sets/src/mage/sets/commander2014/Karoo.java b/Mage.Sets/src/mage/sets/commander2014/Karoo.java
index eed52e1bc32..095d04b79d6 100644
--- a/Mage.Sets/src/mage/sets/commander2014/Karoo.java
+++ b/Mage.Sets/src/mage/sets/commander2014/Karoo.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.SimpleManaAbility;
@@ -66,7 +66,7 @@ public class Karoo extends CardImpl {
this.addAbility(new EntersBattlefieldTappedAbility());
// When Karoo enters the battlefield, sacrifice it unless you return an untapped Plains you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {1}{W} to your mana pool.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 1, 0, 1,0 ), new TapSourceCost()));
diff --git a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java
index 79cb66aa248..2593433d2ea 100644
--- a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java
+++ b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java
@@ -28,7 +28,6 @@
package mage.sets.commander2014;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility;
@@ -55,7 +54,7 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.command.Emblem;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.DemonToken;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
@@ -77,13 +76,13 @@ public class ObNixilisOfTheBlackOath extends CardImpl {
this.addAbility(new LoyaltyAbility(new ObNixilisOfTheBlackOathEffect1(), 2));
// -2: Put a 5/5 black Demon creature token with flying onto the battlefield. You lose 2 life.
- LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new CreateTokenEffect(new ObNixilisDemonToken()), -2);
+ LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new CreateTokenEffect(new DemonToken()), -2);
loyaltyAbility.addEffect(new LoseLifeSourceControllerEffect(2));
this.addAbility(loyaltyAbility);
// -8: You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power."
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new ObNixilisOfTheBlackOathEmblem()), -8));
-
+
// Ob Nixilis of the Black Oath can be your commander.
this.addAbility(CanBeYourCommanderAbility.getInstance());
}
@@ -134,23 +133,6 @@ class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect {
}
-class ObNixilisDemonToken extends Token {
-
- ObNixilisDemonToken() {
- super("Demon", "5/5 black Demon creature token with flying");
- setTokenType(1);
- setOriginalExpansionSetCode("C14");
- cardType.add(CardType.CREATURE);
- subtype.add("Demon");
-
- color.setBlack(true);
- power = new MageInt(5);
- toughness = new MageInt(5);
-
- addAbility(FlyingAbility.getInstance());
- }
-}
-
class ObNixilisOfTheBlackOathEmblem extends Emblem {
// You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power."
public ObNixilisOfTheBlackOathEmblem() {
diff --git a/Mage.Sets/src/mage/sets/commander2014/WarmongerHellkite.java b/Mage.Sets/src/mage/sets/commander2014/WarmongerHellkite.java
index facef8d227a..450a026bcab 100644
--- a/Mage.Sets/src/mage/sets/commander2014/WarmongerHellkite.java
+++ b/Mage.Sets/src/mage/sets/commander2014/WarmongerHellkite.java
@@ -62,7 +62,7 @@ public class WarmongerHellkite extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// All creatures attack each combat if able.
- Effect effect = new AttacksIfAbleAllEffect(new FilterCreaturePermanent("creatures"));
+ Effect effect = new AttacksIfAbleAllEffect(new FilterCreaturePermanent("creatures"), Duration.WhileOnBattlefield, true);
effect.setText("All creatures attack each combat if able");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java
index fcae2dcac52..ae89e66ea5d 100644
--- a/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java
+++ b/Mage.Sets/src/mage/sets/conflux/MasterTransmuter.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect;
@@ -61,7 +61,7 @@ public class MasterTransmuter extends CardImpl {
// {U}, {tap}, Return an artifact you control to its owner's hand: You may put an artifact card from your hand onto the battlefield.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutPermanentOnBattlefieldEffect(new FilterArtifactCard("an artifact card")), new ManaCostsImpl("{U}"));
ability.addCost(new TapSourceCost());
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact"))));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact"))));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/darkascension/GatherTheTownsfolk.java b/Mage.Sets/src/mage/sets/darkascension/GatherTheTownsfolk.java
index d734501cf7f..15553884e18 100644
--- a/Mage.Sets/src/mage/sets/darkascension/GatherTheTownsfolk.java
+++ b/Mage.Sets/src/mage/sets/darkascension/GatherTheTownsfolk.java
@@ -30,13 +30,12 @@ package mage.sets.darkascension;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.condition.common.FatefulHourCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.HumanToken;
/**
*
@@ -64,17 +63,3 @@ public class GatherTheTownsfolk extends CardImpl {
return new GatherTheTownsfolk(this);
}
}
-
-class HumanToken extends Token {
-
- public HumanToken() {
- super("Human", "1/1 white Human creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Human");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-
-}
diff --git a/Mage.Sets/src/mage/sets/darkascension/IncreasingDevotion.java b/Mage.Sets/src/mage/sets/darkascension/IncreasingDevotion.java
index e5405b471e6..12f7f2fcd06 100644
--- a/Mage.Sets/src/mage/sets/darkascension/IncreasingDevotion.java
+++ b/Mage.Sets/src/mage/sets/darkascension/IncreasingDevotion.java
@@ -28,14 +28,18 @@
package mage.sets.darkascension;
import java.util.UUID;
-
-import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.TimingRule;
+import mage.constants.Zone;
import mage.game.Game;
+import mage.game.permanent.token.HumanToken;
import mage.game.stack.Spell;
/**
@@ -48,7 +52,6 @@ public class IncreasingDevotion extends CardImpl {
super(ownerId, 11, "Increasing Devotion", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{W}{W}");
this.expansionSetCode = "DKA";
-
// Put five 1/1 white Human creature tokens onto the battlefield. If Increasing Devotion was cast from a graveyard, put ten of those tokens onto the battlefield instead.
this.getSpellAbility().addEffect(new IncreasingDevotionEffect());
diff --git a/Mage.Sets/src/mage/sets/darkascension/ThrabenDoomsayer.java b/Mage.Sets/src/mage/sets/darkascension/ThrabenDoomsayer.java
index 7977e58f2d5..0b0946ed834 100644
--- a/Mage.Sets/src/mage/sets/darkascension/ThrabenDoomsayer.java
+++ b/Mage.Sets/src/mage/sets/darkascension/ThrabenDoomsayer.java
@@ -41,6 +41,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
+import mage.game.permanent.token.HumanToken;
/**
*
diff --git a/Mage.Sets/src/mage/sets/darksteel/SunderingTitan.java b/Mage.Sets/src/mage/sets/darksteel/SunderingTitan.java
index 40e1cc019e2..bf12c5dd792 100644
--- a/Mage.Sets/src/mage/sets/darksteel/SunderingTitan.java
+++ b/Mage.Sets/src/mage/sets/darksteel/SunderingTitan.java
@@ -32,9 +32,7 @@ import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
-import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.EntersOrLeavesTheBattlefieldSourceTriggeredAbility;
-import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@@ -98,19 +96,18 @@ class SunderingTitanDestroyLandEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
Set lands = new HashSet<>();
if (controller != null && sourcePermanent != null) {
- for (String landName : new String[] {"Forest","Island","Mountain","Plains","Swamp"}) {
- FilterLandPermanent filter = new FilterLandPermanent(new StringBuilder(landName).append(" to destroy").toString());
+ for (String landName : new String[]{"Forest", "Island", "Mountain", "Plains", "Swamp"}) {
+ FilterLandPermanent filter = new FilterLandPermanent(landName + " to destroy");
filter.add(new SubtypePredicate(landName));
- Target target = new TargetLandPermanent(1,1, filter, true);
+ Target target = new TargetLandPermanent(1, 1, filter, true);
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
controller.chooseTarget(outcome, target, source, game);
lands.add(target.getFirstTarget());
}
-
}
if (!lands.isEmpty()) {
int destroyedLands = 0;
- for (UUID landId: lands) {
+ for (UUID landId : lands) {
Permanent land = game.getPermanent(landId);
if (land != null) {
if (land.destroy(source.getSourceId(), game, false)) {
@@ -118,9 +115,9 @@ class SunderingTitanDestroyLandEffect extends OneShotEffect {
}
}
}
- game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(": ").append(destroyedLands).append(destroyedLands > 1 ? " lands were destroyed":"land was destroyed").toString());
+ game.informPlayers(sourcePermanent.getLogName() + ": " + destroyedLands + (destroyedLands > 1 ? " lands were" : "land was") + " destroyed");
}
-
+ return true;
}
return false;
}
diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SecureTheWastes.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SecureTheWastes.java
index 0f3666570af..102d77a2e78 100644
--- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SecureTheWastes.java
+++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SecureTheWastes.java
@@ -28,13 +28,12 @@
package mage.sets.dragonsoftarkir;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.WarriorToken;
/**
*
@@ -47,7 +46,7 @@ public class SecureTheWastes extends CardImpl {
this.expansionSetCode = "DTK";
// Put X 1/1 white Warrior creature tokens onto the battlefield.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SecureTheWastesToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new WarriorToken(), new ManacostVariableValue()));
}
public SecureTheWastes(final SecureTheWastes card) {
@@ -59,17 +58,3 @@ public class SecureTheWastes extends CardImpl {
return new SecureTheWastes(this);
}
}
-
-class SecureTheWastesToken extends Token {
-
- SecureTheWastesToken() {
- super("Warrior", "1/1 white Warrior creature token");
- this.setOriginalExpansionSetCode("DTK");
- cardType.add(CardType.CREATURE);
- subtype.add("Warrior");
-
- color.setWhite(true);
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/eventide/SpringjackShepherd.java b/Mage.Sets/src/mage/sets/eventide/SpringjackShepherd.java
index 460d913355a..481269f78f2 100644
--- a/Mage.Sets/src/mage/sets/eventide/SpringjackShepherd.java
+++ b/Mage.Sets/src/mage/sets/eventide/SpringjackShepherd.java
@@ -1,116 +1,104 @@
-/*
- * 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.sets.eventide;
-
-import java.util.UUID;
-import mage.MageInt;
-import mage.ObjectColor;
-import mage.abilities.Ability;
-import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
-import mage.abilities.effects.common.CreateTokenEffect;
-import mage.cards.CardImpl;
-import mage.constants.CardType;
-import mage.constants.Rarity;
-import mage.filter.FilterPermanent;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.game.permanent.token.Token;
-
-/**
- *
- * @author jeffwadsworth
- *
- */
-public class SpringjackShepherd extends CardImpl {
-
- public SpringjackShepherd(UUID ownerId) {
- super(ownerId, 15, "Springjack Shepherd", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}");
- this.expansionSetCode = "EVE";
- this.subtype.add("Kithkin");
- this.subtype.add("Wizard");
-
- this.power = new MageInt(1);
- this.toughness = new MageInt(2);
-
- // Chroma - When Springjack Shepherd enters the battlefield, put a 0/1 white Goat creature token onto the battlefield for each white mana symbol in the mana costs of permanents you control.
- Effect effect = new CreateTokenEffect(new GoatToken(), new ChromaSpringjackShepherdCount());
- effect.setText("Chroma - When Springjack Shepherd enters the battlefield, put a 0/1 white Goat creature token onto the battlefield for each white mana symbol in the mana costs of permanents you control.");
- this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false, true));
-
- }
-
- public SpringjackShepherd(final SpringjackShepherd card) {
- super(card);
- }
-
- @Override
- public SpringjackShepherd copy() {
- return new SpringjackShepherd(this);
- }
-}
-
-class ChromaSpringjackShepherdCount implements DynamicValue {
-
- @Override
- public int calculate(Game game, Ability sourceAbility, Effect effect) {
- int chroma = 0;
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterPermanent(), sourceAbility.getControllerId(), game)) {
- chroma += permanent.getManaCost().getMana().getWhite();
- }
- return chroma;
- }
-
- @Override
- public DynamicValue copy() {
- return new ChromaSpringjackShepherdCount();
- }
-
- @Override
- public String toString() {
- return "1";
- }
-
- @Override
- public String getMessage() {
- return "";
- }
-}
-
-class GoatToken extends Token {
-
- public GoatToken() {
- super("Goat", "a 0/1 white Goat creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
- subtype.add("Goat");
- power = new MageInt(0);
- toughness = new MageInt(1);
- }
+/*
+ * 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.sets.eventide;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.ObjectColor;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.filter.FilterPermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.GoatToken;
+
+/**
+ *
+ * @author jeffwadsworth
+ *
+ */
+public class SpringjackShepherd extends CardImpl {
+
+ public SpringjackShepherd(UUID ownerId) {
+ super(ownerId, 15, "Springjack Shepherd", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}");
+ this.expansionSetCode = "EVE";
+ this.subtype.add("Kithkin");
+ this.subtype.add("Wizard");
+
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(2);
+
+ // Chroma - When Springjack Shepherd enters the battlefield, put a 0/1 white Goat creature token onto the battlefield for each white mana symbol in the mana costs of permanents you control.
+ Effect effect = new CreateTokenEffect(new GoatToken(), new ChromaSpringjackShepherdCount());
+ effect.setText("Chroma - When Springjack Shepherd enters the battlefield, put a 0/1 white Goat creature token onto the battlefield for each white mana symbol in the mana costs of permanents you control.");
+ this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false, true));
+
+ }
+
+ public SpringjackShepherd(final SpringjackShepherd card) {
+ super(card);
+ }
+
+ @Override
+ public SpringjackShepherd copy() {
+ return new SpringjackShepherd(this);
+ }
+}
+
+class ChromaSpringjackShepherdCount implements DynamicValue {
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ int chroma = 0;
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterPermanent(), sourceAbility.getControllerId(), game)) {
+ chroma += permanent.getManaCost().getMana().getWhite();
+ }
+ return chroma;
+ }
+
+ @Override
+ public DynamicValue copy() {
+ return new ChromaSpringjackShepherdCount();
+ }
+
+ @Override
+ public String toString() {
+ return "1";
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
}
diff --git a/Mage.Sets/src/mage/sets/exodus/DauthiCutthroat.java b/Mage.Sets/src/mage/sets/exodus/DauthiCutthroat.java
new file mode 100644
index 00000000000..031474abcb2
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/exodus/DauthiCutthroat.java
@@ -0,0 +1,83 @@
+/*
+ * 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.sets.exodus;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class DauthiCutthroat extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with shadow");
+
+ static {
+ filter.add(new AbilityPredicate(ShadowAbility.class));
+ }
+
+ public DauthiCutthroat(UUID ownerId) {
+ super(ownerId, 57, "Dauthi Cutthroat", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{B}");
+ this.expansionSetCode = "EXO";
+ this.subtype.add("Dauthi");
+ this.subtype.add("Minion");
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // {1}{B}, {tap}: Destroy target creature with shadow.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{1}{B}"));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetCreaturePermanent(filter));
+ this.addAbility(ability);
+ }
+
+ public DauthiCutthroat(final DauthiCutthroat card) {
+ super(card);
+ }
+
+ @Override
+ public DauthiCutthroat copy() {
+ return new DauthiCutthroat(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/futuresight/CutthroatIlDal.java b/Mage.Sets/src/mage/sets/futuresight/CutthroatIlDal.java
new file mode 100644
index 00000000000..b74a7724e2b
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/futuresight/CutthroatIlDal.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.futuresight;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.common.HellbentCondition;
+import mage.abilities.decorator.ConditionalContinuousEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class CutthroatIlDal extends CardImpl {
+
+ public CutthroatIlDal(UUID ownerId) {
+ super(ownerId, 64, "Cutthroat il-Dal", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}");
+ this.expansionSetCode = "FUT";
+ this.subtype.add("Human");
+ this.subtype.add("Rogue");
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(1);
+
+ // Hellbent - Cutthroat il-Dal has shadow as long as you have no cards in hand.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
+ new GainAbilitySourceEffect(ShadowAbility.getInstance(), Duration.WhileOnBattlefield), HellbentCondition.getInstance(),
+ "Hellbent - {this} has shadow as long as you have no cards in hand"))); }
+
+ public CutthroatIlDal(final CutthroatIlDal card) {
+ super(card);
+ }
+
+ @Override
+ public CutthroatIlDal copy() {
+ return new CutthroatIlDal(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/futuresight/InfiltratorIlKor.java b/Mage.Sets/src/mage/sets/futuresight/InfiltratorIlKor.java
new file mode 100644
index 00000000000..0b402309a6d
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/futuresight/InfiltratorIlKor.java
@@ -0,0 +1,67 @@
+/*
+ * 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.sets.futuresight;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.keyword.ShadowAbility;
+import mage.abilities.keyword.SuspendAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class InfiltratorIlKor extends CardImpl {
+
+ public InfiltratorIlKor(UUID ownerId) {
+ super(ownerId, 37, "Infiltrator il-Kor", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{U}");
+ this.expansionSetCode = "FUT";
+ this.subtype.add("Kor");
+ this.subtype.add("Rogue");
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(1);
+
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // Suspend 2-{1}{U}
+ this.addAbility(new SuspendAbility(2, new ManaCostsImpl("{1}{U}"), this));
+ }
+
+ public InfiltratorIlKor(final InfiltratorIlKor card) {
+ super(card);
+ }
+
+ @Override
+ public InfiltratorIlKor copy() {
+ return new InfiltratorIlKor(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java b/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java
index 08e333a7ef6..16fef1058fe 100644
--- a/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java
+++ b/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java
@@ -44,7 +44,7 @@ import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.DemonToken;
import mage.target.common.TargetControlledCreaturePermanent;
/**
@@ -111,18 +111,3 @@ class SkirsdagHighPriestCost extends CostImpl {
return paid;
}
}
-
-class DemonToken extends Token {
-
- DemonToken() {
- super("Demon", "5/5 black Demon creature token with flying");
- cardType.add(CardType.CREATURE);
- subtype.add("Demon");
-
- color.setBlack(true);
- power = new MageInt(5);
- toughness = new MageInt(5);
-
- addAbility(FlyingAbility.getInstance());
- }
-}
diff --git a/Mage.Sets/src/mage/sets/jacevschandra/FathomSeer.java b/Mage.Sets/src/mage/sets/jacevschandra/FathomSeer.java
index b3b9fa11778..e322cd800d2 100644
--- a/Mage.Sets/src/mage/sets/jacevschandra/FathomSeer.java
+++ b/Mage.Sets/src/mage/sets/jacevschandra/FathomSeer.java
@@ -30,7 +30,7 @@ package mage.sets.jacevschandra;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.MorphAbility;
import mage.cards.CardImpl;
@@ -60,7 +60,7 @@ public class FathomSeer extends CardImpl {
this.toughness = new MageInt(3);
// Morph-Return two Islands you control to their owner's hand.
- this.addAbility(new MorphAbility(this, new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(2,2, filter, true))));
+ this.addAbility(new MorphAbility(this, new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(2,2, filter, true))));
// When Fathom Seer is turned face up, draw two cards.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new DrawCardSourceControllerEffect(2)));
}
diff --git a/Mage.Sets/src/mage/sets/jacevschandra/Gush.java b/Mage.Sets/src/mage/sets/jacevschandra/Gush.java
index eabcd98d8c8..ab9d0a300fa 100644
--- a/Mage.Sets/src/mage/sets/jacevschandra/Gush.java
+++ b/Mage.Sets/src/mage/sets/jacevschandra/Gush.java
@@ -29,7 +29,7 @@ package mage.sets.jacevschandra;
import java.util.UUID;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@@ -55,7 +55,7 @@ public class Gush extends CardImpl {
// You may return two Islands you control to their owner's hand rather than pay Gush's mana cost.
AlternativeCostSourceAbility ability;
- ability = new AlternativeCostSourceAbility(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(2, 2, filter, true)));
+ ability = new AlternativeCostSourceAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(2, 2, filter, true)));
this.addAbility(ability);
// Draw two cards.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
diff --git a/Mage.Sets/src/mage/sets/jacevschandra/WaterspoutDjinn.java b/Mage.Sets/src/mage/sets/jacevschandra/WaterspoutDjinn.java
index ecf4bef9930..711ed79fc65 100644
--- a/Mage.Sets/src/mage/sets/jacevschandra/WaterspoutDjinn.java
+++ b/Mage.Sets/src/mage/sets/jacevschandra/WaterspoutDjinn.java
@@ -30,7 +30,7 @@ package mage.sets.jacevschandra;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@@ -67,7 +67,7 @@ public class WaterspoutDjinn extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// At the beginning of your upkeep, sacrifice Waterspout Djinn unless you return an untapped Island you control to its owner's hand.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
- new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter))),
+ new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter))),
TargetController.YOU, false));
}
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/HeraldOfAnafenza.java b/Mage.Sets/src/mage/sets/khansoftarkir/HeraldOfAnafenza.java
index d1383261c6f..09e806e8bab 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/HeraldOfAnafenza.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/HeraldOfAnafenza.java
@@ -40,7 +40,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.WarriorToken;
import mage.game.stack.StackAbility;
/**
@@ -79,7 +79,7 @@ public class HeraldOfAnafenza extends CardImpl {
class HeraldOfAnafenzaTriggeredAbility extends TriggeredAbilityImpl {
public HeraldOfAnafenzaTriggeredAbility() {
- super(Zone.BATTLEFIELD, new CreateTokenEffect(new HeraldOfAnafenzaWarriorToken()), false);
+ super(Zone.BATTLEFIELD, new CreateTokenEffect(new WarriorToken()), false);
}
public HeraldOfAnafenzaTriggeredAbility(final HeraldOfAnafenzaTriggeredAbility ability) {
@@ -90,7 +90,7 @@ class HeraldOfAnafenzaTriggeredAbility extends TriggeredAbilityImpl {
public HeraldOfAnafenzaTriggeredAbility copy() {
return new HeraldOfAnafenzaTriggeredAbility(this);
}
-
+
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY;
@@ -112,18 +112,3 @@ class HeraldOfAnafenzaTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever you activate {this}'s outlast ability, " + super.getRule();
}
}
-
-class HeraldOfAnafenzaWarriorToken extends Token {
-
- public HeraldOfAnafenzaWarriorToken() {
- super("Warrior", "1/1 white Warrior creature token");
- this.setOriginalExpansionSetCode("KTK");
- this.setTokenType(1);
- cardType.add(CardType.CREATURE);
- subtype.add("Warrior");
-
- color.setWhite(true);
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/MarduCharm.java b/Mage.Sets/src/mage/sets/khansoftarkir/MarduCharm.java
index 44b4423042d..2153f4e42dd 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/MarduCharm.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/MarduCharm.java
@@ -28,7 +28,6 @@
package mage.sets.khansoftarkir;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffect;
@@ -48,7 +47,7 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.WarriorToken;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
@@ -61,12 +60,12 @@ import mage.target.targetpointer.FixedTarget;
public class MarduCharm extends CardImpl {
private static final FilterCard filter = new FilterCard("a noncreature, nonland card");
-
+
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
}
-
+
public MarduCharm(UUID ownerId) {
super(ownerId, 186, "Mardu Charm", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}{W}{B}");
this.expansionSetCode = "KTK";
@@ -76,18 +75,18 @@ public class MarduCharm extends CardImpl {
// * Mardu Charm deals 4 damage to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
-
+
// * Put two 1/1 white Warrior creature tokens onto the battlefield. They gain first strike until end of turn.
Mode mode = new Mode();
mode.getEffects().add(new MarduCharmCreateTokenEffect());
this.getSpellAbility().addMode(mode);
-
+
// * Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.
mode = new Mode();
mode.getEffects().add(new DiscardCardYouChooseTargetEffect(filter));
mode.getTargets().add(new TargetOpponent());
this.getSpellAbility().addMode(mode);
-
+
}
public MarduCharm(final MarduCharm card) {
@@ -101,26 +100,26 @@ public class MarduCharm extends CardImpl {
}
class MarduCharmCreateTokenEffect extends OneShotEffect {
-
+
public MarduCharmCreateTokenEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Put two 1/1 white Warrior creature tokens onto the battlefield. They gain first strike until end of turn";
}
-
+
public MarduCharmCreateTokenEffect(final MarduCharmCreateTokenEffect effect) {
super(effect);
}
-
+
@Override
public MarduCharmCreateTokenEffect copy() {
return new MarduCharmCreateTokenEffect(this);
}
-
+
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- CreateTokenEffect effect = new CreateTokenEffect(new MarduCharmWarriorToken(), 2);
+ CreateTokenEffect effect = new CreateTokenEffect(new WarriorToken(), 2);
effect.apply(game, source);
for (UUID tokenId :effect.getLastAddedTokenIds()) {
Permanent token = game.getPermanent(tokenId);
@@ -135,16 +134,3 @@ class MarduCharmCreateTokenEffect extends OneShotEffect {
return false;
}
}
-class MarduCharmWarriorToken extends Token {
-
- public MarduCharmWarriorToken() {
- super("Warrior", "1/1 white Warrior creature token");
- this.setOriginalExpansionSetCode("KTK");
- this.setTokenType(2);
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
- subtype.add("Warrior");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/MarduHordechief.java b/Mage.Sets/src/mage/sets/khansoftarkir/MarduHordechief.java
index 4452b0dd55b..5338301b668 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/MarduHordechief.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/MarduHordechief.java
@@ -36,7 +36,7 @@ import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.WarriorToken;
import mage.watchers.common.PlayerAttackedWatcher;
/**
@@ -55,7 +55,7 @@ public class MarduHordechief extends CardImpl {
this.toughness = new MageInt(3);
// Raid - When Mardu Hordechief enters the battlefield, if you attacked with a creature this turn, put a 1/1 white Warrior creature token onto the battlefield
- this.addAbility(new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MarduHordechiefToken())), RaidCondition.getInstance(),
+ this.addAbility(new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WarriorToken())), RaidCondition.getInstance(),
"Raid - When {this} enters the battlefield, if you attacked with a creature this turn, put a 1/1 white Warrior creature token onto the battlefield."),
new PlayerAttackedWatcher());
}
@@ -69,17 +69,3 @@ public class MarduHordechief extends CardImpl {
return new MarduHordechief(this);
}
}
-
-class MarduHordechiefToken extends Token {
-
- MarduHordechiefToken() {
- super("Warrior", "1/1 white Warrior creature token");
- this.setOriginalExpansionSetCode("KTK");
- cardType.add(CardType.CREATURE);
- subtype.add("Warrior");
-
- color.setWhite(true);
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/PearlLakeAncient.java b/Mage.Sets/src/mage/sets/khansoftarkir/PearlLakeAncient.java
index a2b8784709f..9681a0d2bc6 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/PearlLakeAncient.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/PearlLakeAncient.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.CantBeCounteredAbility;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.ProwessAbility;
@@ -67,7 +67,7 @@ public class PearlLakeAncient extends CardImpl {
// Return three lands you control to their owner's hand: Return Pearl Lake Ancient to its owner's hand.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true),
- new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(3, 3, new FilterControlledLandPermanent("lands"), true))));
+ new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(3, 3, new FilterControlledLandPermanent("lands"), true))));
}
public PearlLakeAncient(final PearlLakeAncient card) {
diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/TakeUpArms.java b/Mage.Sets/src/mage/sets/khansoftarkir/TakeUpArms.java
index 2d448508bb2..6aaf4499cac 100644
--- a/Mage.Sets/src/mage/sets/khansoftarkir/TakeUpArms.java
+++ b/Mage.Sets/src/mage/sets/khansoftarkir/TakeUpArms.java
@@ -28,12 +28,11 @@
package mage.sets.khansoftarkir;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.WarriorToken;
/**
*
@@ -47,7 +46,7 @@ public class TakeUpArms extends CardImpl {
// Put three 1/1 white Warrior creature tokens onto the battlefield.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new TakeUpArmsToken(), 3));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new WarriorToken(), 3));
}
public TakeUpArms(final TakeUpArms card) {
@@ -59,17 +58,3 @@ public class TakeUpArms extends CardImpl {
return new TakeUpArms(this);
}
}
-
-class TakeUpArmsToken extends Token {
-
- TakeUpArmsToken() {
- super("Warrior", "1/1 white Warrior creature token");
- this.setOriginalExpansionSetCode("KTK");
- cardType.add(CardType.CREATURE);
- subtype.add("Warrior");
-
- color.setWhite(true);
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/legions/BroodSliver.java b/Mage.Sets/src/mage/sets/legions/BroodSliver.java
index 48e856b3b72..86ea9e7ec7b 100644
--- a/Mage.Sets/src/mage/sets/legions/BroodSliver.java
+++ b/Mage.Sets/src/mage/sets/legions/BroodSliver.java
@@ -37,7 +37,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.SetTargetPointer;
import mage.filter.common.FilterCreaturePermanent;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.SliverToken;
/**
*
@@ -53,12 +53,11 @@ public class BroodSliver extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
- // Whenever a Sliver deals combat damage to a player, its controller may put a 1/1 colorless Sliver creature token onto the battlefield.
+ // Whenever a Sliver deals combat damage to a player, its controller may put a 1/1 colorless Sliver creature token onto the battlefield.
Effect effect = new CreateTokenTargetEffect(new SliverToken());
effect.setText("its controller may put a 1/1 colorless Sliver creature token onto the battlefield");
- this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(effect,
- new FilterCreaturePermanent("Sliver", "a Sliver"),
- true, SetTargetPointer.PLAYER, true));
+ this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(effect,
+ new FilterCreaturePermanent("Sliver", "a Sliver"), true, SetTargetPointer.PLAYER, true));
}
public BroodSliver(final BroodSliver card) {
@@ -70,14 +69,3 @@ public class BroodSliver extends CardImpl {
return new BroodSliver(this);
}
}
-
-class SliverToken extends Token {
-
- public SliverToken() {
- super("Sliver", "1/1 colorless Sliver creature token");
- cardType.add(CardType.CREATURE);
- subtype.add("Sliver");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/lorwyn/BoggartMob.java b/Mage.Sets/src/mage/sets/lorwyn/BoggartMob.java
index 0bfee0cd162..e80f8e9d8f4 100644
--- a/Mage.Sets/src/mage/sets/lorwyn/BoggartMob.java
+++ b/Mage.Sets/src/mage/sets/lorwyn/BoggartMob.java
@@ -38,14 +38,14 @@ import mage.constants.Rarity;
import mage.constants.SetTargetPointer;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.GoblinRogueToken;
/**
*
* @author fireshoes
*/
public class BoggartMob extends CardImpl {
-
+
private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Goblin you control");
static {
@@ -62,10 +62,10 @@ public class BoggartMob extends CardImpl {
// Champion a Goblin
this.addAbility(new ChampionAbility(this, "Goblin"));
-
+
// Whenever a Goblin you control deals combat damage to a player, you may put a 1/1 black Goblin Rogue creature token onto the battlefield.
this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility(
- new CreateTokenEffect(new BlackGoblinRogueToken()),
+ new CreateTokenEffect(new GoblinRogueToken()),
filter, true, SetTargetPointer.NONE, true));
}
@@ -78,15 +78,3 @@ public class BoggartMob extends CardImpl {
return new BoggartMob(this);
}
}
-
-class BlackGoblinRogueToken extends Token {
- BlackGoblinRogueToken() {
- super("Goblin Rogue", "1/1 black Goblin Rogue creature token");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Goblin");
- subtype.add("Rogue");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/lorwyn/FamiliarsRuse.java b/Mage.Sets/src/mage/sets/lorwyn/FamiliarsRuse.java
index ba12a2e3612..4bf7c42fe6b 100644
--- a/Mage.Sets/src/mage/sets/lorwyn/FamiliarsRuse.java
+++ b/Mage.Sets/src/mage/sets/lorwyn/FamiliarsRuse.java
@@ -27,17 +27,16 @@
*/
package mage.sets.lorwyn;
-import mage.constants.CardType;
-import mage.constants.Rarity;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import java.util.UUID;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.target.TargetSpell;
import mage.target.common.TargetControlledCreaturePermanent;
-import java.util.UUID;
-import mage.filter.common.FilterControlledCreaturePermanent;
-
/**
*
* @author Loki
@@ -48,7 +47,10 @@ public class FamiliarsRuse extends CardImpl {
super(ownerId, 64, "Familiar's Ruse", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{U}{U}");
this.expansionSetCode = "LRW";
- this.getSpellAbility().addCost(new ReturnToHandTargetPermanentCost(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent("creature"),false)));
+ // As an additional cost to cast Familiar's Ruse, return a creature you control to its owner's hand.
+ this.getSpellAbility().addCost(new ReturnToHandChosenControlledPermanentCost(
+ new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("creature"), true)));
+ // Counter target spell.
this.getSpellAbility().addEffect(new CounterTargetEffect());
this.getSpellAbility().addTarget(new TargetSpell());
}
diff --git a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java
index 9c4305c3bef..2575cf4bc83 100644
--- a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java
+++ b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java
@@ -46,7 +46,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.counters.CounterType;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.CatToken;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -91,15 +91,3 @@ public class AjaniCallerOfThePride extends CardImpl {
return new AjaniCallerOfThePride(this);
}
}
-
-class CatToken extends Token {
-
- public CatToken() {
- super("Cat", "2/2 white Cat creature tokens");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
- subtype.add("Cat");
- power = new MageInt(2);
- toughness = new MageInt(2);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/magic2013/RoaringPrimadox.java b/Mage.Sets/src/mage/sets/magic2013/RoaringPrimadox.java
index f2a2062eb01..5ed8a2f9894 100644
--- a/Mage.Sets/src/mage/sets/magic2013/RoaringPrimadox.java
+++ b/Mage.Sets/src/mage/sets/magic2013/RoaringPrimadox.java
@@ -28,22 +28,14 @@
package mage.sets.magic2013;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.MageInt;
-import mage.abilities.Ability;
import mage.abilities.common.OnEventTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.game.Game;
import mage.game.events.GameEvent.EventType;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import mage.target.common.TargetControlledCreaturePermanent;
/**
*
diff --git a/Mage.Sets/src/mage/sets/magic2013/TradingPost.java b/Mage.Sets/src/mage/sets/magic2013/TradingPost.java
index 2b933e21b2d..f6370a6d285 100644
--- a/Mage.Sets/src/mage/sets/magic2013/TradingPost.java
+++ b/Mage.Sets/src/mage/sets/magic2013/TradingPost.java
@@ -49,7 +49,7 @@ import mage.constants.Zone;
import mage.filter.common.FilterArtifactCard;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.GoatToken;
import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetControlledPermanent;
@@ -59,10 +59,10 @@ import mage.target.common.TargetControlledPermanent;
* @author jeffwadsworth
*/
public class TradingPost extends CardImpl {
-
+
final static FilterControlledPermanent filter = new FilterControlledPermanent("creature");
final static FilterControlledPermanent filter2 = new FilterControlledPermanent("artifact");
-
+
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter2.add(new CardTypePredicate(CardType.ARTIFACT));
@@ -77,26 +77,26 @@ public class TradingPost extends CardImpl {
ability1.addCost(new TapSourceCost());
ability1.addCost(new DiscardTargetCost(new TargetCardInHand()));
this.addAbility(ability1);
-
+
// {1}, {tap}, Pay 1 life: Put a 0/1 white Goat creature token onto the battlefield.
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new GoatToken()), new GenericManaCost(1));
ability2.addCost(new TapSourceCost());
ability2.addCost(new PayLifeCost(1));
this.addAbility(ability2);
-
+
// {1}, {tap}, Sacrifice a creature: Return target artifact card from your graveyard to your hand.
Ability ability3 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new GenericManaCost(1));
ability3.addTarget(new TargetCardInGraveyard(new FilterArtifactCard("artifact card in your graveyard")));
ability3.addCost(new TapSourceCost());
ability3.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
this.addAbility(ability3);
-
+
// {1}, {tap}, Sacrifice an artifact: Draw a card.
Ability ability4 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(1));
ability4.addCost(new TapSourceCost());
ability4.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2)));
this.addAbility(ability4);
-
+
}
public TradingPost(final TradingPost card) {
@@ -108,15 +108,3 @@ public class TradingPost extends CardImpl {
return new TradingPost(this);
}
}
-
-class GoatToken extends Token {
- public GoatToken() {
- super("Goat", "a 0/1 white Goat creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Goat");
- power = new MageInt(0);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java
index 62e2921c40a..1728e7f1f4a 100644
--- a/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java
+++ b/Mage.Sets/src/mage/sets/magic2014/AjanisChosen.java
@@ -43,6 +43,7 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.game.permanent.token.CatToken;
import mage.game.permanent.token.Token;
import mage.players.Player;
@@ -56,7 +57,7 @@ public class AjanisChosen extends CardImpl {
static {
filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
}
-
+
public AjanisChosen(UUID ownerId) {
super(ownerId, 2, "Ajani's Chosen", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}{W}");
this.expansionSetCode = "M14";
@@ -123,16 +124,3 @@ class AjanisChosenEffect extends OneShotEffect {
}
}
-
-
-class CatToken extends Token {
- public CatToken() {
- super("Cat", "2/2 white Cat creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Cat");
- power = new MageInt(2);
- toughness = new MageInt(2);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/magic2014/HiveStirrings.java b/Mage.Sets/src/mage/sets/magic2014/HiveStirrings.java
index 2d378cc5167..9f9a6a6f027 100644
--- a/Mage.Sets/src/mage/sets/magic2014/HiveStirrings.java
+++ b/Mage.Sets/src/mage/sets/magic2014/HiveStirrings.java
@@ -28,12 +28,11 @@
package mage.sets.magic2014;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.SliverToken;
/**
*
@@ -45,10 +44,8 @@ public class HiveStirrings extends CardImpl {
super(ownerId, 21, "Hive Stirrings", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{W}");
this.expansionSetCode = "M14";
-
// Put two 1/1 colorless Sliver creature tokens onto the battlefield.
this.getSpellAbility().addEffect(new CreateTokenEffect(new SliverToken(), 2));
-
}
public HiveStirrings(final HiveStirrings card) {
@@ -60,13 +57,3 @@ public class HiveStirrings extends CardImpl {
return new HiveStirrings(this);
}
}
-
-class SliverToken extends Token {
- SliverToken() {
- super("Sliver", "a 1/1 colorless Sliver creature token");
- cardType.add(CardType.CREATURE);
- subtype.add("Sliver");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/magic2015/ChasmSkulker.java b/Mage.Sets/src/mage/sets/magic2015/ChasmSkulker.java
index 874f933c5a9..b8af72b4240 100644
--- a/Mage.Sets/src/mage/sets/magic2015/ChasmSkulker.java
+++ b/Mage.Sets/src/mage/sets/magic2015/ChasmSkulker.java
@@ -29,7 +29,6 @@ package mage.sets.magic2015;
import java.util.UUID;
import mage.MageInt;
-import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.common.DrawCardControllerTriggeredAbility;
@@ -65,7 +64,7 @@ public class ChasmSkulker extends CardImpl {
// Whenever you draw a card, put a +1/+1 counter on Chasm Skulker.
this.addAbility(new DrawCardControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false));
-
+
// When Chasm Skulker dies, put X 1/1 blue Squid creature tokens with islandwalk onto the battlefield, where X is the number of +1/+1 counters on Chasm Skulker.
this.addAbility(new DiesTriggeredAbility(new ChasmSkulkerEffect(), false));
}
@@ -127,4 +126,4 @@ class ChasmSkulkerSquidToken extends Token {
this.addAbility(new IslandwalkAbility());
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java b/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java
index 9d23e6719af..cf2df4c91fa 100644
--- a/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java
+++ b/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java
@@ -50,6 +50,7 @@ import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.permanent.token.Token;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
@@ -59,15 +60,15 @@ public class GoblinRabblemaster extends CardImpl {
private static final FilterCreaturePermanent otherGoblinFilter = new FilterCreaturePermanent("Goblin", "Other Goblin creatures you control");
private static final FilterCreaturePermanent attackingFilter = new FilterCreaturePermanent("Goblin", "other attacking Goblin");
-
+
static {
otherGoblinFilter.add(new AnotherPredicate());
otherGoblinFilter.add(new ControllerPredicate(TargetController.YOU));
-
+
attackingFilter.add(new AttackingPredicate());
attackingFilter.add(new AnotherPredicate());
}
-
+
public GoblinRabblemaster(UUID ownerId) {
super(ownerId, 145, "Goblin Rabblemaster", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.expansionSetCode = "M15";
@@ -79,11 +80,11 @@ public class GoblinRabblemaster extends CardImpl {
// Other Goblin creatures you control attack each turn if able.
Effect effect = new AttacksIfAbleAllEffect(otherGoblinFilter);
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
-
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect), new AttackedThisTurnWatcher());
+
// At the beginning of combat on your turn, put a 1/1 red Goblin creature token with haste onto the battlefield.
this.addAbility(new BeginningOfCombatTriggeredAbility(new CreateTokenEffect(new GoblinToken()), TargetController.YOU, false));
-
+
// When Goblin Rabblemaster attacks, it gets +1/+0 until end of turn for each other attacking Goblin.
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(new PermanentsOnBattlefieldCount(attackingFilter), new StaticValue(0), Duration.EndOfTurn, true), false));
}
@@ -110,5 +111,5 @@ class GoblinToken extends Token {
toughness = new MageInt(1);
addAbility(HasteAbility.getInstance());
}
-
+
}
diff --git a/Mage.Sets/src/mage/sets/magic2015/SliverHive.java b/Mage.Sets/src/mage/sets/magic2015/SliverHive.java
index f5c40cb43e3..cfba0c94491 100644
--- a/Mage.Sets/src/mage/sets/magic2015/SliverHive.java
+++ b/Mage.Sets/src/mage/sets/magic2015/SliverHive.java
@@ -51,7 +51,7 @@ import mage.filter.FilterSpell;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.SliverToken;
/**
*
@@ -134,15 +134,3 @@ class SliverHiveManaCondition extends CreatureCastManaCondition {
return false;
}
}
-
-class SliverToken extends Token {
-
- SliverToken() {
- super("Sliver", "1/1 colorless Sliver creature token");
- setOriginalExpansionSetCode("M15");
- cardType.add(CardType.CREATURE);
- subtype.add("Sliver");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/magicorigins/EvolutionaryLeap.java b/Mage.Sets/src/mage/sets/magicorigins/EvolutionaryLeap.java
index b5cd46c4577..29b4b9dc852 100644
--- a/Mage.Sets/src/mage/sets/magicorigins/EvolutionaryLeap.java
+++ b/Mage.Sets/src/mage/sets/magicorigins/EvolutionaryLeap.java
@@ -42,6 +42,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Library;
@@ -60,7 +61,7 @@ public class EvolutionaryLeap extends CardImpl {
// {G}, Sacrifice a creature: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EvolutionaryLeapEffect(), new ManaCostsImpl("{G}"));
- ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent()));
+ ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/magicorigins/PriestOfTheBloodRite.java b/Mage.Sets/src/mage/sets/magicorigins/PriestOfTheBloodRite.java
index 6eed42819e2..ad780413154 100644
--- a/Mage.Sets/src/mage/sets/magicorigins/PriestOfTheBloodRite.java
+++ b/Mage.Sets/src/mage/sets/magicorigins/PriestOfTheBloodRite.java
@@ -38,7 +38,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.DemonToken;
/**
*
@@ -70,19 +70,3 @@ public class PriestOfTheBloodRite extends CardImpl {
return new PriestOfTheBloodRite(this);
}
}
-
-class DemonToken extends Token {
-
- DemonToken() {
- super("Demon", "5/5 black Demon creature token with flying");
- cardType.add(CardType.CREATURE);
- subtype.add("Demon");
- setOriginalExpansionSetCode("ORI");
-
- color.setBlack(true);
- power = new MageInt(5);
- toughness = new MageInt(5);
-
- addAbility(FlyingAbility.getInstance());
- }
-}
diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/Thwart.java b/Mage.Sets/src/mage/sets/mercadianmasques/Thwart.java
index a8c224e8dfe..0ecda013df4 100644
--- a/Mage.Sets/src/mage/sets/mercadianmasques/Thwart.java
+++ b/Mage.Sets/src/mage/sets/mercadianmasques/Thwart.java
@@ -29,7 +29,7 @@ package mage.sets.mercadianmasques;
import java.util.UUID;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@@ -54,7 +54,7 @@ public class Thwart extends CardImpl {
// You may return three Islands you control to their owner's hand rather than pay Thwart's mana cost.
AlternativeCostSourceAbility ability;
- ability = new AlternativeCostSourceAbility(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(3, 3, filter, true)));
+ ability = new AlternativeCostSourceAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(3, 3, filter, true)));
this.addAbility(ability);
// Counter target spell.
diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/TidalBore.java b/Mage.Sets/src/mage/sets/mercadianmasques/TidalBore.java
index abd9bf620da..792c862964f 100644
--- a/Mage.Sets/src/mage/sets/mercadianmasques/TidalBore.java
+++ b/Mage.Sets/src/mage/sets/mercadianmasques/TidalBore.java
@@ -29,7 +29,7 @@ package mage.sets.mercadianmasques;
import java.util.UUID;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.MayTapOrUntapTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
@@ -58,7 +58,7 @@ public class TidalBore extends CardImpl {
this.expansionSetCode = "MMQ";
// You may return an Island you control to its owner's hand rather than pay Tidal Bore's mana cost.
- this.addAbility(new AlternativeCostSourceAbility(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter))));
+ this.addAbility(new AlternativeCostSourceAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter))));
// You may tap or untap target creature.
this.getSpellAbility().addEffect(new MayTapOrUntapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
diff --git a/Mage.Sets/src/mage/sets/mirrodin/InciteWar.java b/Mage.Sets/src/mage/sets/mirrodin/InciteWar.java
index b7635f2125e..d646a4430e0 100644
--- a/Mage.Sets/src/mage/sets/mirrodin/InciteWar.java
+++ b/Mage.Sets/src/mage/sets/mirrodin/InciteWar.java
@@ -48,18 +48,19 @@ import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
* @author fireshoes
*/
public class InciteWar extends CardImpl {
-
+
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
- }
+ }
public InciteWar(UUID ownerId) {
super(ownerId, 96, "Incite War", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{R}");
@@ -68,12 +69,13 @@ public class InciteWar extends CardImpl {
// Choose one - Creatures target player controls attack this turn if able;
this.getSpellAbility().addEffect(new InciteWarMustAttackEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
-
+ this.getSpellAbility().addWatcher(new AttackedThisTurnWatcher());
+
// or creatures you control gain first strike until end of turn.
Mode mode = new Mode();
mode.getEffects().add(new GainAbilityAllEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filter));
this.getSpellAbility().getModes().addMode(mode);
-
+
// Entwine {2}
this.addAbility(new EntwineAbility("{2}"));
}
@@ -91,7 +93,7 @@ public class InciteWar extends CardImpl {
class InciteWarMustAttackEffect extends OneShotEffect {
public InciteWarMustAttackEffect() {
- super(Outcome.Detriment);
+ super(Outcome.Detriment);
staticText = "Creatures target player control attack this turn if able";
}
@@ -116,4 +118,4 @@ class InciteWarMustAttackEffect extends OneShotEffect {
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java
index 74adb82e243..c26e3cff44c 100644
--- a/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java
+++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java
@@ -25,12 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.sets.mirrodinbesieged;
import java.util.UUID;
-
-import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
@@ -39,6 +36,11 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.InfectAbility;
import mage.cards.CardImpl;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -48,21 +50,26 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class CorruptedConscience extends CardImpl {
- public CorruptedConscience (UUID ownerId) {
+ public CorruptedConscience(UUID ownerId) {
super(ownerId, 22, "Corrupted Conscience", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
this.expansionSetCode = "MBS";
this.subtype.add("Aura");
+ // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
+
+ // You control enchanted creature.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect()));
+
+ // Enchanted creature has infect. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(InfectAbility.getInstance(), AttachmentType.AURA)));
}
- public CorruptedConscience (final CorruptedConscience card) {
+ public CorruptedConscience(final CorruptedConscience card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/WhiteSunsZenith.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/WhiteSunsZenith.java
index ca6630a0c4d..4ff0f362062 100644
--- a/Mage.Sets/src/mage/sets/mirrodinbesieged/WhiteSunsZenith.java
+++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/WhiteSunsZenith.java
@@ -29,7 +29,6 @@
package mage.sets.mirrodinbesieged;
import java.util.UUID;
-import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.CreateTokenEffect;
@@ -37,7 +36,7 @@ import mage.abilities.effects.common.ShuffleSpellEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.CatToken;
/**
*
@@ -62,16 +61,3 @@ public class WhiteSunsZenith extends CardImpl {
return new WhiteSunsZenith(this);
}
}
-
-class CatToken extends Token {
- public CatToken() {
- super("Cat", "2/2 white Cat creature token");
- setOriginalExpansionSetCode("SOM");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Cat");
- power = new MageInt(2);
- toughness = new MageInt(2);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/modernmasters/MarshFlitter.java b/Mage.Sets/src/mage/sets/modernmasters/MarshFlitter.java
index 56a97459bb9..65428a838bb 100644
--- a/Mage.Sets/src/mage/sets/modernmasters/MarshFlitter.java
+++ b/Mage.Sets/src/mage/sets/modernmasters/MarshFlitter.java
@@ -44,7 +44,7 @@ import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.GoblinRogueToken;
import mage.target.common.TargetControlledPermanent;
/**
@@ -70,7 +70,7 @@ public class MarshFlitter extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Marsh Flitter enters the battlefield, put two 1/1 black Goblin Rogue creature tokens onto the battlefield.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BlackGoblinRogueToken(), 2), false));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinRogueToken(), 2), false));
// Sacrifice a Goblin: Marsh Flitter has base power and toughness 3/3 until end of turn.
Effect effect = new SetPowerToughnessSourceEffect(3, 3, Duration.EndOfTurn);
effect.setText("{this} has base power and toughness 3/3 until end of turn");
@@ -88,15 +88,3 @@ public class MarshFlitter extends CardImpl {
return new MarshFlitter(this);
}
}
-
-class BlackGoblinRogueToken extends Token {
- BlackGoblinRogueToken() {
- super("Goblin Rogue", "1/1 black Goblin Rogue creature tokens");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Goblin");
- subtype.add("Rogue");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java b/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java
index 8a294fd70a3..b3f6d2144fa 100644
--- a/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java
+++ b/Mage.Sets/src/mage/sets/modernmasters/WarrenWeirding.java
@@ -47,6 +47,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.game.permanent.token.GoblinRogueToken;
import mage.game.permanent.token.Token;
import mage.players.Player;
import mage.target.TargetPlayer;
@@ -83,9 +84,11 @@ public class WarrenWeirding extends CardImpl {
class WarrenWeirdingEffect extends OneShotEffect {
private static final FilterCreaturePermanent filterGoblin = new FilterCreaturePermanent();
+
static {
filterGoblin.add(new SubtypePredicate("Goblin"));
}
+
WarrenWeirdingEffect ( ) {
super(Outcome.Sacrifice);
staticText = "Target player sacrifices a creature. If a Goblin is sacrificed this way, that player puts two 1/1 black Goblin Rogue creature tokens onto the battlefield, and those tokens gain haste until end of turn";
@@ -113,7 +116,7 @@ class WarrenWeirdingEffect extends OneShotEffect {
permanent.sacrifice(source.getSourceId(), game);
if (filterGoblin.match(permanent, game)) {
for (int i = 0; i < 2; i++) {
- Token token = new WarrenWeirdingBlackGoblinRogueToken();
+ Token token = new GoblinRogueToken();
Effect effect = new CreateTokenTargetEffect(token);
effect.setTargetPointer(new FixedTarget(player.getId()));
if (effect.apply(game, source)) {
@@ -138,15 +141,3 @@ class WarrenWeirdingEffect extends OneShotEffect {
}
}
-
-class WarrenWeirdingBlackGoblinRogueToken extends Token {
- WarrenWeirdingBlackGoblinRogueToken() {
- super("Goblin Rogue", "1/1 black Goblin Rogue creature tokens, and those tokens gain haste until end of turn");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Goblin");
- subtype.add("Rogue");
- power.setValue(1);
- toughness.setValue(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/morningtide/Bitterblossom.java b/Mage.Sets/src/mage/sets/morningtide/Bitterblossom.java
index 783584d8e87..2a19532c5d4 100644
--- a/Mage.Sets/src/mage/sets/morningtide/Bitterblossom.java
+++ b/Mage.Sets/src/mage/sets/morningtide/Bitterblossom.java
@@ -1,82 +1,66 @@
-/*
- * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of BetaSteward_at_googlemail.com.
- */
-package mage.sets.morningtide;
-
-import java.util.UUID;
-import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
-import mage.abilities.effects.common.CreateTokenEffect;
-import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
-import mage.abilities.keyword.FlyingAbility;
-import mage.cards.CardImpl;
-import mage.constants.CardType;
-import mage.constants.Rarity;
-import mage.constants.TargetController;
-import mage.game.permanent.token.Token;
-
-/**
- *
- * @author Loki
- */
-public class Bitterblossom extends CardImpl {
-
- public Bitterblossom(UUID ownerId) {
- super(ownerId, 58, "Bitterblossom", Rarity.RARE, new CardType[]{CardType.TRIBAL, CardType.ENCHANTMENT}, "{1}{B}");
- this.expansionSetCode = "MOR";
- this.subtype.add("Faerie");
-
- // At the beginning of your upkeep, you lose 1 life and put a 1/1 black Faerie Rogue creature token with flying onto the battlefield.
- Ability ability = new BeginningOfUpkeepTriggeredAbility(new LoseLifeSourceControllerEffect(1), TargetController.YOU, false);
- ability.addEffect(new CreateTokenEffect(new FaerieToken(), 1));
- this.addAbility(ability);
- }
-
- public Bitterblossom(final Bitterblossom card) {
- super(card);
- }
-
- @Override
- public Bitterblossom copy() {
- return new Bitterblossom(this);
- }
-}
-
-class FaerieToken extends Token {
-
- FaerieToken() {
- super("Faerie Rogue", "1/1 black Faerie Rogue creature token with flying");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Faerie");
- subtype.add("Rogue");
- power = new MageInt(1);
- toughness = new MageInt(1);
- this.addAbility(FlyingAbility.getInstance());
- }
-}
+/*
+ * 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.sets.morningtide;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.TargetController;
+import mage.game.permanent.token.FaerieRogueToken;
+
+/**
+ *
+ * @author Loki
+ */
+public class Bitterblossom extends CardImpl {
+
+ public Bitterblossom(UUID ownerId) {
+ super(ownerId, 58, "Bitterblossom", Rarity.RARE, new CardType[]{CardType.TRIBAL, CardType.ENCHANTMENT}, "{1}{B}");
+ this.expansionSetCode = "MOR";
+ this.subtype.add("Faerie");
+
+ // At the beginning of your upkeep, you lose 1 life and put a 1/1 black Faerie Rogue creature token with flying onto the battlefield.
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(new LoseLifeSourceControllerEffect(1), TargetController.YOU, false);
+ ability.addEffect(new CreateTokenEffect(new FaerieRogueToken(), 1));
+ this.addAbility(ability);
+ }
+
+ public Bitterblossom(final Bitterblossom card) {
+ super(card);
+ }
+
+ @Override
+ public Bitterblossom copy() {
+ return new Bitterblossom(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/morningtide/NotoriousThrong.java b/Mage.Sets/src/mage/sets/morningtide/NotoriousThrong.java
new file mode 100644
index 00000000000..d943672f4a4
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/morningtide/NotoriousThrong.java
@@ -0,0 +1,112 @@
+/*
+ * 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.sets.morningtide;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.condition.common.ProwlCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
+import mage.abilities.keyword.ProwlAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.game.Game;
+import mage.game.permanent.token.FaerieRogueToken;
+import mage.players.Player;
+import mage.watchers.common.AmountOfDamageAPlayerReceivedThisTurnWatcher;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class NotoriousThrong extends CardImpl {
+
+ public NotoriousThrong(UUID ownerId) {
+ super(ownerId, 45, "Notorious Throng", Rarity.RARE, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{3}{U}");
+ this.expansionSetCode = "MOR";
+ this.subtype.add("Rogue");
+
+ // Prowl {5}{U}
+ this.addAbility(new ProwlAbility(this, "{5}{U}"));
+ // Put X 1/1 black Faerie Rogue creature tokens with flying onto the battlefield, where X is the damage dealt to your opponents this turn.
+ this.getSpellAbility().addEffect(new NotoriousThrongEffect());
+ this.getSpellAbility().addWatcher(new AmountOfDamageAPlayerReceivedThisTurnWatcher());
+ // If Notorious Throng's prowl cost was paid, take an extra turn after this one.
+ Effect effect = new ConditionalOneShotEffect(new AddExtraTurnControllerEffect(), ProwlCondition.getInstance());
+ effect.setText("If {this}'s prowl cost was paid, take an extra turn after this one.");
+ this.getSpellAbility().addEffect(effect);
+ }
+
+ public NotoriousThrong(final NotoriousThrong card) {
+ super(card);
+ }
+
+ @Override
+ public NotoriousThrong copy() {
+ return new NotoriousThrong(this);
+ }
+}
+
+class NotoriousThrongEffect extends OneShotEffect {
+
+ public NotoriousThrongEffect() {
+ super(Outcome.PutCreatureInPlay);
+ staticText = "Put X 1/1 black Faerie Rogue creature tokens with flying onto the battlefield, where X is the damage dealt to your opponents this turn";
+ }
+
+ public NotoriousThrongEffect(NotoriousThrongEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public NotoriousThrongEffect copy() {
+ return new NotoriousThrongEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ AmountOfDamageAPlayerReceivedThisTurnWatcher watcher = (AmountOfDamageAPlayerReceivedThisTurnWatcher) game.getState().getWatchers().get("AmountOfDamageReceivedThisTurn");
+ if(controller != null && watcher != null) {
+ int numTokens = 0;
+ for(UUID opponentId: game.getOpponents(controller.getId())) {
+ numTokens += watcher.getAmountOfDamageReceivedThisTurn(opponentId);
+ }
+ if(numTokens > 0) {
+ new CreateTokenEffect(new FaerieRogueToken(), numTokens).apply(game, source);
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/morningtide/VioletPall.java b/Mage.Sets/src/mage/sets/morningtide/VioletPall.java
index 7b760e28e44..b76090f5c2e 100644
--- a/Mage.Sets/src/mage/sets/morningtide/VioletPall.java
+++ b/Mage.Sets/src/mage/sets/morningtide/VioletPall.java
@@ -28,18 +28,16 @@
package mage.sets.morningtide;
import java.util.UUID;
-import mage.MageInt;
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.ObjectColor;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
-import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.FaerieRogueToken;
import mage.target.common.TargetCreaturePermanent;
/**
@@ -61,7 +59,7 @@ public class VioletPall extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
- this.getSpellAbility().addEffect(new CreateTokenEffect(new VioletPallFaerieToken(), 1));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new FaerieRogueToken(), 1));
}
public VioletPall(final VioletPall card) {
@@ -73,17 +71,3 @@ public class VioletPall extends CardImpl {
return new VioletPall(this);
}
}
-
-class VioletPallFaerieToken extends Token {
-
- VioletPallFaerieToken() {
- super("Faerie Rogue", "1/1 black Faerie Rogue creature token with flying");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Faerie");
- subtype.add("Rogue");
- power = new MageInt(1);
- toughness = new MageInt(1);
- this.addAbility(FlyingAbility.getInstance());
- }
-}
diff --git a/Mage.Sets/src/mage/sets/morningtide/WeirdingShaman.java b/Mage.Sets/src/mage/sets/morningtide/WeirdingShaman.java
index 8bc8b3e8eb4..063142396ed 100644
--- a/Mage.Sets/src/mage/sets/morningtide/WeirdingShaman.java
+++ b/Mage.Sets/src/mage/sets/morningtide/WeirdingShaman.java
@@ -41,7 +41,7 @@ import mage.cards.CardImpl;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.GoblinRogueToken;
import mage.target.common.TargetControlledPermanent;
/**
@@ -64,7 +64,7 @@ public class WeirdingShaman extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(1);
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new goblinRogueToken(), 2), new ManaCostsImpl("{3}{B}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new GoblinRogueToken(), 2), new ManaCostsImpl("{3}{B}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter)));
this.addAbility(ability);
}
@@ -78,15 +78,3 @@ public class WeirdingShaman extends CardImpl {
return new WeirdingShaman(this);
}
}
-
-class goblinRogueToken extends Token {
- goblinRogueToken() {
- super("Goblin", "1/1 black Goblin Rogue creature tokens");
- cardType.add(CardType.CREATURE);
- color.setBlack(true);
- subtype.add("Goblin");
- subtype.add("Rogue");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/nemesis/Daze.java b/Mage.Sets/src/mage/sets/nemesis/Daze.java
index 5cdf8ec4c8c..ecb769b3740 100644
--- a/Mage.Sets/src/mage/sets/nemesis/Daze.java
+++ b/Mage.Sets/src/mage/sets/nemesis/Daze.java
@@ -29,7 +29,7 @@ package mage.sets.nemesis;
import java.util.UUID;
import mage.abilities.costs.AlternativeCostSourceAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CounterUnlessPaysEffect;
import mage.cards.CardImpl;
@@ -60,7 +60,7 @@ public class Daze extends CardImpl {
// You may return an Island you control to its owner's hand rather than pay Daze's mana cost.
- this.addAbility(new AlternativeCostSourceAbility(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter))));
+ this.addAbility(new AlternativeCostSourceAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter))));
// Counter target spell unless its controller pays {1}.
this.getSpellAbility().addTarget(new TargetSpell());
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java b/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java
index d158331c83f..b9bd7826273 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java
@@ -25,12 +25,9 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.sets.newphyrexia;
import java.util.UUID;
-
-import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -39,6 +36,11 @@ import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.ControlEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.TargetController;
+import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -51,21 +53,26 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class Enslave extends CardImpl {
- public Enslave (UUID ownerId) {
+ public Enslave(UUID ownerId) {
super(ownerId, 58, "Enslave", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}");
this.expansionSetCode = "NPH";
this.subtype.add("Aura");
+ // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
+
+ // You control enchanted creature.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect()));
+
+ // At the beginning of your upkeep, enchanted creature deals 1 damage to its owner.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new EnslaveEffect(), TargetController.YOU, false, false));
}
- public Enslave (final Enslave card) {
+ public Enslave(final Enslave card) {
super(card);
}
@@ -77,6 +84,7 @@ public class Enslave extends CardImpl {
}
class EnslaveEffect extends OneShotEffect {
+
EnslaveEffect() {
super(Outcome.Damage);
staticText = "enchanted creature deals 1 damage to its owner";
@@ -88,13 +96,13 @@ class EnslaveEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (sourcePermanent != null) {
- Permanent attached = game.getPermanent(sourcePermanent.getAttachedTo());
+ Permanent attached = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo());
if (attached != null) {
Player owner = game.getPlayer(attached.getOwnerId());
if (owner != null) {
- owner.damage(1, source.getSourceId(), game, false, true);
+ owner.damage(1, attached.getId(), game, false, true);
return true;
}
}
@@ -108,4 +116,4 @@ class EnslaveEffect extends OneShotEffect {
return new EnslaveEffect(this);
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianObliterator.java b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianObliterator.java
index 5811c99d20a..16b0136dbda 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianObliterator.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianObliterator.java
@@ -58,7 +58,10 @@ public class PhyrexianObliterator extends CardImpl {
this.power = new MageInt(5);
this.toughness = new MageInt(5);
+ // Trample
this.addAbility(TrampleAbility.getInstance());
+
+ // Whenever a source deals damage to Phyrexian Obliterator, that source's controller sacrifices that many permanents.
this.addAbility(new PhyrexianObliteratorTriggeredAbility());
}
@@ -73,6 +76,7 @@ public class PhyrexianObliterator extends CardImpl {
}
class PhyrexianObliteratorTriggeredAbility extends TriggeredAbilityImpl {
+
PhyrexianObliteratorTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeEffect(new FilterPermanent(), 0, ""));
}
diff --git a/Mage.Sets/src/mage/sets/newphyrexia/ReaperOfSheoldred.java b/Mage.Sets/src/mage/sets/newphyrexia/ReaperOfSheoldred.java
index c8da60dba23..5e9a8469cf7 100644
--- a/Mage.Sets/src/mage/sets/newphyrexia/ReaperOfSheoldred.java
+++ b/Mage.Sets/src/mage/sets/newphyrexia/ReaperOfSheoldred.java
@@ -41,6 +41,7 @@ import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/**
@@ -57,7 +58,10 @@ public class ReaperOfSheoldred extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(5);
+ // Infect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)
this.addAbility(InfectAbility.getInstance());
+
+ // Whenever a source deals damage to Reaper of Sheoldred, that source's controller gets a poison counter.
this.addAbility(new ReaperOfSheoldredTriggeredAbility());
}
@@ -72,6 +76,7 @@ public class ReaperOfSheoldred extends CardImpl {
}
class ReaperOfSheoldredTriggeredAbility extends TriggeredAbilityImpl {
+
ReaperOfSheoldredTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.POISON.createInstance()));
}
@@ -93,10 +98,16 @@ class ReaperOfSheoldredTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(this.getSourceId())) {
- for (Effect effect : this.getEffects()) {
- effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
+ UUID controller = game.getControllerId(event.getSourceId());
+ if (controller != null) {
+ Player player = game.getPlayer(controller);
+ if (player != null) {
+ for (Effect effect : this.getEffects()) {
+ effect.setTargetPointer(new FixedTarget(player.getId()));
+ }
+ return true;
+ }
}
- return true;
}
return false;
}
diff --git a/Mage.Sets/src/mage/sets/planechase2012/KrondTheDawnClad.java b/Mage.Sets/src/mage/sets/planechase2012/KrondTheDawnClad.java
index a42a96ec85f..75c25f891d0 100644
--- a/Mage.Sets/src/mage/sets/planechase2012/KrondTheDawnClad.java
+++ b/Mage.Sets/src/mage/sets/planechase2012/KrondTheDawnClad.java
@@ -28,8 +28,6 @@
package mage.sets.planechase2012;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
@@ -37,7 +35,10 @@ import mage.abilities.condition.common.EnchantedCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
import mage.target.TargetPermanent;
/**
@@ -52,18 +53,18 @@ public class KrondTheDawnClad extends CardImpl {
this.supertype.add("Legendary");
this.subtype.add("Archon");
-
this.power = new MageInt(6);
this.toughness = new MageInt(6);
- // Flying
+ // Flying, vigilance
this.addAbility(FlyingAbility.getInstance());
+ this.addAbility(VigilanceAbility.getInstance());
// Whenever Krond the Dawn-Clad attacks, if it's enchanted, exile target permanent.
Ability ability = new ConditionalTriggeredAbility(
new AttacksTriggeredAbility(new ExileTargetEffect(), false),
new EnchantedCondition(),
- "Whenever Krond the Dawn-Clad attacks, if it's enchanted, exile target permanent.");
+ "Whenever {this} attacks, if it's enchanted, exile target permanent.");
ability.addTarget(new TargetPermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java
index e7993aa1681..0125728af80 100644
--- a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java
+++ b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java
@@ -33,7 +33,7 @@ import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.KickedCondition;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.KickerAbility;
import mage.cards.CardImpl;
@@ -56,7 +56,7 @@ public class ArcticMerfolk extends CardImpl {
this.toughness = new MageInt(1);
// Kicker—Return a creature you control to its owner's hand. (You may return a creature you control to its owner's hand in addition to any other costs as you cast this spell.)
- this.addAbility(new KickerAbility(new ReturnToHandTargetPermanentCost(new TargetControlledCreaturePermanent(1,1,new FilterControlledCreaturePermanent("a creature"),true))));
+ this.addAbility(new KickerAbility(new ReturnToHandChosenControlledPermanentCost(new TargetControlledCreaturePermanent(1,1,new FilterControlledCreaturePermanent("a creature"),true))));
// If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.
this.addAbility(new EntersBattlefieldAbility(
diff --git a/Mage.Sets/src/mage/sets/planeshift/CrosissCatacombs.java b/Mage.Sets/src/mage/sets/planeshift/CrosissCatacombs.java
index 40cafe55313..7efc25e7f80 100644
--- a/Mage.Sets/src/mage/sets/planeshift/CrosissCatacombs.java
+++ b/Mage.Sets/src/mage/sets/planeshift/CrosissCatacombs.java
@@ -29,7 +29,7 @@ package mage.sets.planeshift;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
@@ -59,7 +59,7 @@ public class CrosissCatacombs extends CardImpl {
this.subtype.add("Lair");
// When Crosis's Catacombs enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {U}, {B}, or {R} to your mana pool.
this.addAbility(new BlueManaAbility());
this.addAbility(new BlackManaAbility());
diff --git a/Mage.Sets/src/mage/sets/planeshift/DarigaazsCaldera.java b/Mage.Sets/src/mage/sets/planeshift/DarigaazsCaldera.java
index cf9b3567fda..09e9902d6cc 100644
--- a/Mage.Sets/src/mage/sets/planeshift/DarigaazsCaldera.java
+++ b/Mage.Sets/src/mage/sets/planeshift/DarigaazsCaldera.java
@@ -29,7 +29,7 @@ package mage.sets.planeshift;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.GreenManaAbility;
@@ -59,7 +59,7 @@ public class DarigaazsCaldera extends CardImpl {
this.subtype.add("Lair");
// When Darigaaz's Caldera enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {B}, {R}, or {G} to your mana pool.
this.addAbility(new BlackManaAbility());
this.addAbility(new RedManaAbility());
diff --git a/Mage.Sets/src/mage/sets/planeshift/DromarsCavern.java b/Mage.Sets/src/mage/sets/planeshift/DromarsCavern.java
index 0527355c9bc..87e138351ae 100644
--- a/Mage.Sets/src/mage/sets/planeshift/DromarsCavern.java
+++ b/Mage.Sets/src/mage/sets/planeshift/DromarsCavern.java
@@ -29,7 +29,7 @@ package mage.sets.planeshift;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
@@ -58,7 +58,7 @@ public class DromarsCavern extends CardImpl {
this.subtype.add("Lair");
// When Dromar's Cavern enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {W}, {U}, or {B} to your mana pool.
this.addAbility(new WhiteManaAbility());
this.addAbility(new BlueManaAbility());
diff --git a/Mage.Sets/src/mage/sets/planeshift/RithsGrove.java b/Mage.Sets/src/mage/sets/planeshift/RithsGrove.java
index d0fe9fde6f0..aa36ec7965a 100644
--- a/Mage.Sets/src/mage/sets/planeshift/RithsGrove.java
+++ b/Mage.Sets/src/mage/sets/planeshift/RithsGrove.java
@@ -29,7 +29,7 @@ package mage.sets.planeshift;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
@@ -59,7 +59,7 @@ public class RithsGrove extends CardImpl {
this.subtype.add("Lair");
// When Rith's Grove enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {R}, {G}, or {W} to your mana pool.
this.addAbility(new RedManaAbility());
this.addAbility(new GreenManaAbility());
diff --git a/Mage.Sets/src/mage/sets/planeshift/TrevasRuins.java b/Mage.Sets/src/mage/sets/planeshift/TrevasRuins.java
index 64b9eec6c94..d72cc657f27 100644
--- a/Mage.Sets/src/mage/sets/planeshift/TrevasRuins.java
+++ b/Mage.Sets/src/mage/sets/planeshift/TrevasRuins.java
@@ -29,7 +29,7 @@ package mage.sets.planeshift;
import java.util.UUID;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
@@ -59,7 +59,7 @@ public class TrevasRuins extends CardImpl {
this.subtype.add("Lair");
// When Treva's Ruins enters the battlefield, sacrifice it unless you return a non-Lair land you control to its owner's hand.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)))));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)))));
// {tap}: Add {G}, {W}, or {U} to your mana pool.
this.addAbility(new GreenManaAbility());
this.addAbility(new WhiteManaAbility());
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/Deprive.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/Deprive.java
index afa39d5afc2..773a63bab34 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/Deprive.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/Deprive.java
@@ -31,7 +31,7 @@ package mage.sets.riseoftheeldrazi;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledLandPermanent;
@@ -52,7 +52,7 @@ public class Deprive extends CardImpl {
this.expansionSetCode = "ROE";
// As an additional cost to cast Deprive, return a land you control to its owner's hand.
- this.getSpellAbility().addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ this.getSpellAbility().addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
// Counter target spell.
this.getSpellAbility().addTarget(new TargetSpell());
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/EmrakulTheAeonsTorn.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/EmrakulTheAeonsTorn.java
index 11b0df213d7..81f7d3e5c6d 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/EmrakulTheAeonsTorn.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/EmrakulTheAeonsTorn.java
@@ -29,30 +29,20 @@ package mage.sets.riseoftheeldrazi;
import java.util.UUID;
import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.CantBeCounteredAbility;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CastSourceTriggeredAbility;
+import mage.abilities.effects.common.ShuffleIntoLibraryGraveOfSourceOwnerEffect;
+import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
import mage.abilities.keyword.AnnihilatorAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProtectionAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorlessPredicate;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
-import mage.game.stack.Spell;
-import mage.game.turn.TurnMod;
-import mage.players.Player;
-
/**
* @author Loki
@@ -72,17 +62,18 @@ public class EmrakulTheAeonsTorn extends CardImpl {
this.subtype.add("Eldrazi");
this.power = new MageInt(15);
this.toughness = new MageInt(15);
-
+
// Emrakul, the Aeons Torn can't be countered.
this.addAbility(new CantBeCounteredAbility());
- // When you cast Emrakul, take an extra turn after this one.
- this.addAbility(new EmrakulTheAeonsTornOnCastAbility());
+ // When you cast Emrakul, take an extra turn after this one.
+ this.addAbility(new CastSourceTriggeredAbility(new AddExtraTurnControllerEffect()));
+
// Flying, protection from colored spells, annihilator 6
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new ProtectionAbility(filter));
this.addAbility(new AnnihilatorAbility(6));
// When Emrakul is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.
- this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new EmrakulTheAeonsTornEffect(), false));
+ this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new ShuffleIntoLibraryGraveOfSourceOwnerEffect(), false));
}
public EmrakulTheAeonsTorn(final EmrakulTheAeonsTorn card) {
@@ -94,89 +85,3 @@ public class EmrakulTheAeonsTorn extends CardImpl {
return new EmrakulTheAeonsTorn(this);
}
}
-class EmrakulTheAeonsTornOnCastAbility extends TriggeredAbilityImpl {
-
- private static final String abilityText = "When you cast {this}, take an extra turn after this one";
-
- EmrakulTheAeonsTornOnCastAbility() {
- super(Zone.STACK, new EmrakulExtraTurnEffect());
- }
-
- EmrakulTheAeonsTornOnCastAbility(EmrakulTheAeonsTornOnCastAbility ability) {
- super(ability);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == EventType.SPELL_CAST;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- Spell spell = (Spell) game.getObject(event.getTargetId());
- return this.getSourceId().equals(spell.getSourceId());
- }
-
- @Override
- public EmrakulTheAeonsTornOnCastAbility copy() {
- return new EmrakulTheAeonsTornOnCastAbility(this);
- }
-
- @Override
- public String getRule() {
- return abilityText;
- }
-}
-
-class EmrakulTheAeonsTornEffect extends OneShotEffect {
-
- EmrakulTheAeonsTornEffect() {
- super(Outcome.Benefit);
- staticText = "its owner shuffles his or her graveyard into his or her library";
- }
-
- EmrakulTheAeonsTornEffect(final EmrakulTheAeonsTornEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
- if (player != null) {
- for (Card card: player.getGraveyard().getCards(game)) {
- card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
- }
- player.shuffleLibrary(game);
- return true;
- }
- return false;
- }
-
- @Override
- public EmrakulTheAeonsTornEffect copy() {
- return new EmrakulTheAeonsTornEffect(this);
- }
-}
-
-class EmrakulExtraTurnEffect extends OneShotEffect {
-
- EmrakulExtraTurnEffect() {
- super(Outcome.ExtraTurn);
- staticText = "take an extra turn after this one";
- }
-
- EmrakulExtraTurnEffect(final EmrakulExtraTurnEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false));
- return true;
- }
-
- @Override
- public EmrakulExtraTurnEffect copy() {
- return new EmrakulExtraTurnEffect(this);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/KozilekButcherOfTruth.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/KozilekButcherOfTruth.java
index 81f0622ac4c..00a59b921e3 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/KozilekButcherOfTruth.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/KozilekButcherOfTruth.java
@@ -25,28 +25,18 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.sets.riseoftheeldrazi;
import java.util.UUID;
-
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.MageInt;
-import mage.abilities.Ability;
-import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.ShuffleIntoLibraryGraveOfSourceOwnerEffect;
import mage.abilities.keyword.AnnihilatorAbility;
-import mage.cards.Card;
import mage.cards.CardImpl;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.stack.Spell;
-import mage.players.Player;
+import mage.constants.CardType;
+import mage.constants.Rarity;
/**
*
@@ -54,25 +44,25 @@ import mage.players.Player;
*/
public class KozilekButcherOfTruth extends CardImpl {
- public KozilekButcherOfTruth (UUID ownerId) {
+ public KozilekButcherOfTruth(UUID ownerId) {
super(ownerId, 6, "Kozilek, Butcher of Truth", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{10}");
this.expansionSetCode = "ROE";
this.supertype.add("Legendary");
this.subtype.add("Eldrazi");
this.power = new MageInt(12);
this.toughness = new MageInt(12);
-
- // When you cast Kozilek, Butcher of Truth, draw four cards.
- this.addAbility(new KozilekButcherOfTruthOnCastAbility());
-
+
+ // When you cast Kozilek, Butcher of Truth, draw four cards.
+ this.addAbility(new CastSourceTriggeredAbility(new DrawCardSourceControllerEffect(4)));
+
// Annihilator 4 (Whenever this creature attacks, defending player sacrifices four permanents.)
this.addAbility(new AnnihilatorAbility(4));
-
+
// When Kozilek is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.
- this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new KozilekButcherOfTruthEffect(), false));
+ this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new ShuffleIntoLibraryGraveOfSourceOwnerEffect(), false));
}
- public KozilekButcherOfTruth (final KozilekButcherOfTruth card) {
+ public KozilekButcherOfTruth(final KozilekButcherOfTruth card) {
super(card);
}
@@ -82,67 +72,3 @@ public class KozilekButcherOfTruth extends CardImpl {
}
}
-
-class KozilekButcherOfTruthOnCastAbility extends TriggeredAbilityImpl {
-
- private static final String abilityText = "When you cast {this}, draw four cards";
-
- KozilekButcherOfTruthOnCastAbility() {
- super(Zone.STACK, new DrawCardSourceControllerEffect(4));
- }
-
- KozilekButcherOfTruthOnCastAbility(final KozilekButcherOfTruthOnCastAbility ability) {
- super(ability);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.SPELL_CAST;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- Spell spell = (Spell) game.getObject(event.getTargetId());
- return this.getSourceId().equals(spell.getSourceId());
- }
-
- @Override
- public KozilekButcherOfTruthOnCastAbility copy() {
- return new KozilekButcherOfTruthOnCastAbility(this);
- }
-
- @Override
- public String getRule() {
- return abilityText;
- }
-}
-
-class KozilekButcherOfTruthEffect extends OneShotEffect {
- KozilekButcherOfTruthEffect() {
- super(Outcome.Benefit);
- staticText = "its owner shuffles his or her graveyard into his or her library";
- }
-
- KozilekButcherOfTruthEffect(final KozilekButcherOfTruthEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- for (Card card: controller.getGraveyard().getCards(game)) {
- controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true, true);
- }
- controller.shuffleLibrary(game);
- return true;
- }
- return false;
- }
-
- @Override
- public KozilekButcherOfTruthEffect copy() {
- return new KozilekButcherOfTruthEffect(this);
- }
-
-}
diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/UlamogTheInfiniteGyre.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/UlamogTheInfiniteGyre.java
index 0c43c1abf89..4a25d967f60 100644
--- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/UlamogTheInfiniteGyre.java
+++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/UlamogTheInfiniteGyre.java
@@ -30,22 +30,15 @@ package mage.sets.riseoftheeldrazi;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
-import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
+import mage.abilities.effects.common.ShuffleIntoLibraryGraveOfSourceOwnerEffect;
import mage.abilities.keyword.AnnihilatorAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.Rarity;
-import mage.constants.Zone;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
-import mage.game.stack.Spell;
-import mage.players.Player;
import mage.target.TargetPermanent;
/**
@@ -64,13 +57,16 @@ public class UlamogTheInfiniteGyre extends CardImpl {
this.toughness = new MageInt(10);
// When you cast Ulamog, the Infinite Gyre, destroy target permanent.
- this.addAbility(new UlamogTheInfiniteGyreDestroyOnCastAbility());
+ Ability ability = new CastSourceTriggeredAbility(new DestroyTargetEffect());
+ ability.addTarget(new TargetPermanent());
+ this.addAbility(ability);
+
// Annihilator 4 (Whenever this creature attacks, defending player sacrifices four permanents.)
this.addAbility(new AnnihilatorAbility(4));
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
// When Ulamog is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.
- this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new UlamogTheInfiniteGyreEnterGraveyardEffect(), false));
+ this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new ShuffleIntoLibraryGraveOfSourceOwnerEffect(), false));
}
public UlamogTheInfiniteGyre(final UlamogTheInfiniteGyre card) {
@@ -82,64 +78,3 @@ public class UlamogTheInfiniteGyre extends CardImpl {
return new UlamogTheInfiniteGyre(this);
}
}
-
-class UlamogTheInfiniteGyreDestroyOnCastAbility extends TriggeredAbilityImpl {
-
- UlamogTheInfiniteGyreDestroyOnCastAbility() {
- super(Zone.STACK, new DestroyTargetEffect());
- this.addTarget(new TargetPermanent());
- }
-
- UlamogTheInfiniteGyreDestroyOnCastAbility(UlamogTheInfiniteGyreDestroyOnCastAbility ability) {
- super(ability);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == EventType.SPELL_CAST;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- Spell spell = (Spell) game.getObject(event.getTargetId());
- return this.getSourceId().equals(spell.getSourceId());
- }
-
- @Override
- public UlamogTheInfiniteGyreDestroyOnCastAbility copy() {
- return new UlamogTheInfiniteGyreDestroyOnCastAbility(this);
- }
-
- @Override
- public String getRule() {
- return "When you cast {this}, " + super.getRule();
- }
-}
-
-class UlamogTheInfiniteGyreEnterGraveyardEffect extends OneShotEffect {
-
- UlamogTheInfiniteGyreEnterGraveyardEffect() {
- super(Outcome.Benefit);
- staticText = "its owner shuffles his or her graveyard into his or her library";
- }
-
- UlamogTheInfiniteGyreEnterGraveyardEffect(UlamogTheInfiniteGyreEnterGraveyardEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player owner = game.getPlayer(game.getOwnerId(source.getSourceId()));
- if (owner != null) {
- owner.moveCards(owner.getGraveyard(), null, Zone.LIBRARY, source, game);
- owner.shuffleLibrary(game);
- return true;
- }
- return false;
- }
-
- @Override
- public UlamogTheInfiniteGyreEnterGraveyardEffect copy() {
- return new UlamogTheInfiniteGyreEnterGraveyardEffect(this);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoonbowIllusionist.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoonbowIllusionist.java
index ef110170247..d41c6240d87 100644
--- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoonbowIllusionist.java
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MoonbowIllusionist.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -63,7 +63,7 @@ public class MoonbowIllusionist extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {2}, Return a land you control to its owner's hand: Target land becomes the basic land type of your choice until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesBasicLandTargetEffect(Duration.EndOfTurn), new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land"))));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land"))));
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroBreezecaller.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroBreezecaller.java
index c3f406d50ff..9578e96727f 100644
--- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroBreezecaller.java
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroBreezecaller.java
@@ -34,7 +34,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.keyword.FlyingAbility;
@@ -66,7 +66,7 @@ public class OboroBreezecaller extends CardImpl {
// {2}, Return a land you control to its owner's hand: Untap target land.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroEnvoy.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroEnvoy.java
index 4ed03c26ba5..1c1e54e47aa 100644
--- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroEnvoy.java
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/OboroEnvoy.java
@@ -31,7 +31,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
@@ -68,7 +68,7 @@ public class OboroEnvoy extends CardImpl {
Effect effect = new BoostTargetEffect(new SignInversionDynamicValue(new CardsInControllerHandCount()), new StaticValue(-0), Duration.EndOfTurn);
effect.setText("Target creature gets -X/-0 until end of turn, where X is the number of cards in your hand");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SoramaroFirstToDream.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SoramaroFirstToDream.java
index a4134bda06e..6ea5106fd85 100644
--- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SoramaroFirstToDream.java
+++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SoramaroFirstToDream.java
@@ -32,7 +32,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
@@ -70,7 +70,7 @@ public class SoramaroFirstToDream extends CardImpl {
// {4}, Return a land you control to its owner's hand: Draw a card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new DrawCardSourceControllerEffect(1), new GenericManaCost(4));
- ability.addCost(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
+ ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/KembaKhaRegent.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/KembaKhaRegent.java
index 91e4e6d7672..acbfb13f318 100644
--- a/Mage.Sets/src/mage/sets/scarsofmirrodin/KembaKhaRegent.java
+++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/KembaKhaRegent.java
@@ -38,7 +38,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.EquipmentAttachedCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.CatToken;
/**
*
@@ -69,16 +69,3 @@ public class KembaKhaRegent extends CardImpl {
return new KembaKhaRegent(this);
}
}
-
-class CatToken extends Token {
-
- public CatToken() {
- super("Cat", "a 2/2 white Cat creature token");
- cardType.add(CardType.CREATURE);
- color.setWhite(true);
-
- subtype.add("Cat");
- power = new MageInt(2);
- toughness = new MageInt(2);
- }
-}
diff --git a/Mage.Sets/src/mage/sets/scourge/WirewoodSymbiote.java b/Mage.Sets/src/mage/sets/scourge/WirewoodSymbiote.java
index 8bc500b1c35..3c676c3bdb7 100644
--- a/Mage.Sets/src/mage/sets/scourge/WirewoodSymbiote.java
+++ b/Mage.Sets/src/mage/sets/scourge/WirewoodSymbiote.java
@@ -34,7 +34,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledCreaturePermanent;
@@ -63,7 +63,7 @@ public class WirewoodSymbiote extends CardImpl {
this.toughness = new MageInt(1);
// Return an Elf you control to its owner's hand: Untap target creature. Activate this ability only once each turn.
- Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/seventhedition/Compost.java b/Mage.Sets/src/mage/sets/seventhedition/Compost.java
index 2b1b44ee3c8..feaf9284a64 100644
--- a/Mage.Sets/src/mage/sets/seventhedition/Compost.java
+++ b/Mage.Sets/src/mage/sets/seventhedition/Compost.java
@@ -54,10 +54,9 @@ public class Compost extends CardImpl {
super(ownerId, 235, "Compost", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.expansionSetCode = "7ED";
-
// Whenever a black card is put into an opponent's graveyard from anywhere, you may draw a card.
this.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
- new DrawCardSourceControllerEffect(1), true, TargetController.OPPONENT));
+ new DrawCardSourceControllerEffect(1), true, filter, TargetController.OPPONENT));
}
public Compost(final Compost card) {
diff --git a/Mage.Sets/src/mage/sets/shadowmoor/RosheenMeanderer.java b/Mage.Sets/src/mage/sets/shadowmoor/RosheenMeanderer.java
index 80bc63dda1a..6907063e21f 100644
--- a/Mage.Sets/src/mage/sets/shadowmoor/RosheenMeanderer.java
+++ b/Mage.Sets/src/mage/sets/shadowmoor/RosheenMeanderer.java
@@ -37,6 +37,7 @@ import mage.abilities.condition.Condition;
import mage.abilities.effects.common.BasicManaEffect;
import mage.abilities.mana.BasicManaAbility;
import mage.cards.CardImpl;
+import mage.constants.AbilityType;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.game.Game;
@@ -56,9 +57,9 @@ public class RosheenMeanderer extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // {tap}: Add {4} to your mana pool. Spend this mana only on costs that contain {X}.
+ // {T}: Add {4} to your mana pool. Spend this mana only on costs that contain {X}.
this.addAbility(new RosheenMeandererManaAbility());
-
+
}
public RosheenMeanderer(final RosheenMeanderer card) {
@@ -75,7 +76,7 @@ class RosheenMeandererManaAbility extends BasicManaAbility {
RosheenMeandererManaAbility() {
super(new BasicManaEffect(new RosheenMeandererConditionalMana()));
- this.netMana.add(new Mana(0,0,0,0,0,4,0));
+ this.netMana.add(new Mana(0, 0, 0, 0, 0, 4, 0));
}
RosheenMeandererManaAbility(RosheenMeandererManaAbility ability) {
@@ -98,10 +99,16 @@ class RosheenMeandererConditionalMana extends ConditionalMana {
}
class RosheenMeandererManaCondition implements Condition {
+
@Override
public boolean apply(Game game, Ability source) {
- MageObject object = game.getObject(source.getSourceId());
- return object != null
- && object.getManaCost().getText().contains("X");
+ if (AbilityType.SPELL.equals(source.getAbilityType())) {
+ MageObject object = game.getObject(source.getSourceId());
+ return object != null
+ && object.getManaCost().getText().contains("X");
+
+ } else {
+ return source.getManaCosts().getText().contains("X");
+ }
}
}
diff --git a/Mage.Sets/src/mage/sets/shardsofalara/BoneSplinters.java b/Mage.Sets/src/mage/sets/shardsofalara/BoneSplinters.java
index 002f0c851c2..77ac4cc3a49 100644
--- a/Mage.Sets/src/mage/sets/shardsofalara/BoneSplinters.java
+++ b/Mage.Sets/src/mage/sets/shardsofalara/BoneSplinters.java
@@ -34,6 +34,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
@@ -50,8 +51,8 @@ public class BoneSplinters extends CardImpl {
// As an additional cost to cast Bone Splinters, sacrifice a creature.
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))));
// Destroy target creature.
- this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new DestroyTargetEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (to destoy)")));
+ this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy target creature"));
}
public BoneSplinters(final BoneSplinters card) {
diff --git a/Mage.Sets/src/mage/sets/shardsofalara/GoblinAssault.java b/Mage.Sets/src/mage/sets/shardsofalara/GoblinAssault.java
index 43ca9f54978..7877a087dc0 100644
--- a/Mage.Sets/src/mage/sets/shardsofalara/GoblinAssault.java
+++ b/Mage.Sets/src/mage/sets/shardsofalara/GoblinAssault.java
@@ -28,22 +28,22 @@
package mage.sets.shardsofalara;
import java.util.UUID;
-
-import mage.constants.*;
import mage.MageInt;
-import mage.ObjectColor;
-import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.RequirementEffect;
import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Rarity;
+import mage.constants.TargetController;
+import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
import mage.game.permanent.token.Token;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
@@ -51,15 +51,21 @@ import mage.game.permanent.token.Token;
*/
public class GoblinAssault extends CardImpl {
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Goblin creatures");
+
+ static {
+ filter.add(new SubtypePredicate("Goblin"));
+ }
+
public GoblinAssault(UUID ownerId) {
super(ownerId, 101, "Goblin Assault", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
this.expansionSetCode = "ALA";
-
// At the beginning of your upkeep, put a 1/1 red Goblin creature token with haste onto the battlefield.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new GoblinAssaultToken()), TargetController.YOU, false));
+
// Goblin creatures attack each turn if able.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GoblinAssaultEffect()));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AttacksIfAbleAllEffect(filter, Duration.WhileOnBattlefield)), new AttackedThisTurnWatcher());
}
public GoblinAssault(final GoblinAssault card) {
@@ -72,48 +78,6 @@ public class GoblinAssault extends CardImpl {
}
}
-
-class GoblinAssaultEffect extends RequirementEffect {
-
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Goblin creatures");
- static {
- filter.add(new SubtypePredicate("Goblin"));
- }
-
- public GoblinAssaultEffect() {
- super(Duration.WhileOnBattlefield);
- staticText = "Goblin creatures attack each turn if able";
- }
-
- public GoblinAssaultEffect(final GoblinAssaultEffect effect) {
- super(effect);
- }
-
- @Override
- public GoblinAssaultEffect copy() {
- return new GoblinAssaultEffect(this);
- }
-
- @Override
- public boolean applies(Permanent permanent, Ability source, Game game) {
- if (filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
- return true;
- }
- return false;
- }
-
- @Override
- public boolean mustAttack(Game game) {
- return true;
- }
-
- @Override
- public boolean mustBlock(Game game) {
- return false;
- }
-
-}
-
class GoblinAssaultToken extends Token {
public GoblinAssaultToken() {
diff --git a/Mage.Sets/src/mage/sets/stronghold/SliverQueen.java b/Mage.Sets/src/mage/sets/stronghold/SliverQueen.java
index a7d7b7c7273..c5218656fc1 100644
--- a/Mage.Sets/src/mage/sets/stronghold/SliverQueen.java
+++ b/Mage.Sets/src/mage/sets/stronghold/SliverQueen.java
@@ -36,7 +36,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
-import mage.game.permanent.token.Token;
+import mage.game.permanent.token.SliverToken;
/**
*
@@ -66,14 +66,3 @@ public class SliverQueen extends CardImpl {
return new SliverQueen(this);
}
}
-
-class SliverToken extends Token {
-
- public SliverToken() {
- super("Sliver", "1/1 colorless Sliver creature token");
- cardType.add(CardType.CREATURE);
- subtype.add("Sliver");
- power = new MageInt(1);
- toughness = new MageInt(1);
- }
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/tempest/CircleOfProtectionShadow.java b/Mage.Sets/src/mage/sets/tempest/CircleOfProtectionShadow.java
new file mode 100644
index 00000000000..195c8378d33
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/tempest/CircleOfProtectionShadow.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.tempest;
+
+import java.util.UUID;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToYouEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class CircleOfProtectionShadow extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature of your choice with shadow");
+
+ static {
+ filter.add(new AbilityPredicate(ShadowAbility.class));
+ }
+
+ public CircleOfProtectionShadow(UUID ownerId) {
+ super(ownerId, 224, "Circle of Protection: Shadow", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
+ this.expansionSetCode = "TMP";
+
+ // {1}: The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage.
+ Effect effect = new PreventNextDamageFromChosenSourceToYouEffect(Duration.EndOfTurn, filter);
+ effect.setText("The next time a creature of your choice with shadow would deal damage to you this turn, prevent that damage");
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("1")));
+ }
+
+ public CircleOfProtectionShadow(final CircleOfProtectionShadow card) {
+ super(card);
+ }
+
+ @Override
+ public CircleOfProtectionShadow copy() {
+ return new CircleOfProtectionShadow(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/tempest/DauthiGhoul.java b/Mage.Sets/src/mage/sets/tempest/DauthiGhoul.java
new file mode 100644
index 00000000000..8b81a6833e1
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/tempest/DauthiGhoul.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.tempest;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.DiesCreatureTriggeredAbility;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.counters.CounterType;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class DauthiGhoul extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature with shadow");
+
+ static {
+ filter.add(new AbilityPredicate(ShadowAbility.class));
+ }
+
+ public DauthiGhoul(UUID ownerId) {
+ super(ownerId, 15, "Dauthi Ghoul", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{B}");
+ this.expansionSetCode = "TMP";
+ this.subtype.add("Dauthi");
+ this.subtype.add("Zombie");
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // Whenever a creature with shadow dies, put a +1/+1 counter on Dauthi Ghoul.
+ this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, filter));
+ }
+
+ public DauthiGhoul(final DauthiGhoul card) {
+ super(card);
+ }
+
+ @Override
+ public DauthiGhoul copy() {
+ return new DauthiGhoul(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/tempest/ThalakosMistfolk.java b/Mage.Sets/src/mage/sets/tempest/ThalakosMistfolk.java
new file mode 100644
index 00000000000..d13503cf7ed
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/tempest/ThalakosMistfolk.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.tempest;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.PutOnLibrarySourceEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class ThalakosMistfolk extends CardImpl {
+
+ public ThalakosMistfolk(UUID ownerId) {
+ super(ownerId, 93, "Thalakos Mistfolk", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{U}");
+ this.expansionSetCode = "TMP";
+ this.subtype.add("Thalakos");
+ this.subtype.add("Illusion");
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // {U}: Put Thalakos Mistfolk on top of its owner's library.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibrarySourceEffect(true), new ManaCostsImpl("{U}")));
+ }
+
+ public ThalakosMistfolk(final ThalakosMistfolk card) {
+ super(card);
+ }
+
+ @Override
+ public ThalakosMistfolk copy() {
+ return new ThalakosMistfolk(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/timeshifted/FacelessButcher.java b/Mage.Sets/src/mage/sets/timeshifted/FacelessButcher.java
index 3fc17bbe5a5..9ff88812945 100644
--- a/Mage.Sets/src/mage/sets/timeshifted/FacelessButcher.java
+++ b/Mage.Sets/src/mage/sets/timeshifted/FacelessButcher.java
@@ -32,6 +32,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
+import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
import mage.cards.CardImpl;
@@ -56,8 +57,8 @@ public class FacelessButcher extends CardImpl {
static {
filter.add(new AnotherPredicate());
}
-
-
+
+
public FacelessButcher(UUID ownerId) {
super(ownerId, 43, "Faceless Butcher", Rarity.SPECIAL, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.expansionSetCode = "TSB";
@@ -65,10 +66,12 @@ public class FacelessButcher extends CardImpl {
this.subtype.add("Horror");
this.power = new MageInt(2);
this.toughness = new MageInt(3);
-
+
// When Faceless Butcher enters the battlefield, exile target creature other than Faceless Butcher.
- Ability ability1 = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect(), false);
+ Effect effect = new ExileTargetForSourceEffect();
+ effect.setText("exile target creature other than {this}");
+ Ability ability1 = new EntersBattlefieldTriggeredAbility(effect, false);
Target target = new TargetPermanent(filter);
ability1.addTarget(target);
this.addAbility(ability1);
@@ -76,7 +79,7 @@ public class FacelessButcher extends CardImpl {
// When Faceless Butcher leaves the battlefield, return the exiled card to the battlefield under its owner's control.
Ability ability2 = new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false);
this.addAbility(ability2);
-
+
}
public FacelessButcher(final FacelessButcher card) {
diff --git a/Mage.Sets/src/mage/sets/timespiral/FacelessDevourer.java b/Mage.Sets/src/mage/sets/timespiral/FacelessDevourer.java
new file mode 100644
index 00000000000..10a7130adcd
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/timespiral/FacelessDevourer.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.timespiral;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.ExileTargetForSourceEffect;
+import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.filter.predicate.permanent.AnotherPredicate;
+import mage.target.Target;
+import mage.target.TargetPermanent;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class FacelessDevourer extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(new AnotherPredicate());
+ filter.add(new AbilityPredicate(ShadowAbility.class));
+ }
+
+ public FacelessDevourer(UUID ownerId) {
+ super(ownerId, 108, "Faceless Devourer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}");
+ this.expansionSetCode = "TSP";
+ this.subtype.add("Nightmare");
+ this.subtype.add("Horror");
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(1);
+
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // When Faceless Devourer enters the battlefield, exile another target creature with shadow.
+ Effect effect = new ExileTargetForSourceEffect();
+ effect.setText("exile another target creature with shadow");
+ Ability ability = new EntersBattlefieldTriggeredAbility(effect, false);
+ Target target = new TargetPermanent(filter);
+ ability.addTarget(target);
+ this.addAbility(ability);
+ // When Faceless Devourer leaves the battlefield, return the exiled card to the battlefield under its owner's control.
+ ability = new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false);
+ this.addAbility(ability);
+ }
+
+ public FacelessDevourer(final FacelessDevourer card) {
+ super(card);
+ }
+
+ @Override
+ public FacelessDevourer copy() {
+ return new FacelessDevourer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/timespiral/ScrybRanger.java b/Mage.Sets/src/mage/sets/timespiral/ScrybRanger.java
index f4218fe4bd2..e3fe4173f65 100644
--- a/Mage.Sets/src/mage/sets/timespiral/ScrybRanger.java
+++ b/Mage.Sets/src/mage/sets/timespiral/ScrybRanger.java
@@ -32,7 +32,7 @@ import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.FlyingAbility;
@@ -76,7 +76,7 @@ public class ScrybRanger extends CardImpl {
// protection from blue
this.addAbility(new ProtectionAbility(filter));
// Return a Forest you control to its owner's hand: Untap target creature. Activate this ability only once each turn.
- Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filterForest)));
+ Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filterForest)));
ability.addTarget(new TargetCreaturePermanent(1));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/timespiral/StrongholdOverseer.java b/Mage.Sets/src/mage/sets/timespiral/StrongholdOverseer.java
new file mode 100644
index 00000000000..6127f98184d
--- /dev/null
+++ b/Mage.Sets/src/mage/sets/timespiral/StrongholdOverseer.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.sets.timespiral;
+
+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.Effect;
+import mage.abilities.effects.common.continuous.BoostAllEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.ShadowAbility;
+import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Rarity;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class StrongholdOverseer extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with shadow");
+ private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures without shadow");
+
+ static {
+ filter.add(new AbilityPredicate(ShadowAbility.class));
+ filter2.add(Predicates.not(new AbilityPredicate(ShadowAbility.class)));
+ }
+
+ public StrongholdOverseer(UUID ownerId) {
+ super(ownerId, 133, "Stronghold Overseer", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}");
+ this.expansionSetCode = "TSP";
+ this.subtype.add("Demon");
+ this.power = new MageInt(5);
+ this.toughness = new MageInt(5);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+ // Shadow
+ this.addAbility(ShadowAbility.getInstance());
+ // {B}{B}: Creatures with shadow get +1/+0 until end of turn and creatures without shadow get -1/-0 until end of turn.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 0, Duration.EndOfTurn, filter, false), new ManaCostsImpl("{B}{B}"));
+ Effect effect = new BoostAllEffect(-1, 0, Duration.EndOfTurn, filter2, false);
+ effect.setText("and creatures without shadow get -1/-0 until end of turn");
+ ability.addEffect(effect);
+ this.addAbility(ability);
+ }
+
+ public StrongholdOverseer(final StrongholdOverseer card) {
+ super(card);
+ }
+
+ @Override
+ public StrongholdOverseer copy() {
+ return new StrongholdOverseer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/timespiral/Triskelavus.java b/Mage.Sets/src/mage/sets/timespiral/Triskelavus.java
index 704c4c478d8..6a95558fbb8 100644
--- a/Mage.Sets/src/mage/sets/timespiral/Triskelavus.java
+++ b/Mage.Sets/src/mage/sets/timespiral/Triskelavus.java
@@ -34,6 +34,7 @@ import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.SacrificeSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@@ -61,12 +62,14 @@ public class Triskelavus extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
-
+
// Triskelavus enters the battlefield with three +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it"));
-
+
// {1}, Remove a +1/+1 counter from Triskelavus: Put a 1/1 colorless Triskelavite artifact creature token with flying onto the battlefield. It has "Sacrifice this creature: This creature deals 1 damage to target creature or player."
- this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new TriskelaviteToken()), new RemoveCountersSourceCost(CounterType.P1P1.createInstance())));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new TriskelaviteToken()), new GenericManaCost(1));
+ ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
+ this.addAbility(ability);
}
public Triskelavus(final Triskelavus card) {
@@ -93,7 +96,7 @@ class TriskelaviteToken extends Token {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new SacrificeSourceCost());
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
-
+
addAbility(FlyingAbility.getInstance());
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/visions/QuirionRanger.java b/Mage.Sets/src/mage/sets/visions/QuirionRanger.java
index bfba3fdce8c..1df79ddb4ce 100644
--- a/Mage.Sets/src/mage/sets/visions/QuirionRanger.java
+++ b/Mage.Sets/src/mage/sets/visions/QuirionRanger.java
@@ -34,7 +34,7 @@ import mage.constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledPermanent;
@@ -63,7 +63,7 @@ public class QuirionRanger extends CardImpl {
this.toughness = new MageInt(1);
// Return a Forest you control to its owner's hand: Untap target creature. Activate this ability only once each turn.
- Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(filter)));
+ Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter)));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/sets/zendikar/LivingTsunami.java b/Mage.Sets/src/mage/sets/zendikar/LivingTsunami.java
index 8c761ff0bfe..436b2886265 100644
--- a/Mage.Sets/src/mage/sets/zendikar/LivingTsunami.java
+++ b/Mage.Sets/src/mage/sets/zendikar/LivingTsunami.java
@@ -34,7 +34,7 @@ import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
-import mage.abilities.costs.common.ReturnToHandTargetPermanentCost;
+import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
@@ -67,7 +67,7 @@ public class LivingTsunami extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// At the beginning of your upkeep, sacrifice Living Tsunami unless you return a land you control to its owner's hand.
- this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceUnlessPaysEffect(new ReturnToHandTargetPermanentCost(new TargetControlledPermanent(1, 1, filter, true))), TargetController.YOU, false));
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(1, 1, filter, true))), TargetController.YOU, false));
}
public LivingTsunami(final LivingTsunami card) {
diff --git a/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java b/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java
index 7b75921e09f..ab0741a212c 100644
--- a/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java
+++ b/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java
@@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@@ -20,19 +20,14 @@
* 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.sets.zendikar;
import java.util.UUID;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Rarity;
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -41,6 +36,10 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BecomesBasicLandEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Rarity;
+import mage.constants.Zone;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
@@ -61,6 +60,7 @@ public class SpreadingSeas extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
+
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
// Enchanted land is an Island.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesBasicLandEnchantedEffect("Island")));
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java
index d1f5ab38482..c404d825452 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/InfectTest.java
@@ -27,6 +27,7 @@
*/
package org.mage.test.cards.abilities.keywords;
+import mage.abilities.keyword.InfectAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
@@ -126,4 +127,46 @@ public class InfectTest extends CardTestPlayerBase {
}
+ /**
+ * Phyrexian Obliterator is enchanted with Corrupted Conscience and Enslave
+ *
+ * on upkeep Phyrexian Obliterator does 1 damage to its owner but this
+ * damage was NOT infect damage and it should have been
+ */
+ @Test
+ public void GainedInfectByEnchantment() {
+ // Trample
+ // Whenever a source deals damage to Phyrexian Obliterator, that source's controller sacrifices that many permanents.
+ addCard(Zone.BATTLEFIELD, playerB, "Phyrexian Obliterator");
+
+ // Enchant creature
+ // You control enchanted creature.
+ // Enchanted creature has infect. (It deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)
+ addCard(Zone.HAND, playerA, "Corrupted Conscience"); // Enchantment {3}{U}{U}
+ // Enchant creature
+ // You control enchanted creature.
+ // At the beginning of your upkeep, enchanted creature deals 1 damage to its owner.
+ addCard(Zone.HAND, playerA, "Enslave"); // Enchantment {4}{B}{B}
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 9);
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Corrupted Conscience", "Phyrexian Obliterator");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enslave", "Phyrexian Obliterator");
+
+ setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, "Phyrexian Obliterator", 1);
+ assertPermanentCount(playerA, "Corrupted Conscience", 1);
+ assertPermanentCount(playerA, "Enslave", 1);
+
+ assertAbility(playerA, "Phyrexian Obliterator", InfectAbility.getInstance(), true);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertCounterCount(playerB, CounterType.POISON, 1);
+
+ }
+
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java
index c9736f2aa00..e3701dd6a48 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/CopySpellTest.java
@@ -27,6 +27,7 @@
*/
package org.mage.test.cards.copy;
+import mage.abilities.keyword.FlyingAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
@@ -61,4 +62,61 @@ public class CopySpellTest extends CardTestPlayerBase {
assertHandCount(playerA, "Silvercoat Lion", 1);
}
+ @Test
+ public void ZadaHedronGrinderBoost() {
+ // Target creature gets +3/+3 and gains flying until end of turn.
+ addCard(Zone.HAND, playerA, "Angelic Blessing", 1); // {2}{W}
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
+
+ // Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for each other creature you control that the spell could target. Each copy targets a different one of those creatures.
+ addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angelic Blessing", "Zada, Hedron Grinder");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertGraveyardCount(playerA, "Angelic Blessing", 1);
+ assertPowerToughness(playerA, "Pillarfield Ox", 5, 7);
+ assertAbility(playerA, "Pillarfield Ox", FlyingAbility.getInstance(), true);
+ assertPowerToughness(playerA, "Zada, Hedron Grinder", 6, 6);
+ assertAbility(playerA, "Zada, Hedron Grinder", FlyingAbility.getInstance(), true);
+
+ assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
+ assertAbility(playerB, "Silvercoat Lion", FlyingAbility.getInstance(), false);
+ }
+
+ @Test
+ public void ZadaHedronGrinderBoostWithCharm() {
+ // Choose two -
+ // • Counter target spell.
+ // • Return target permanent to its owner's hand.
+ // • Tap all creatures your opponents control.
+ // • Draw a card.
+ addCard(Zone.HAND, playerA, "Cryptic Command", 1); // {2}{U}{U}{U}
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
+
+ // Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for each other creature you control that the spell could target. Each copy targets a different one of those creatures.
+ addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Command", "mode=2Zada, Hedron Grinder");
+ setModeChoice(playerA, "2"); // Return target permanent to its owner's hand
+ setModeChoice(playerA, "4"); // Draw a card
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
+
+ assertGraveyardCount(playerA, "Cryptic Command", 1);
+ assertPermanentCount(playerA, "Zada, Hedron Grinder", 0);
+ assertPermanentCount(playerA, "Pillarfield Ox", 0);
+ assertHandCount(playerA, 4); // 2 draw + 2 creatures returned to hand
+ }
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
index d7a9ca20297..80560b23bec 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/ConditionalManaTest.java
@@ -36,7 +36,6 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
-
public class ConditionalManaTest extends CardTestPlayerBase {
@Test
@@ -47,11 +46,11 @@ public class ConditionalManaTest extends CardTestPlayerBase {
// Target player gains 7 life.
addCard(Zone.HAND, playerA, "Heroes' Reunion", 1);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Heroes' Reunion", playerA);
-
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Heroes' Reunion", playerA);
+
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
-
+
assertGraveyardCount(playerA, "Heroes' Reunion", 1);
assertHandCount(playerA, "Heroes' Reunion", 0); // player A could not cast it
assertLife(playerA, 27);
@@ -63,16 +62,16 @@ public class ConditionalManaTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Pillar of the Paruns", 2);
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
playerA.addChoice("White");
playerA.addChoice("White");
-
+
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertHandCount(playerA, "Silvercoat Lion", 1); // player A could not cast Silvercoat Lion because the conditional mana is not available
}
-
+
@Test
public void testWorkingWithReflectingPool() {
addCard(Zone.BATTLEFIELD, playerA, "Cavern of Souls", 1);
@@ -80,13 +79,13 @@ public class ConditionalManaTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
-
+
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
- assertPermanentCount(playerA, "Silvercoat Lion", 1);
+ assertPermanentCount(playerA, "Silvercoat Lion", 1);
}
-
+
@Test
public void testWorkingWithReflectingPool2() {
addCard(Zone.BATTLEFIELD, playerA, "Reflecting Pool", 1); // can create white mana without restriction from the Hive
@@ -98,10 +97,48 @@ public class ConditionalManaTest extends CardTestPlayerBase {
setChoice(playerA, "White");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
-
+
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
-
- assertPermanentCount(playerA, "Silvercoat Lion", 1);
- }
+
+ assertPermanentCount(playerA, "Silvercoat Lion", 1);
+ }
+
+ /**
+ * I wasunable to use "Rosheen Meanderer" ability to pay for "Candelabra of
+ * Tawnos" ability even thought it has "X" on its cost
+ */
+ @Test
+ public void testRosheenMeandererUsingAbility() {
+ // Flying
+ addCard(Zone.HAND, playerB, "Snapping Drake", 2); // {3}{U}
+ // {T}: Add {4} to your mana pool. Spend this mana only on costs that contain {X}.
+ addCard(Zone.BATTLEFIELD, playerB, "Rosheen Meanderer", 1);
+ // {X}, {T}: Untap X target lands.
+ addCard(Zone.BATTLEFIELD, playerB, "Candelabra of Tawnos", 1);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Snapping Drake");
+
+ activateManaAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: Add {4}");
+
+ activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{X},{T}: Untap");
+ setChoice(playerB, "X=4");
+ addTarget(playerB, "Island");
+ addTarget(playerB, "Island");
+ addTarget(playerB, "Island");
+ addTarget(playerB, "Island");
+
+ castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Snapping Drake");
+
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+
+ assertTappedCount("Island", true, 4);
+ assertTappedCount("Rosheen Meanderer", true, 1);
+ assertTappedCount("Candelabra of Tawnos", true, 1);
+
+ assertPermanentCount(playerB, "Snapping Drake", 2);
+ }
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java
new file mode 100644
index 00000000000..38bed27ca82
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/DrawTriggeredTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package org.mage.test.cards.triggers;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class DrawTriggeredTest extends CardTestPlayerBase {
+
+ /*
+ * Day's Undoing - Doesn't create card draw triggers "Specifically, it
+ * doesn't work with Chasm Skulker.
+ *
+ * Steps to reproduce:
+ 1) Have Chasm Skulker on the battlefield.
+ 2) Cast Day's Undoing.
+ 3) You will draw 7 cards, but Chasm Skulker's ""when you draw a card"" trigger does not trigger." ==> What is correct
+ */
+ @Test
+ public void DaysUndoingTriggeredDrewEventAreRemovedTest() {
+ // Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. If it's your turn, end the turn.
+ addCard(Zone.HAND, playerA, "Day's Undoing");
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+
+ // Whenever you draw a card, put a +1/+1 counter on Chasm Skulker.
+ // When Chasm Skulker dies, put X 1/1 blue Squid creature tokens with islandwalk onto the battlefield, where X is the number of +1/+1 counters on Chasm Skulker.
+ addCard(Zone.BATTLEFIELD, playerB, "Chasm Skulker", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Day's Undoing");
+
+ setStopAt(2, PhaseStep.UNTAP);
+ execute();
+
+ assertExileCount("Day's Undoing", 1);
+ assertPermanentCount(playerB, "Chasm Skulker", 1);
+ assertPowerToughness(playerB, "Chasm Skulker", 1, 1);
+
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/UlamogTheInfiniteGyreTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/UlamogTheInfiniteGyreTest.java
index 44a39cd25c7..dfde867688b 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/UlamogTheInfiniteGyreTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/UlamogTheInfiniteGyreTest.java
@@ -36,11 +36,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*
* @author LevelX2
*/
-
public class UlamogTheInfiniteGyreTest extends CardTestPlayerBase {
/**
- * Tests if Ulamog, the Infinite Gyre is countered its triggered ability resolves anyway
+ * Tests if Ulamog, the Infinite Gyre is countered its triggered ability
+ * resolves anyway
*/
@Test
public void testDisabledEffectOnChangeZone() {
@@ -57,11 +57,57 @@ public class UlamogTheInfiniteGyreTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
-
assertHandCount(playerA, "Ulamog, the Infinite Gyre", 0);
assertPermanentCount(playerA, "Ulamog, the Infinite Gyre", 0);
assertGraveyardCount(playerB, "Counterspell", 1);
assertPermanentCount(playerB, "Island", 1);
}
+ /**
+ * If one of the big eldrazi is under the control of someone that is not its
+ * owner when it goes to the graveyard, it's ability doesn't trigger
+ * correctly.
+ */
+ @Test
+ public void testControlledByOtherPlayer() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 15);
+ // When you cast Kozilek, Butcher of Truth, draw four cards.
+ // Annihilator 4 (Whenever this creature attacks, defending player sacrifices four permanents.)
+ // When Kozilek is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.
+ addCard(Zone.HAND, playerA, "Kozilek, Butcher of Truth"); // {10}
+ // Destroy target creature.
+ // Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, you gain 2 life.
+ addCard(Zone.HAND, playerA, "Unholy Hunger"); // {3}{B}{B}
+ addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 4);
+ addCard(Zone.HAND, playerB, "Control Magic", 1);
+ addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kozilek, Butcher of Truth");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Control Magic", "Kozilek, Butcher of Truth");
+ castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, "Unholy Hunger", "Kozilek, Butcher of Truth");
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+
+ assertPermanentCount(playerA, "Kozilek, Butcher of Truth", 0);
+ assertPermanentCount(playerB, "Kozilek, Butcher of Truth", 0);
+
+ assertLife(playerA, 20);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+ assertHandCount(playerB, "Control Magic", 0);
+ assertGraveyardCount(playerB, "Control Magic", 1);
+
+ assertGraveyardCount(playerA, "Kozilek, Butcher of Truth", 0);
+
+ assertHandCount(playerA, "Kozilek, Butcher of Truth", 0);
+ assertGraveyardCount(playerA, "Silvercoat Lion", 0);
+
+ assertGraveyardCount(playerA, "Unholy Hunger", 0);
+
+ assertHandCount(playerA, 4);
+
+ }
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SunderingTitanTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SunderingTitanTest.java
new file mode 100644
index 00000000000..325257cf28c
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SunderingTitanTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package org.mage.test.cards.triggers.dies;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class SunderingTitanTest extends CardTestPlayerBase {
+
+ /**
+ * the card Sundering Titan doesn't trigger for the aposing player
+ *
+ */
+ @Test
+ public void testComesIntoTriggeredAbility() {
+ // // When Sundering Titan enters the battlefield or leaves the battlefield, choose a land of each basic land type, then destroy those lands.
+ addCard(Zone.HAND, playerA, "Sundering Titan"); // {8}
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sundering Titan");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Sundering Titan", 1);
+ assertGraveyardCount(playerA, "Swamp", 1);
+ assertGraveyardCount(playerA, "Forest", 1);
+ assertGraveyardCount(playerA, "Island", 1);
+
+ assertGraveyardCount(playerB, "Mountain", 1);
+ assertGraveyardCount(playerB, "Plains", 1);
+
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
index 26e68f09440..bc7f74a40f4 100644
--- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
+++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java
@@ -858,7 +858,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
}
}
- Assert.assertEquals("(Graveyard) Card counts are not equal (" + cardName + ")", count, actualCount);
+ Assert.assertEquals("(Graveyard " + player.getName() + ") Card counts are not equal (" + cardName + ")", count, actualCount);
}
/**
diff --git a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java b/Mage/src/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java
similarity index 88%
rename from Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java
rename to Mage/src/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java
index 6a0e383c83f..238377fdf4b 100644
--- a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetPermanentCost.java
+++ b/Mage/src/mage/abilities/costs/common/ReturnToHandChosenControlledPermanentCost.java
@@ -40,9 +40,10 @@ import mage.target.common.TargetControlledPermanent;
*
* @author BetaSteward_at_googlemail.com
*/
-public class ReturnToHandTargetPermanentCost extends CostImpl {
+public class ReturnToHandChosenControlledPermanentCost extends CostImpl {
- public ReturnToHandTargetPermanentCost(TargetControlledPermanent target) {
+ public ReturnToHandChosenControlledPermanentCost(TargetControlledPermanent target) {
+ target.setNotTarget(true);
this.addTarget(target);
if (target.getMaxNumberOfTargets() > 1 && target.getMaxNumberOfTargets() == target.getNumberOfTargets()) {
this.text = new StringBuilder("return ").append(target.getMaxNumberOfTargets()).append(" ").append(target.getTargetName()).append(" you control to its owner's hand").toString();
@@ -51,7 +52,7 @@ public class ReturnToHandTargetPermanentCost extends CostImpl {
}
}
- public ReturnToHandTargetPermanentCost(ReturnToHandTargetPermanentCost cost) {
+ public ReturnToHandChosenControlledPermanentCost(ReturnToHandChosenControlledPermanentCost cost) {
super(cost);
}
@@ -78,8 +79,8 @@ public class ReturnToHandTargetPermanentCost extends CostImpl {
}
@Override
- public ReturnToHandTargetPermanentCost copy() {
- return new ReturnToHandTargetPermanentCost(this);
+ public ReturnToHandChosenControlledPermanentCost copy() {
+ return new ReturnToHandChosenControlledPermanentCost(this);
}
}
diff --git a/Mage/src/mage/abilities/costs/common/SacrificeTargetCost.java b/Mage/src/mage/abilities/costs/common/SacrificeTargetCost.java
index 8e33063ba2f..be90768d5fd 100644
--- a/Mage/src/mage/abilities/costs/common/SacrificeTargetCost.java
+++ b/Mage/src/mage/abilities/costs/common/SacrificeTargetCost.java
@@ -51,6 +51,7 @@ public class SacrificeTargetCost extends CostImpl {
this.addTarget(target);
target.setNotTarget(true); // sacrifice is never targeted
this.text = "sacrifice " + target.getTargetName();
+ target.setTargetName(target.getTargetName() + " (to sacrifice)");
}
public SacrificeTargetCost(TargetControlledPermanent target, boolean noText) {
diff --git a/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java b/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java
index 44403167deb..e679a45d44b 100644
--- a/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java
@@ -148,7 +148,7 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR
if (targetName != null && targetName.length() > 0) {
return targetName + " doesn't untap during its controller's next untap step";
} else {
- return "Target " + (mode == null ? "creature" : mode.getTargets().get(0).getTargetName()) + " doesn't untap during its controller's next untap step";
+ return "target " + (mode == null ? "creature" : mode.getTargets().get(0).getTargetName()) + " doesn't untap during its controller's next untap step";
}
}
diff --git a/Mage/src/mage/abilities/effects/common/ExileTargetForSourceEffect.java b/Mage/src/mage/abilities/effects/common/ExileTargetForSourceEffect.java
index 99b3a1e0bdc..f909d0828ea 100644
--- a/Mage/src/mage/abilities/effects/common/ExileTargetForSourceEffect.java
+++ b/Mage/src/mage/abilities/effects/common/ExileTargetForSourceEffect.java
@@ -84,6 +84,10 @@ public class ExileTargetForSourceEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
+ if(staticText != null && !staticText.isEmpty()) {
+ return staticText;
+ }
+
if (mode.getTargets().isEmpty()) {
return "Exile it";
} else {
diff --git a/Mage/src/mage/abilities/effects/common/ShuffleIntoLibraryGraveOfSourceOwnerEffect.java b/Mage/src/mage/abilities/effects/common/ShuffleIntoLibraryGraveOfSourceOwnerEffect.java
new file mode 100644
index 00000000000..149117f39f0
--- /dev/null
+++ b/Mage/src/mage/abilities/effects/common/ShuffleIntoLibraryGraveOfSourceOwnerEffect.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.abilities.effects.common;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ShuffleIntoLibraryGraveOfSourceOwnerEffect extends OneShotEffect {
+
+ public ShuffleIntoLibraryGraveOfSourceOwnerEffect() {
+ super(Outcome.Benefit);
+ staticText = "its owner shuffles his or her graveyard into his or her library";
+ }
+
+ public ShuffleIntoLibraryGraveOfSourceOwnerEffect(final ShuffleIntoLibraryGraveOfSourceOwnerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ UUID ownerId = game.getOwnerId(source.getSourceId());
+ if (ownerId == null) {
+ return false;
+ }
+ Player owner = game.getPlayer(ownerId);
+ if (owner != null) {
+ owner.moveCards(owner.getGraveyard(), null, Zone.LIBRARY, source, game);
+ owner.shuffleLibrary(game);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public ShuffleIntoLibraryGraveOfSourceOwnerEffect copy() {
+ return new ShuffleIntoLibraryGraveOfSourceOwnerEffect(this);
+ }
+}
diff --git a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java
index 4cdc3b8317a..2983f348322 100644
--- a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java
+++ b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java
@@ -3,7 +3,6 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
-
package mage.abilities.effects.common.combat;
import mage.abilities.Ability;
@@ -12,6 +11,7 @@ import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.watchers.common.AttackedThisTurnWatcher;
/**
*
@@ -24,19 +24,28 @@ public class AttacksIfAbleAllEffect extends RequirementEffect {
public AttacksIfAbleAllEffect(FilterCreaturePermanent filter) {
this(filter, Duration.WhileOnBattlefield);
}
-
+
+ boolean eachCombat;
+
public AttacksIfAbleAllEffect(FilterCreaturePermanent filter, Duration duration) {
+ this(filter, duration, false);
+ }
+
+ public AttacksIfAbleAllEffect(FilterCreaturePermanent filter, Duration duration, boolean eachCombat) {
super(duration);
- staticText = new StringBuilder(filter.getMessage())
- .append(" attack ")
- .append(duration.equals(Duration.EndOfTurn) ? "this":"each")
- .append(" turn if able").toString();
this.filter = filter;
+ this.eachCombat = eachCombat;
+ if (this.duration == Duration.EndOfTurn) {
+ staticText = filter.getMessage() + " attack " + (eachCombat ? "each combat" : "this turn") + " if able";
+ } else {
+ staticText = filter.getMessage() + " attack each " + (eachCombat ? "combat" : "turn") + " if able";
+ }
}
public AttacksIfAbleAllEffect(final AttacksIfAbleAllEffect effect) {
super(effect);
this.filter = effect.filter;
+ this.eachCombat = effect.eachCombat;
}
@Override
@@ -46,7 +55,14 @@ public class AttacksIfAbleAllEffect extends RequirementEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
- return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
+ if (filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) {
+ if (eachCombat) {
+ return true;
+ }
+ AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get("AttackedThisTurn");
+ return watcher != null && !watcher.getAttackedThisTurnCreatures().contains(permanent.getId());
+ }
+ return false;
}
@Override
diff --git a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java
index a06f8ddead7..cc9600fb9c2 100644
--- a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java
+++ b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java
@@ -25,13 +25,12 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.abilities.effects.common.combat;
-import mage.constants.Duration;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.RequirementEffect;
+import mage.constants.Duration;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -56,10 +55,7 @@ public class AttacksIfAbleTargetEffect extends RequirementEffect {
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
- if (this.getTargetPointer().getTargets(game, source).contains(permanent.getId())) {
- return true;
- }
- return false;
+ return this.getTargetPointer().getTargets(game, source).contains(permanent.getId());
}
@Override
@@ -79,8 +75,7 @@ public class AttacksIfAbleTargetEffect extends RequirementEffect {
}
if (this.duration == Duration.EndOfTurn) {
return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks this turn if able").toString();
- }
- else {
+ } else {
return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks each turn if able").toString();
}
}
diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java
index 068fee171e2..41f4c112c21 100644
--- a/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java
+++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesBasicLandEnchantedEffect.java
@@ -25,12 +25,10 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.abilities.effects.common.continuous;
import java.util.ArrayList;
import java.util.Arrays;
-import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.mana.BlackManaAbility;
@@ -46,12 +44,6 @@ import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
-/**
- *
- * @author LevelX2
- */
-
-
public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
protected ArrayList landTypes = new ArrayList<>();
@@ -93,7 +85,7 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
break;
case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game);
- for (String landType : landTypes) {
+ for (String landType : landTypes) {
switch (landType) {
case "Swamp":
permanent.addAbility(new BlackManaAbility(), source.getSourceId(), game);
@@ -134,8 +126,8 @@ public class BecomesBasicLandEnchantedEffect extends ContinuousEffectImpl {
private String setText() {
StringBuilder sb = new StringBuilder("Enchanted land is a ");
int i = 1;
- for (String landType : landTypes) {
- if (i >1) {
+ for (String landType : landTypes) {
+ if (i > 1) {
if (i == landTypes.size()) {
sb.append(" and ");
} else {
diff --git a/Mage/src/mage/abilities/effects/common/turn/AddExtraTurnControllerEffect.java b/Mage/src/mage/abilities/effects/common/turn/AddExtraTurnControllerEffect.java
index 9b08d1d3618..82ada6f9893 100644
--- a/Mage/src/mage/abilities/effects/common/turn/AddExtraTurnControllerEffect.java
+++ b/Mage/src/mage/abilities/effects/common/turn/AddExtraTurnControllerEffect.java
@@ -1,30 +1,30 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list
-* of conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
package mage.abilities.effects.common.turn;
import java.util.UUID;
@@ -54,8 +54,8 @@ public class AddExtraTurnControllerEffect extends OneShotEffect {
public AddExtraTurnControllerEffect(boolean loseGameAtEnd) {
super(loseGameAtEnd ? Outcome.AIDontUseIt : Outcome.ExtraTurn);
this.loseGameAtEnd = loseGameAtEnd;
- staticText = "Take an extra turn after this one";
- if(loseGameAtEnd) {
+ staticText = "take an extra turn after this one";
+ if (loseGameAtEnd) {
staticText += ". At the beginning of that turn's end step, you lose the game";
}
}
@@ -76,7 +76,7 @@ public class AddExtraTurnControllerEffect extends OneShotEffect {
if (player != null) {
TurnMod extraTurn = new TurnMod(player.getId(), false);
game.getState().getTurnMods().add(extraTurn);
- if(loseGameAtEnd) {
+ if (loseGameAtEnd) {
LoseGameDelayedTriggeredAbility delayedTriggeredAbility = new LoseGameDelayedTriggeredAbility();
delayedTriggeredAbility.setSourceId(source.getSourceId());
delayedTriggeredAbility.setControllerId(source.getControllerId());
diff --git a/Mage/src/mage/abilities/keyword/NinjutsuAbility.java b/Mage/src/mage/abilities/keyword/NinjutsuAbility.java
index 23d23b2aad4..8fc900bd3d1 100644
--- a/Mage/src/mage/abilities/keyword/NinjutsuAbility.java
+++ b/Mage/src/mage/abilities/keyword/NinjutsuAbility.java
@@ -1,36 +1,33 @@
/*
-* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are
-* permitted provided that the following conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of
-* conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list
-* of conditions and the following disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
-* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-* The views and conclusions contained in the software and documentation are those of the
-* authors and should not be interpreted as representing official policies, either expressed
-* or implied, of BetaSteward_at_googlemail.com.
-*/
-
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
package mage.abilities.keyword;
import java.util.UUID;
-
-import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
@@ -41,6 +38,7 @@ import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
+import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.UnblockedPredicate;
import mage.game.Game;
@@ -52,9 +50,9 @@ import mage.target.common.TargetControlledPermanent;
/**
* 702.47. Ninjutsu
*
- * 702.47a Ninjutsu is an activated ability that functions only while the card
- * with ninjutsu is in a player's hand. "Ninjutsu [cost]" means "[Cost], Reveal
- * this card from your hand, Return an unblocked attacking creature you control
+ * 702.47a Ninjutsu is an activated ability that functions only while the card
+ * with ninjutsu is in a player's hand. "Ninjutsu [cost]" means "[Cost], Reveal
+ * this card from your hand, Return an unblocked attacking creature you control
* to its owner's hand: Put this card onto the battlefield from your hand tapped
* and attacking."
*
@@ -62,8 +60,8 @@ import mage.target.common.TargetControlledPermanent;
* announced until the ability leaves the stack.
*
* 702.47c A ninjutsu ability may be activated only while a creature on the
- * battlefield is unblocked (see rule 509.1h). The creature with ninjutsu is
- * put onto the battlefield unblocked. It will be attacking the same player or
+ * battlefield is unblocked (see rule 509.1h). The creature with ninjutsu is put
+ * onto the battlefield unblocked. It will be attacking the same player or
* planeswalker as the creature that was returned to its owner's hand.
*
*
@@ -78,13 +76,13 @@ public class NinjutsuAbility extends ActivatedAbilityImpl {
}
/**
- *
+ *
* @param manaCost ninjutsu mana cost
*/
public NinjutsuAbility(ManaCost manaCost) {
- super(Zone.HAND,new NinjutsuEffect(), manaCost);
+ super(Zone.HAND, new NinjutsuEffect(), manaCost);
this.addCost(new RevealNinjutsuCardCost());
- this.addCost(new ReturnAttackerToHandTargetCost(new TargetControlledCreaturePermanent(1,1,filter,false)));
+ this.addCost(new ReturnAttackerToHandTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)));
}
public NinjutsuAbility(NinjutsuAbility ability) {
@@ -128,7 +126,7 @@ class NinjutsuEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
UUID defendingPlayerId = null;
- for (Cost cost :source.getCosts()) {
+ for (Cost cost : source.getCosts()) {
if (cost instanceof ReturnAttackerToHandTargetCost) {
defendingPlayerId = ((ReturnAttackerToHandTargetCost) cost).getDefendingPlayerId();
}
@@ -161,7 +159,7 @@ class ReturnAttackerToHandTargetCost extends CostImpl {
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
if (targets.choose(Outcome.ReturnToHand, controllerId, sourceId, game)) {
- for (UUID targetId: targets.get(0).getTargets()) {
+ for (UUID targetId : targets.get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent == null) {
return false;
diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java
index bb949267611..8a709d93107 100644
--- a/Mage/src/mage/cards/repository/CardRepository.java
+++ b/Mage/src/mage/cards/repository/CardRepository.java
@@ -63,7 +63,7 @@ public enum CardRepository {
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 41;
// raise this if new cards were added to the server
- private static final long CARD_CONTENT_VERSION = 38;
+ private static final long CARD_CONTENT_VERSION = 39;
private final Random random = new Random();
private Dao cardDao;
diff --git a/Mage/src/mage/game/permanent/token/CatToken.java b/Mage/src/mage/game/permanent/token/CatToken.java
new file mode 100644
index 00000000000..486891abbb1
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/CatToken.java
@@ -0,0 +1,50 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class CatToken extends Token {
+
+ public CatToken() {
+ super("Cat", "2/2 white Cat creature token");
+ cardType.add(CardType.CREATURE);
+ color.setWhite(true);
+ subtype.add("Cat");
+ power = new MageInt(2);
+ toughness = new MageInt(2);
+ availableImageSetCodes.addAll(Arrays.asList("SOM", "M13", "M14", "C14"));
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/DemonToken.java b/Mage/src/mage/game/permanent/token/DemonToken.java
new file mode 100644
index 00000000000..824d6eb0a28
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/DemonToken.java
@@ -0,0 +1,69 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+import mage.abilities.keyword.FlyingAbility;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class DemonToken extends Token {
+
+ public DemonToken() {
+ super("Demon", "5/5 black Demon creature token with flying");
+ cardType.add(CardType.CREATURE);
+ color.setBlack(true);
+ subtype.add("Demon");
+ power = new MageInt(5);
+ toughness = new MageInt(5);
+ addAbility(FlyingAbility.getInstance());
+ availableImageSetCodes.addAll(Arrays.asList("INN", "AVR", "C14", "ORI"));
+ }
+
+ public DemonToken(final DemonToken token) {
+ super(token);
+ }
+
+ @Override
+ public DemonToken copy() {
+ return new DemonToken(this);
+ }
+
+ @Override
+ public void setExpansionSetCodeForImage(String code) {
+ super.setExpansionSetCodeForImage(code);
+ if (getOriginalExpansionSetCode().equals("C14")) {
+ this.setTokenType(2);
+ }
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/EldraziScionToken.java b/Mage/src/mage/game/permanent/token/EldraziScionToken.java
index 1b8e1cd6a74..92d33cadc1f 100644
--- a/Mage/src/mage/game/permanent/token/EldraziScionToken.java
+++ b/Mage/src/mage/game/permanent/token/EldraziScionToken.java
@@ -1,16 +1,16 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@@ -20,14 +20,14 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
-
package mage.game.permanent.token;
+import java.util.Random;
import mage.MageInt;
import mage.Mana;
import mage.abilities.costs.common.SacrificeSourceCost;
@@ -49,7 +49,24 @@ public class EldraziScionToken extends Token {
power = new MageInt(1);
toughness = new MageInt(1);
addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana, new SacrificeSourceCost()));
- this.setOriginalExpansionSetCode("BFZ");
+ setOriginalExpansionSetCode("BFZ");
+
}
+ @Override
+ public void setExpansionSetCodeForImage(String code) {
+ super.setExpansionSetCodeForImage(code);
+ if (getOriginalExpansionSetCode().equals("BFZ")) {
+ this.setTokenType(new Random().nextInt(3) + 1); // 3 different images
+ }
+ }
+
+ public EldraziScionToken(final EldraziScionToken token) {
+ super(token);
+ }
+
+ @Override
+ public EldraziScionToken copy() {
+ return new EldraziScionToken(this); //To change body of generated methods, choose Tools | Templates.
+ }
}
diff --git a/Mage/src/mage/game/permanent/token/FaerieRogueToken.java b/Mage/src/mage/game/permanent/token/FaerieRogueToken.java
new file mode 100644
index 00000000000..a64ff364484
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/FaerieRogueToken.java
@@ -0,0 +1,53 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+import mage.abilities.keyword.FlyingAbility;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class FaerieRogueToken extends Token {
+
+ public FaerieRogueToken() {
+ super("Faerie Rogue", "1/1 black Faerie Rogue creature token with flying");
+ cardType.add(CardType.CREATURE);
+ color.setBlack(true);
+ subtype.add("Faerie");
+ subtype.add("Rogue");
+ power = new MageInt(1);
+ toughness = new MageInt(1);
+ addAbility(FlyingAbility.getInstance());
+ availableImageSetCodes.addAll(Arrays.asList("SHM", "MOR", "MMA"));
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/GoatToken.java b/Mage/src/mage/game/permanent/token/GoatToken.java
new file mode 100644
index 00000000000..82ea1284145
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/GoatToken.java
@@ -0,0 +1,50 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class GoatToken extends Token {
+
+ public GoatToken() {
+ super("Goat", "0/1 white Goat creature token");
+ cardType.add(CardType.CREATURE);
+ color.setWhite(true);
+ subtype.add("Goat");
+ power = new MageInt(0);
+ toughness = new MageInt(1);
+ availableImageSetCodes.addAll(Arrays.asList("EVE", "M13", "M14", "C14"));
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/GoblinRogueToken.java b/Mage/src/mage/game/permanent/token/GoblinRogueToken.java
new file mode 100644
index 00000000000..b7839593c22
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/GoblinRogueToken.java
@@ -0,0 +1,51 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class GoblinRogueToken extends Token {
+
+ public GoblinRogueToken() {
+ super("Goblin Rogue", "1/1 black Goblin Rogue creature token");
+ cardType.add(CardType.CREATURE);
+ color.setBlack(true);
+ subtype.add("Goblin");
+ subtype.add("Rogue");
+ power = new MageInt(1);
+ toughness = new MageInt(1);
+ availableImageSetCodes.addAll(Arrays.asList("LRW", "MMA"));
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/HumanToken.java b/Mage/src/mage/game/permanent/token/HumanToken.java
new file mode 100644
index 00000000000..6e580a5642f
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/HumanToken.java
@@ -0,0 +1,67 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class HumanToken extends Token {
+
+ public HumanToken() {
+ super("Human", "1/1 white Human creature token");
+ cardType.add(CardType.CREATURE);
+ color.setWhite(true);
+ subtype.add("Human");
+ power = new MageInt(1);
+ toughness = new MageInt(1);
+ availableImageSetCodes.addAll(Arrays.asList("DKA", "AVR", "FNMP"));
+ }
+
+ public HumanToken(final HumanToken token) {
+ super(token);
+ }
+
+ @Override
+ public HumanToken copy() {
+ return new HumanToken(this);
+ }
+
+ @Override
+ public void setExpansionSetCodeForImage(String code) {
+ super.setExpansionSetCodeForImage(code);
+ if (getOriginalExpansionSetCode().equals("AVR")) {
+ this.setTokenType(1);
+ }
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/SliverToken.java b/Mage/src/mage/game/permanent/token/SliverToken.java
new file mode 100644
index 00000000000..1c95852bfe0
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/SliverToken.java
@@ -0,0 +1,49 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import mage.constants.CardType;
+import mage.MageInt;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class SliverToken extends Token {
+
+ public SliverToken() {
+ super("Sliver", "1/1 colorless Sliver creature token");
+ cardType.add(CardType.CREATURE);
+ subtype.add("Sliver");
+ power = new MageInt(1);
+ toughness = new MageInt(1);
+ availableImageSetCodes.addAll(Arrays.asList("M14", "M15"));
+ }
+}
diff --git a/Mage/src/mage/game/permanent/token/WarriorToken.java b/Mage/src/mage/game/permanent/token/WarriorToken.java
new file mode 100644
index 00000000000..5ddc1c3aa21
--- /dev/null
+++ b/Mage/src/mage/game/permanent/token/WarriorToken.java
@@ -0,0 +1,68 @@
+/*
+* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are
+* permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice, this list
+* of conditions and the following disclaimer in the documentation and/or other materials
+* provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* The views and conclusions contained in the software and documentation are those of the
+* authors and should not be interpreted as representing official policies, either expressed
+* or implied, of BetaSteward_at_googlemail.com.
+*/
+
+package mage.game.permanent.token;
+
+import java.util.Arrays;
+import java.util.Random;
+import mage.MageInt;
+import mage.constants.CardType;
+
+/**
+ *
+ * @author LoneFox
+ */
+public class WarriorToken extends Token {
+
+ public WarriorToken() {
+ super("Warrior", "1/1 white Warrior creature token");
+ cardType.add(CardType.CREATURE);
+ color.setWhite(true);
+ subtype.add("Warrior");
+ power = new MageInt(1);
+ toughness = new MageInt(1);
+ availableImageSetCodes.addAll(Arrays.asList("KTK", "DTK"));
+ }
+
+ public WarriorToken(final WarriorToken token) {
+ super(token);
+ }
+
+ @Override
+ public WarriorToken copy() {
+ return new WarriorToken(this);
+ }
+
+ @Override
+ public void setExpansionSetCodeForImage(String code) {
+ super.setExpansionSetCodeForImage(code);
+ if (getOriginalExpansionSetCode().equals("KTK")) {
+ this.setTokenType(new Random().nextInt(2) + 1);
+ }
+ }
+}
diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java
index 8ab8b836b3c..eb175ea8a29 100644
--- a/Mage/src/mage/players/PlayerImpl.java
+++ b/Mage/src/mage/players/PlayerImpl.java
@@ -1136,7 +1136,9 @@ public abstract class PlayerImpl implements Player, Serializable {
justActivatedType = null;
if (result) {
if (isHuman() && (ability.getAbilityType().equals(AbilityType.SPELL) || ability.getAbilityType().equals(AbilityType.ACTIVATED))) {
- setJustActivatedType(ability.getAbilityType());
+ if (ability.isUsesStack()) { // if the ability does not use the stack (e.g. Suspend) auto pass would go to next phase unintended
+ setJustActivatedType(ability.getAbilityType());
+ }
}
game.getPlayers().resetPassed();
}
@@ -2924,6 +2926,9 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game) {
+ if (cards.isEmpty()) {
+ return true;
+ }
Set cardList = new HashSet<>();
for (UUID cardId : cards) {
fromZone = game.getState().getZone(cardId);
diff --git a/Mage/src/mage/target/common/TargetSpellOrPermanent.java b/Mage/src/mage/target/common/TargetSpellOrPermanent.java
index fea5811abbf..a52afb47ca7 100644
--- a/Mage/src/mage/target/common/TargetSpellOrPermanent.java
+++ b/Mage/src/mage/target/common/TargetSpellOrPermanent.java
@@ -117,13 +117,15 @@ public class TargetSpellOrPermanent extends TargetImpl {
if (permanent != null) {
if (source != null) {
MageObject targetSource = game.getObject(source.getSourceId());
- return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
+ return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game)
+ && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
} else {
return filter.match(permanent, game);
}
}
Spell spell = game.getStack().getSpell(id);
- if (spell != null) {
+ if (spell != null
+ && !source.getSourceId().equals(id)) { // 114.4. A spell or ability on the stack is an illegal target for itself.
return filter.match(spell, game);
}
return false;
@@ -151,7 +153,9 @@ public class TargetSpellOrPermanent extends TargetImpl {
MageObject targetSource = game.getObject(sourceId);
for (StackObject stackObject : game.getStack()) {
Spell spell = game.getStack().getSpell(stackObject.getId());
- if (spell != null && filter.match(spell, sourceId, sourceControllerId, game)) {
+ if (spell != null
+ && !sourceId.equals(spell.getSourceId())
+ && filter.match(spell, sourceId, sourceControllerId, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
@@ -184,7 +188,8 @@ public class TargetSpellOrPermanent extends TargetImpl {
int count = 0;
for (StackObject stackObject : game.getStack()) {
Spell spell = game.getStack().getSpell(stackObject.getId());
- if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) {
+ if (spell != null
+ && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
@@ -208,7 +213,9 @@ public class TargetSpellOrPermanent extends TargetImpl {
MageObject targetSource = game.getObject(sourceId);
for (StackObject stackObject : game.getStack()) {
Spell spell = game.getStack().getSpell(stackObject.getId());
- if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) {
+ if (spell != null
+ && !sourceId.equals(spell.getSourceId())
+ && filter.match(spell, sourceId, sourceControllerId, game)) {
possibleTargets.add(spell.getId());
}
}
@@ -225,7 +232,8 @@ public class TargetSpellOrPermanent extends TargetImpl {
Set possibleTargets = new HashSet<>();
for (StackObject stackObject : game.getStack()) {
Spell spell = game.getStack().getSpell(stackObject.getId());
- if (spell != null && filter.match(spell, null, sourceControllerId, game) && filter.match(spell, game)) {
+ if (spell != null
+ && filter.match(spell, null, sourceControllerId, game)) {
possibleTargets.add(spell.getId());
}
}
diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt
index a8e576fdfed..3a42aba4874 100644
--- a/Utils/release/getting_implemented_cards.txt
+++ b/Utils/release/getting_implemented_cards.txt
@@ -30,6 +30,9 @@ git log 3d8494edb5c0fddcb972758f7d983b8b66a9651e..head --diff-filter=A --name-st
since 1.4.4.v4
git log 513a574ae98aff3d7820e5411a8e5f2a6506e69c..head --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
+since 1.4.4.v6
+git log 7650f53dee0b4d480d2a63befed72b6c8197e752..head --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt
+
3. Copy added_cards.txt to trunk\Utils folder
4. Run script:
> perl extract_in_wiki_format.perl