diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 79a7037063..529c630d99 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -1057,6 +1057,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { this.tablesPane.hideTables(); } + public void setTableFilter() { + if (this.tablesPane != null) { + this.tablesPane.setTableFilter(); + } + } + public void showGames(boolean setActive) { MagePane topPanebefore = getTopMost(tablesPane); if (!tablesPane.isVisible()) { diff --git a/Mage.Client/src/main/java/mage/client/SessionHandler.java b/Mage.Client/src/main/java/mage/client/SessionHandler.java index b99b42e460..74930a76df 100644 --- a/Mage.Client/src/main/java/mage/client/SessionHandler.java +++ b/Mage.Client/src/main/java/mage/client/SessionHandler.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; import mage.cards.decks.DeckCardLists; +import mage.client.chat.LocalCommands; import mage.constants.ManaType; import mage.constants.PlayerAction; import mage.game.match.MatchOptions; @@ -306,7 +307,11 @@ public class SessionHandler { } public static boolean sendChatMessage(UUID chatId, String text) { - return session.sendChatMessage(chatId, text); + if (!LocalCommands.handleLocalCommands(chatId, text)) { + return session.sendChatMessage(chatId, text); + } else { + return false; + } } public static boolean sendPlayerManaType(UUID gameId, UUID playerId, ManaType data) { diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java index 1fa3ee5e80..634f956679 100644 --- a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java +++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java @@ -271,8 +271,8 @@ public class ChatPanelBasic extends javax.swing.JPanel { if (color.equals(MessageColor.YELLOW)) { textColor = "Yellow"; } - if (messageType == MessageType.WHISPER) { - if (username.equalsIgnoreCase("Whisper from " + SessionHandler.getUserName())) { + if (messageType == MessageType.WHISPER_FROM) { + if (username.equalsIgnoreCase(SessionHandler.getUserName())) { if (message.toLowerCase().startsWith("profanity 0")) { PreferencesDialog.saveValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0"); } else if (message.toLowerCase().startsWith("profanity 1")) { @@ -281,6 +281,10 @@ public class ChatPanelBasic extends javax.swing.JPanel { PreferencesDialog.saveValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "2"); } } + username = "Whisper from " + username; + } + if (messageType == MessageType.WHISPER_TO) { + username = "Whisper to " + username; } Matcher matchPattern = cardNamePattern.matcher(message); diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java index cfae0931f9..a3bc1aaa97 100644 --- a/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java +++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java @@ -57,7 +57,8 @@ public class ChatPanelSeparated extends ChatPanelBasic { public void receiveMessage(String username, String message, String time, ChatMessage.MessageType messageType, ChatMessage.MessageColor color) { switch (messageType) { case TALK: - case WHISPER: + case WHISPER_TO: + case WHISPER_FROM: case USER_INFO: super.receiveMessage(username, message, time, messageType, color); return; diff --git a/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java b/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java new file mode 100644 index 0000000000..ec854cad40 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java @@ -0,0 +1,65 @@ +package mage.client.chat; + +import mage.client.MageFrame; +import mage.client.SessionHandler; +import mage.client.util.IgnoreList; +import mage.interfaces.callback.ClientCallback; +import mage.view.ChatMessage; + +import java.text.DateFormat; +import java.util.Date; +import java.util.Optional; +import java.util.StringTokenizer; +import java.util.UUID; + +public class LocalCommands { + + private static final DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.SHORT); + + /** + * Handler for commands that do not require server interaction, i.e settings etc + * @param chatId + * @param text + * @return true if the command was handled locally, else false + */ + public static boolean handleLocalCommands(UUID chatId, String text) { + final StringTokenizer st = new StringTokenizer(text.trim()); + final int tokens = st.countTokens(); + if (tokens == 0) { + return false; + } + + final String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + Optional response = Optional.empty(); + + switch (st.nextToken()) { + case "/ignore": + case "\\ignore": + final String ignoreTarget = tokens > 1 ? st.nextToken() : ""; + response = Optional.of(IgnoreList.ignore(serverAddress, ignoreTarget)); + break; + case "/unignore": + case "\\unignore": + final String unignoreTarget = tokens > 1 ? st.nextToken() : ""; + response = Optional.of(IgnoreList.unignore(serverAddress, unignoreTarget)); + break; + // TODO: move profanity settings to here + default: + break; + } + + if (response.isPresent()) { + displayLocalCommandResponse(chatId, response.get()); + return true; + } + + return false; + } + + private static void displayLocalCommandResponse(UUID chatId, String response) { + final String text = new StringBuilder().append("").append(response).append("").toString(); + ClientCallback chatMessage = new ClientCallback("chatMessage", chatId, + new ChatMessage("", text, timeFormatter.format(new Date()), ChatMessage.MessageColor.BLUE)); + MageFrame.getInstance().processCallback(chatMessage); + } +} diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java index be43daee88..c94ebc1808 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java @@ -41,6 +41,7 @@ import mage.client.SessionHandler; import mage.client.components.MageComponents; import mage.client.table.TablePlayerPanel; import mage.client.util.Event; +import mage.client.util.IgnoreList; import mage.client.util.Listener; import mage.constants.MatchTimeLimit; import mage.constants.MultiplayerAttackOption; @@ -386,6 +387,8 @@ public class NewTableDialog extends MageDialog { options.setPassword(this.txtPassword.getText()); options.setQuitRatio((Integer) this.spnQuitRatio.getValue()); options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue()); + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); if (!checkMatchOptions(options)) { return; } diff --git a/Mage.Client/src/main/java/mage/client/preference/MagePreferences.java b/Mage.Client/src/main/java/mage/client/preference/MagePreferences.java index 6f63f14f18..64f200a28f 100644 --- a/Mage.Client/src/main/java/mage/client/preference/MagePreferences.java +++ b/Mage.Client/src/main/java/mage/client/preference/MagePreferences.java @@ -1,8 +1,11 @@ package mage.client.preference; +import com.google.common.collect.Sets; +import mage.client.MageFrame; + +import java.util.Set; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; -import mage.client.MageFrame; // TODO: Move all preference related logic from MageFrame and PreferencesDialog to this class. public class MagePreferences { @@ -14,6 +17,8 @@ public class MagePreferences { private static final String KEY_EMAIL = "email"; private static final String KEY_AUTO_CONNECT = "autoConnect"; + private static final String NODE_KEY_IGNORE_LIST = "ignoreListString"; + private static Preferences prefs() { // TODO: Move MageFrame.prefs to this class. return MageFrame.getPreferences(); @@ -98,4 +103,36 @@ public class MagePreferences { public static void setAutoConnect(boolean autoConnect) { prefs().putBoolean(KEY_AUTO_CONNECT, autoConnect); } + + public static void addIgnoredUser(String serverAddress, String username) { + ignoreListNode(serverAddress).putBoolean(username, true); + } + + public static boolean removeIgnoredUser(String serverAddress, String username) { + Preferences ignoreList = ignoreListNode(serverAddress); + boolean exists = ignoreList.getBoolean(username, false); + if (exists) { + ignoreList.remove(username); + } + + return exists; + } + + public static Set ignoreList(String serverAddress) { + try { + return Sets.newHashSet(ignoreListNode(serverAddress).keys()); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + return Sets.newHashSet(); + } + + public static void clearIgnoreList(String serverAddress) throws BackingStoreException { + ignoreListNode(serverAddress).clear(); + } + + private static Preferences ignoreListNode(String serverAddress) { + return prefs().node(NODE_KEY_IGNORE_LIST).node(serverAddress); + } + } diff --git a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java index c2bd89eb95..3185af1bee 100644 --- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java +++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java @@ -34,6 +34,7 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import mage.cards.decks.Deck; import mage.client.MageFrame; +import mage.client.SessionHandler; import mage.client.chat.ChatPanelBasic; import mage.client.constants.Constants.DeckEditorMode; import mage.client.dialog.PreferencesDialog; @@ -42,6 +43,7 @@ import mage.client.game.GamePanel; import mage.client.plugins.impl.Plugins; import mage.client.util.DeckUtil; import mage.client.util.GameManager; +import mage.client.util.IgnoreList; import mage.client.util.audio.AudioManager; import mage.client.util.object.SaveObjectUtil; import mage.interfaces.callback.CallbackClient; @@ -110,6 +112,15 @@ public class CallbackClientImpl implements CallbackClient { break; case "chatMessage": { ChatMessage message = (ChatMessage) callback.getData(); + + // Drop messages from ignored users + if (message.getUsername() != null && IgnoreList.IGNORED_MESSAGE_TYPES.contains(message.getMessageType())) { + final String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + if (IgnoreList.userIsIgnored(serverAddress, message.getUsername())) { + break; + } + } + ChatPanelBasic panel = MageFrame.getChat(callback.getObjectId()); if (panel != null) { // play the sound related to the message @@ -422,6 +433,7 @@ public class CallbackClientImpl implements CallbackClient { usedPanel.receiveMessage("", new StringBuilder("Download card images by using the \"Images\" menu to the top right .") .append("
Download icons and symbols by using the \"Symbols\" menu to the top right.") .append("
\\list - Show a list of available chat commands.") + .append("
").append(IgnoreList.usage()) .append("
Type \\w yourUserName profanity 0 (or 1 or 2) to turn off/on the profanity filter").toString(), null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE); break; diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPane.java b/Mage.Client/src/main/java/mage/client/table/TablesPane.java index 78e685ae6e..dad29c460f 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPane.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPane.java @@ -140,4 +140,10 @@ public class TablesPane extends MagePane { public void deactivated() { tablesPanel.stopTasks(); } + + public void setTableFilter() { + if (tablesPanel != null) { + tablesPanel.setTableFilter(); + } + } } diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 3000313736..56dacd4e4c 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -51,6 +51,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -85,6 +86,7 @@ import mage.client.dialog.TableWaitingDialog; import static mage.client.table.TablesPanel.PASSWORDED; import mage.client.util.ButtonColumn; import mage.client.util.GUISizeHelper; +import mage.client.util.IgnoreList; import mage.client.util.MageTableRowSorter; import mage.client.util.gui.GuiDisplayUtil; import mage.client.util.gui.TableUtil; @@ -550,7 +552,7 @@ public class TablesPanel extends javax.swing.JPanel { return chatPanelMain.getUserChatPanel(); } - private void setTableFilter() { + public void setTableFilter() { // state List> stateFilterList = new ArrayList<>(); if (btnStateWaiting.isSelected()) { @@ -630,6 +632,20 @@ public class TablesPanel extends javax.swing.JPanel { passwordFilterList.add(RowFilter.regexFilter("^\\*\\*\\*$", TableTableModel.COLUMN_PASSWORD)); } + // Hide games of ignored players + List> ignoreListFilterList = new ArrayList<>(); + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + final Set ignoreListCopy = IgnoreList.ignoreList(serverAddress); + if (ignoreListCopy.size() > 0) { + ignoreListFilterList.add(new RowFilter() { + @Override + public boolean include(Entry entry) { + final String owner = entry.getStringValue(TableTableModel.COLUMN_OWNER); + return !ignoreListCopy.contains(owner); + } + }); + } + if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty() || skillFilterList.isEmpty() || ratingFilterList.isEmpty() || passwordFilterList.isEmpty()) { // no selection @@ -673,6 +689,12 @@ public class TablesPanel extends javax.swing.JPanel { filterList.addAll(passwordFilterList); } + if (ignoreListFilterList.size() > 1) { + filterList.add(RowFilter.orFilter(ignoreListFilterList)); + } else if (ignoreListFilterList.size() == 1) { + filterList.addAll(ignoreListFilterList); + } + if (filterList.size() == 1) { activeTablesSorter.setRowFilter(filterList.get(0)); } else { @@ -1177,6 +1199,8 @@ public class TablesPanel extends javax.swing.JPanel { options.setSkillLevel(SkillLevel.CASUAL); options.setRollbackTurnsAllowed(true); options.setQuitRatio(100); + String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); + options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); table = SessionHandler.createTable(roomId, options); SessionHandler.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"), ""); diff --git a/Mage.Client/src/main/java/mage/client/util/IgnoreList.java b/Mage.Client/src/main/java/mage/client/util/IgnoreList.java new file mode 100644 index 0000000000..6c020518d0 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/IgnoreList.java @@ -0,0 +1,98 @@ +package mage.client.util; + +import com.google.common.collect.ImmutableSet; +import mage.client.MageFrame; +import mage.client.preference.MagePreferences; +import mage.view.ChatMessage; + +import java.util.Arrays; +import java.util.Set; + +public class IgnoreList { + + private static final String USAGE = "
\\ignore - shows current ignore list on this server." + + "
\\ignore [username] - add a username to your ignore list on this server." + + "
\\unignore [username] - remove a username from your ignore list on this server.
"; + + public static final int MAX_IGNORE_LIST_SIZE = 50; + public static Set IGNORED_MESSAGE_TYPES = + ImmutableSet.of(ChatMessage.MessageType.TALK, + ChatMessage.MessageType.WHISPER_FROM); + + public static String usage() { + return USAGE; + } + + public static Set ignoreList(String serverAddress) { + return MagePreferences.ignoreList(serverAddress); + } + + public static String ignoreListString(String serverAddress) { + final String[] list = MagePreferences.ignoreList(serverAddress).toArray(new String[0]); + Arrays.sort(list); + return "Current ignore list on " + serverAddress + ": " + + Arrays.toString(list) + + ""; + } + + public static String ignore(String serverAddress, String user) { + if (user == null || user.length() == 0) { + return ignoreListString(serverAddress); + } + + if (MagePreferences.ignoreList(serverAddress).size() >= MAX_IGNORE_LIST_SIZE) { + return "Your ignore list is too big, remove a user to be able to add a new one."; + } + + if (userIsIgnored(serverAddress, user)) { + return new StringBuilder() + .append(user) + .append(" is already on your ignore list on ") + .append(serverAddress) + .toString(); + } + + MagePreferences.addIgnoredUser(serverAddress, user); + updateTablesTable(); + + return new StringBuilder() + .append("Added ") + .append(user) + .append(" to your ignore list on ") + .append(serverAddress) + .toString(); + } + + private static void updateTablesTable() { + MageFrame mageFrame = MageFrame.getInstance(); + if (mageFrame != null) { + mageFrame.setTableFilter(); + } + } + + public static String unignore(String serverAddress, String user) { + if (user == null || user.length() == 0) { + return usage(); + } + if (MagePreferences.removeIgnoredUser(serverAddress, user)) { + updateTablesTable(); + return new StringBuilder() + .append("Removed ") + .append(user) + .append(" from your ignore list on ") + .append(serverAddress) + .toString(); + } else { + return new StringBuilder() + .append("No such user \"") + .append(user) + .append("\" on your ignore list on ") + .append(serverAddress) + .toString(); + } + } + + public static boolean userIsIgnored(String serverAddress, String username) { + return MagePreferences.ignoreList(serverAddress).contains(username); + } +} diff --git a/Mage.Client/src/main/java/mage/client/util/TransformedImageCache.java b/Mage.Client/src/main/java/mage/client/util/TransformedImageCache.java index 285512c072..56916cfbb3 100644 --- a/Mage.Client/src/main/java/mage/client/util/TransformedImageCache.java +++ b/Mage.Client/src/main/java/mage/client/util/TransformedImageCache.java @@ -68,7 +68,7 @@ public class TransformedImageCache { } } - static final Map> IMAGE_CACHE; + private static final Map> IMAGE_CACHE; static { // TODO: can we use a single map? @@ -85,17 +85,17 @@ public class TransformedImageCache { private static BufferedImage rotateImage(BufferedImage image, double angle) { double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle)); - int w = image.getWidth(), h = image.getHeight(); - int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin); + int width = image.getWidth(), height = image.getHeight(); + int newWidth = (int) Math.floor(width * cos + height * sin), newHeight = (int) Math.floor(height * cos + width * sin); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); - BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT); + BufferedImage result = gc.createCompatibleImage(newWidth, newHeight, Transparency.TRANSLUCENT); Graphics2D g = result.createGraphics(); - g.translate((neww - w) / 2, (newh - h) / 2); - g.rotate(angle, w / 2, h / 2); + g.translate((newWidth - width) / 2, (newHeight - height) / 2); + g.rotate(angle, width / 2, height / 2); g.drawRenderedImage(image, null); g.dispose(); return result; diff --git a/Mage.Client/src/test/java/mage/client/preference/MagePreferencesTest.java b/Mage.Client/src/test/java/mage/client/preference/MagePreferencesTest.java new file mode 100644 index 0000000000..7b9681e712 --- /dev/null +++ b/Mage.Client/src/test/java/mage/client/preference/MagePreferencesTest.java @@ -0,0 +1,47 @@ +package mage.client.preference; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class MagePreferencesTest { + @Before + public void setUp() { + MagePreferences.ignoreList("test.com.xx").clear(); + } + + @After + public void tearDown() { + MagePreferences.ignoreList("test.com.xx").clear(); + } + + @Test + public void testIgnoreList() throws Exception { + assertThat(MagePreferences.ignoreList("test.com.xx").size(), is(0)); + assertThat(MagePreferences.removeIgnoredUser("test.com.xx", "test"), is(false)); + + MagePreferences.addIgnoredUser("test.com.xx", "test"); + assertThat(MagePreferences.ignoreList("test.com.xx").size(), is(1)); + assertThat(MagePreferences.ignoreList("other.com.xx").size(), is(0)); + + MagePreferences.addIgnoredUser("test.com.xx", "lul"); + assertThat(MagePreferences.ignoreList("test.com.xx").size(), is(2)); + + assertThat(MagePreferences.ignoreList("test.com.xx").contains("test"), is(true)); + assertThat(MagePreferences.ignoreList("test.com.xx").contains("lul"), is(true)); + + assertThat(MagePreferences.removeIgnoredUser("test.com.xx", "test"), is(true)); + assertThat(MagePreferences.removeIgnoredUser("test.com.xx", "test"), is(false)); + assertThat(MagePreferences.ignoreList("test.com.xx").size(), is(1)); + + assertThat(MagePreferences.removeIgnoredUser("test.com.xx", "lul"), is(true)); + assertThat(MagePreferences.removeIgnoredUser("test.com.xx", "lul"), is(false)); + assertThat(MagePreferences.ignoreList("test.com.xx").size(), is(0)); + + assertThat(MagePreferences.ignoreList("test.com.xx").contains("test"), is(false)); + assertThat(MagePreferences.ignoreList("test.com.xx").contains("lul"), is(false)); + } +} \ No newline at end of file diff --git a/Mage.Client/src/test/java/mage/client/util/IgnoreListTest.java b/Mage.Client/src/test/java/mage/client/util/IgnoreListTest.java new file mode 100644 index 0000000000..c4ad2f8b44 --- /dev/null +++ b/Mage.Client/src/test/java/mage/client/util/IgnoreListTest.java @@ -0,0 +1,85 @@ +package mage.client.util; + +import mage.client.preference.MagePreferences; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +public class IgnoreListTest { + + @Before + public void setUp() throws Exception { + MagePreferences.clearIgnoreList("test.com.xx"); + } + + @After + public void tearDown() throws Exception { + MagePreferences.clearIgnoreList("test.com.xx"); + } + + @Test + public void ignoreListEmpty() throws Exception { + assertThat(IgnoreList.ignoreListString("test.com.xx"), is("Current ignore list on test.com.xx: []")); + } + + @Test + public void ignoreList() throws Exception { + final String test = IgnoreList.ignore("test.com.xx", "test"); + final String kranken = IgnoreList.ignore("test.com.xx", "kranken"); + assertThat(IgnoreList.ignoreListString("test.com.xx"), is("Current ignore list on test.com.xx: [kranken, test]")); + assertThat(test, is("Added test to your ignore list on test.com.xx")); + assertThat(kranken, is("Added kranken to your ignore list on test.com.xx")); + } + + @Test + public void ignore() throws Exception { + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(false)); + final String r = IgnoreList.ignore("test.com.xx", "kranken"); + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(true)); + assertEquals(r, "Added kranken to your ignore list on test.com.xx"); + } + + @Test + public void ignoreAgain() throws Exception { + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(false)); + IgnoreList.ignore("test.com.xx", "kranken"); + final String r = IgnoreList.ignore("test.com.xx", "kranken"); + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(true)); + assertEquals(r, "kranken is already on your ignore list on test.com.xx"); + } + + @Test + public void ignoreDefaultResponse() throws Exception { + final String r1 = IgnoreList.ignore("test.com.xx", ""); + final String r2 = IgnoreList.ignore("test.com.xx", null); + assertThat(IgnoreList.ignoreListString("test.com.xx"), is("Current ignore list on test.com.xx: []")); + assertEquals(r1, r2); + assertEquals(r2, "Current ignore list on test.com.xx: []"); + } + + @Test + public void ignoreMaxSize() throws Exception { + for (int i = 0; i < 50; i++) { + IgnoreList.ignore("test.com.xx", "" + i); + } + final String r = IgnoreList.ignore("test.com.xx", "lul"); + assertEquals(r, "Your ignore list is too big, remove a user to be able to add a new one."); + assertThat(IgnoreList.ignoreListString("test.com.xx"), is("Current ignore list on test.com.xx: [0, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 6, 7, 8, 9]")); + } + + @Test + public void unignore() throws Exception { + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(false)); + IgnoreList.ignore("test.com.xx", "kranken"); + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(true)); + final String r = IgnoreList.unignore("test.com.xx", "kranken"); + assertThat(IgnoreList.userIsIgnored("test.com.xx", "kranken"), is(false)); + assertEquals(r, "Removed kranken from your ignore list on test.com.xx"); + + } + +} \ No newline at end of file diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java index c3a98840c1..3549dcd0c5 100644 --- a/Mage.Common/src/mage/remote/SessionImpl.java +++ b/Mage.Common/src/mage/remote/SessionImpl.java @@ -244,6 +244,10 @@ public class SessionImpl implements Session { }); } + public Optional getServerHostname() { + return isConnected() ? Optional.of(connection.getHost()) : Optional.empty(); + } + @Override public boolean stopConnecting() { canceled = true; @@ -960,6 +964,8 @@ public class SessionImpl implements Session { return false; } + + @Override public boolean joinGame(UUID gameId) { try { diff --git a/Mage.Common/src/mage/remote/interfaces/Connect.java b/Mage.Common/src/mage/remote/interfaces/Connect.java index 5cb8750e59..63cbdc431d 100644 --- a/Mage.Common/src/mage/remote/interfaces/Connect.java +++ b/Mage.Common/src/mage/remote/interfaces/Connect.java @@ -29,6 +29,8 @@ package mage.remote.interfaces; import mage.remote.Connection; +import java.util.Optional; + /** * @author noxx */ @@ -52,6 +54,8 @@ public interface Connect { boolean isConnected(); + Optional getServerHostname(); + boolean disconnectUser(String userSessionId); boolean endUserSession(String userSessionId); diff --git a/Mage.Common/src/mage/view/ChatMessage.java b/Mage.Common/src/mage/view/ChatMessage.java index d13dccddb3..888837b9d6 100644 --- a/Mage.Common/src/mage/view/ChatMessage.java +++ b/Mage.Common/src/mage/view/ChatMessage.java @@ -49,7 +49,7 @@ public class ChatMessage implements Serializable { } public enum MessageType { - USER_INFO, STATUS, GAME, TALK, WHISPER + USER_INFO, STATUS, GAME, TALK, WHISPER_FROM, WHISPER_TO } public enum SoundToPlay { diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java index 521fd616b0..70de72b033 100644 --- a/Mage.Server/src/main/java/mage/server/ChatManager.java +++ b/Mage.Server/src/main/java/mage/server/ChatManager.java @@ -132,6 +132,10 @@ public class ChatManager { chatSessions.get(chatId).broadcastInfoToUser(user, informUser); return; } + + if (message.length() > 500) { + message = message.replaceFirst("^(.{500}).*", "$1 (rest of message truncated)"); + } String messageToCheck = message; Matcher matchPattern = cardNamePattern.matcher(message); @@ -186,7 +190,10 @@ public class ChatManager { + "
\\me - shows the history of the current player" + "
\\list or \\l - Show a list of commands" + "
\\whisper or \\w [player name] [text] - whisper to the player with the given name" - + "
[Card Name] - Show a highlighted card name"; + + "
[Card Name] - Show a highlighted card name" + + "
\\ignore - shows current ignore list on this server." + + "
\\ignore [username] - add a username to your ignore list on this server." + + "
\\unignore [username] - remove a username from your ignore list on this server."; private boolean performUserCommand(User user, String message, UUID chatId, boolean doError) { String command = message.substring(1).trim().toUpperCase(Locale.ENGLISH); diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 34119c0852..cb9290d84e 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -127,10 +127,10 @@ public class ChatSession { public boolean broadcastWhisperToUser(User fromUser, User toUser, String message) { if (clients.containsKey(toUser.getId())) { toUser.fireCallback(new ClientCallback("chatMessage", chatId, - new ChatMessage(new StringBuilder("Whisper from ").append(fromUser.getName()).toString(), message, timeFormatter.format(new Date()), MessageColor.YELLOW, MessageType.WHISPER, SoundToPlay.PlayerWhispered))); + new ChatMessage(fromUser.getName(), message, timeFormatter.format(new Date()), MessageColor.YELLOW, MessageType.WHISPER_FROM, SoundToPlay.PlayerWhispered))); if (clients.containsKey(fromUser.getId())) { fromUser.fireCallback(new ClientCallback("chatMessage", chatId, - new ChatMessage(new StringBuilder("Whisper to ").append(toUser.getName()).toString(), message, timeFormatter.format(new Date()), MessageColor.YELLOW, MessageType.WHISPER, null))); + new ChatMessage(toUser.getName(), message, timeFormatter.format(new Date()), MessageColor.YELLOW, MessageType.WHISPER_TO, null))); return true; } } diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index f4490101b7..b21e858cc4 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -27,14 +27,6 @@ */ package mage.server; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; import mage.MageException; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; @@ -68,6 +60,15 @@ import mage.server.util.ThreadExecutor; import mage.view.ChatMessage; import org.apache.log4j.Logger; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -99,7 +100,7 @@ public class TableController { } else { controllerName = "System"; } - table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), match); + table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), match, options.getBannedUsers()); chatId = ChatManager.getInstance().createChatSession("Match Table " + table.getId()); init(); } @@ -118,7 +119,7 @@ public class TableController { } else { controllerName = "System"; } - table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), tournament); + table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), TableRecorderImpl.getInstance(), tournament, options.getMatchOptions().getBannedUsers()); chatId = ChatManager.getInstance().createChatSession("Tourn. table " + table.getId()); } @@ -195,8 +196,9 @@ public class TableController { return false; } - Player player = createPlayer(name, seat.getPlayerType(), skill); - if (player != null) { + Optional playerOptional = createPlayer(name, seat.getPlayerType(), skill); + if (playerOptional.isPresent()) { + Player player = playerOptional.get(); if (!player.canJoinTable(table)) { user.showUserMessage("Join Table", new StringBuilder("A ").append(seat.getPlayerType()).append(" player can't join this table.").toString()); return false; @@ -227,10 +229,11 @@ public class TableController { } public synchronized boolean replaceDraftPlayer(Player oldPlayer, String name, String playerType, int skill) { - Player newPlayer = createPlayer(name, playerType, skill); - if (newPlayer == null || table.getState() != TableState.DRAFTING) { + Optional newPlayerOpt = createPlayer(name, playerType, skill); + if (!newPlayerOpt.isPresent() || table.getState() != TableState.DRAFTING) { return false; } + Player newPlayer = newPlayerOpt.get(); TournamentPlayer oldTournamentPlayer = tournament.getPlayer(oldPlayer.getId()); tournament.removePlayer(oldPlayer.getId()); tournament.addPlayer(newPlayer, playerType); @@ -306,13 +309,14 @@ public class TableController { } } - Player player = createPlayer(name, seat.getPlayerType(), skill); - if (player == null) { + Optional playerOpt = createPlayer(name, seat.getPlayerType(), skill); + if (!playerOpt.isPresent()) { String message = new StringBuilder("Could not create player ").append(name).append(" of type ").append(seat.getPlayerType()).toString(); logger.warn(new StringBuilder("User: ").append(user.getName()).append(" => ").append(message).toString()); user.showUserMessage("Join Table", message); return false; } + Player player = playerOpt.get(); logger.debug("DECK validated: " + table.getValidator().getName() + ' ' + player.getName() + ' ' + deck.getName()); if (!player.canJoinTable(table)) { user.showUserMessage("Join Table", new StringBuilder("A ").append(seat.getPlayerType()).append(" player can't join this table.").toString()); @@ -443,17 +447,18 @@ public class TableController { // ReplayManager.getInstance().replayGame(table.getId(), userId); // return true; // } - private Player createPlayer(String name, String playerType, int skill) { - Player player; + private Optional createPlayer(String name, String playerType, int skill) { + Optional playerOpt; if (options == null) { - player = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, skill); + playerOpt = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, skill); } else { - player = PlayerFactory.getInstance().createPlayer(playerType, name, options.getRange(), skill); + playerOpt = PlayerFactory.getInstance().createPlayer(playerType, name, options.getRange(), skill); } - if (player != null) { + if (playerOpt.isPresent()) { + Player player = playerOpt.get(); logger.trace("Player " + player.getName() + " created id: " + player.getId()); } - return player; + return playerOpt; } public void leaveTableAll() { diff --git a/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java b/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java index f7e430e808..7b43c65ce5 100644 --- a/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java +++ b/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java @@ -28,14 +28,16 @@ package mage.server.game; -import java.lang.reflect.Constructor; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; import mage.constants.RangeOfInfluence; import mage.players.Player; import org.apache.log4j.Logger; +import java.lang.reflect.Constructor; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + /** * * @author BetaSteward_at_googlemail.com @@ -53,14 +55,14 @@ public class PlayerFactory { private PlayerFactory() {} - public Player createPlayer(String playerType, String name, RangeOfInfluence range, int skill) { + public Optional createPlayer(String playerType, String name, RangeOfInfluence range, int skill) { try { Class playerTypeClass = playerTypes.get(playerType); if (playerTypeClass != null) { Constructor con = playerTypeClass.getConstructor(String.class, RangeOfInfluence.class, int.class); Player player = (Player) con.newInstance(name, range, skill); logger.trace("Player created: " + name + " - " + player.getId()); - return player; + return Optional.of(player); } else { logger.fatal("Unknown player type: " + playerType); @@ -68,7 +70,7 @@ public class PlayerFactory { } catch (Exception ex) { logger.fatal("PlayerFactory error ", ex); } - return null; + return Optional.empty(); } public Set getPlayerTypes() { diff --git a/Mage.Sets/src/mage/cards/a/AetherChaser.java b/Mage.Sets/src/mage/cards/a/AetherChaser.java index 01fc50c283..668608907f 100644 --- a/Mage.Sets/src/mage/cards/a/AetherChaser.java +++ b/Mage.Sets/src/mage/cards/a/AetherChaser.java @@ -27,7 +27,6 @@ */ package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -41,6 +40,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.game.permanent.token.ServoToken; +import java.util.UUID; + /** * * @author fireshoes @@ -62,7 +63,7 @@ public class AetherChaser extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(2))); // Whenever Aether Chaser attacks, you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token. - this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), false, + this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new ServoToken()), new PayEnergyCost(2)), true, "Whenever {this} attacks you may pay {E}{E}. If you do, create a 1/1 colorless Servo artifact creature token.")); } diff --git a/Mage.Sets/src/mage/cards/a/AshlingsPrerogative.java b/Mage.Sets/src/mage/cards/a/AshlingsPrerogative.java index 0849ce9330..d7d1155f02 100644 --- a/Mage.Sets/src/mage/cards/a/AshlingsPrerogative.java +++ b/Mage.Sets/src/mage/cards/a/AshlingsPrerogative.java @@ -86,6 +86,10 @@ class AshlingsPrerogativeIncorrectOddityEffect extends PermanentsEnterBattlefiel super(creaturefilter); staticText = "Each creature without converted mana cost of the chosen value enters the battlefield tapped."; } + + public AshlingsPrerogativeIncorrectOddityEffect(final AshlingsPrerogativeIncorrectOddityEffect effect) { + super(effect); + } @Override public boolean applies(GameEvent event, Ability source, Game game) { @@ -101,6 +105,11 @@ class AshlingsPrerogativeIncorrectOddityEffect extends PermanentsEnterBattlefiel return permanent != null && creaturefilter.match(permanent, game) && permanent.getConvertedManaCost() % 2 == incorrectModResult; } + + @Override + public AshlingsPrerogativeIncorrectOddityEffect copy() { + return new AshlingsPrerogativeIncorrectOddityEffect(this); + } } class AshlingsPrerogativeCorrectOddityEffect extends GainAbilityAllEffect { @@ -112,6 +121,9 @@ class AshlingsPrerogativeCorrectOddityEffect extends GainAbilityAllEffect { super(HasteAbility.getInstance(), Duration.WhileOnBattlefield, creaturefilter); staticText = "Each creature with converted mana cost of the chosen value has haste."; } + public AshlingsPrerogativeCorrectOddityEffect(final AshlingsPrerogativeCorrectOddityEffect effect) { + super(effect); + } @Override protected boolean selectedByRuntimeData(Permanent permanent, Ability source, Game game) { @@ -123,5 +135,9 @@ class AshlingsPrerogativeCorrectOddityEffect extends GainAbilityAllEffect { } return permanent != null && creaturefilter.match(permanent, game) && permanent.getConvertedManaCost() % 2 == correctModResult; } - + + @Override + public AshlingsPrerogativeCorrectOddityEffect copy() { + return new AshlingsPrerogativeCorrectOddityEffect(this); + } } diff --git a/Mage.Sets/src/mage/cards/c/CanopyCover.java b/Mage.Sets/src/mage/cards/c/CanopyCover.java index e587d4832d..39e9d8af7a 100644 --- a/Mage.Sets/src/mage/cards/c/CanopyCover.java +++ b/Mage.Sets/src/mage/cards/c/CanopyCover.java @@ -59,7 +59,7 @@ public class CanopyCover extends CardImpl { private static final FilterObject filter = new FilterStackObject("spells or abilities your opponents control"); public CanopyCover(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.subtype.add("Aura"); // Enchant creature @@ -70,7 +70,7 @@ public class CanopyCover extends CardImpl { this.addAbility(ability); // Enchanted creature can't be blocked except by creatures with flying or reach. (!this is a static ability of the enchantment) - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OrchardSpiritEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanopyCoverEffect())); // Enchanted creature can't be the target of spells or abilities your opponents control. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.OPPONENT))); @@ -86,14 +86,14 @@ public class CanopyCover extends CardImpl { } } -class OrchardSpiritEffect extends RestrictionEffect { +class CanopyCoverEffect extends RestrictionEffect { - public OrchardSpiritEffect() { + public CanopyCoverEffect() { super(Duration.WhileOnBattlefield); staticText = "Enchanted creature can't be blocked except by creatures with flying or reach"; } - public OrchardSpiritEffect(final OrchardSpiritEffect effect) { + public CanopyCoverEffect(final CanopyCoverEffect effect) { super(effect); } @@ -102,7 +102,7 @@ class OrchardSpiritEffect extends RestrictionEffect { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { Permanent equipped = game.getPermanent(equipment.getAttachedTo()); - if (permanent.getId().equals(equipped.getId())) { + if (equipped != null && permanent.getId().equals(equipped.getId())) { return true; } } @@ -115,7 +115,7 @@ class OrchardSpiritEffect extends RestrictionEffect { } @Override - public OrchardSpiritEffect copy() { - return new OrchardSpiritEffect(this); + public CanopyCoverEffect copy() { + return new CanopyCoverEffect(this); } } diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index 6c39693cf3..f49744f66c 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -30,6 +30,7 @@ package mage.cards.c; import java.util.HashSet; import java.util.Set; import java.util.UUID; + import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; @@ -62,13 +63,12 @@ import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTarget; /** - * * @author jeffwadsworth */ public class ChandraPyromaster extends CardImpl { public ChandraPyromaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{R}"); this.subtype.add("Chandra"); this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); @@ -211,9 +211,11 @@ class ChandraPyromasterEffect2 extends OneShotEffect { Card card = library.removeFromTop(game); if (card != null) { controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " ", source.getSourceId(), game, Zone.LIBRARY, true); - ContinuousEffect effect = new ChandraPyromasterCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); + if (!card.getManaCost().isEmpty()) { + ContinuousEffect effect = new ChandraPyromasterCastFromExileEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java index 36d0bc9a56..d33ad86cca 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java +++ b/Mage.Sets/src/mage/cards/c/ChandraTorchOfDefiance.java @@ -28,6 +28,7 @@ package mage.cards.c; import java.util.UUID; + import mage.MageObject; import mage.Mana; import mage.abilities.Ability; @@ -57,7 +58,6 @@ import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreaturePermanent; /** - * * @author fireshoes */ public class ChandraTorchOfDefiance extends CardImpl { @@ -120,17 +120,19 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect { if (card != null) { boolean exiledCardWasCast = false; controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); - if (controller.chooseUse(Outcome.Benefit, "Cast the card? (You still pay the costs)", source, game) && !card.getCardType().contains(CardType.LAND)) { + if (!card.getManaCost().isEmpty()) + if (controller.chooseUse(Outcome.Benefit, "Cast the card? (You still pay the costs)", source, game) && !card.getCardType().contains(CardType.LAND)) { // LinkedHashMap useableAbilities = controller.getUseableActivatedAbilities(card, Zone.EXILED, game); // for (ActivatedAbility ability : useableAbilities.values()) { // // } // controller.activateAbility(useableAbilities, game); - exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false); - } + exiledCardWasCast = controller.cast(card.getSpellAbility(), game, false); + } if (!exiledCardWasCast) { new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT).apply(game, source); } + } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java b/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java new file mode 100644 index 0000000000..77cac8a8db --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CoalhaulerSwine.java @@ -0,0 +1,99 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author vereena42 + */ +public class CoalhaulerSwine extends CardImpl { + + public CoalhaulerSwine(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + + this.subtype.add("Boar"); + this.subtype.add("Beast"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever Coalhauler Swine is dealt damage, it deals that much damage to each player. + this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new CoalhaulerSwineEffect(), false)); + } + + public CoalhaulerSwine(final CoalhaulerSwine card) { + super(card); + } + + @Override + public CoalhaulerSwine copy() { + return new CoalhaulerSwine(this); + } + + class CoalhaulerSwineEffect extends OneShotEffect { + + public CoalhaulerSwineEffect() { + super(Outcome.Damage); + staticText = "it deals that much damage to each player"; + } + + public CoalhaulerSwineEffect(final CoalhaulerSwineEffect effect) { + super(effect); + } + + @Override + public CoalhaulerSwineEffect copy() { + return new CoalhaulerSwineEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID playerId : game.getPlayers().keySet()) { + Player player = game.getPlayer(playerId); + if(player != null) { + player.damage((Integer) this.getValue("damage"), source.getSourceId(), game, false, true); + } + } + return true; + } + + } +} diff --git a/Mage.Sets/src/mage/cards/d/DeathWatch.java b/Mage.Sets/src/mage/cards/d/DeathWatch.java new file mode 100644 index 0000000000..dccd3c92ec --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathWatch.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.cards.d; + +import mage.abilities.Ability; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author vereena42 + */ +public class DeathWatch extends CardImpl { + + public DeathWatch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); + + 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); + + // When enchanted creature dies, its controller loses life equal to its power and you gain life equal to its toughness. + this.addAbility( new DiesAttachedTriggeredAbility(new DeathWatchEffect(), "enchanted creature")); + } + + public DeathWatch(final DeathWatch card) { + super(card); + } + + @Override + public DeathWatch copy() { + return new DeathWatch(this); + } + + class DeathWatchEffect extends OneShotEffect { + + public DeathWatchEffect() { + super(Outcome.LoseLife); + staticText = "that creature's controller loses life equal to its power and you gain life equal to its toughness."; + } + + public DeathWatchEffect(DeathWatchEffect copy) { + super(copy); + } + + @Override + public DeathWatchEffect copy() { + return new DeathWatchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = (Permanent) getValue("attachedTo"); + if(creature != null){ + Player opponent = game.getPlayer(creature.getOwnerId()); + if (opponent != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.gainLife(creature.getToughness().getValue(), game); + opponent.loseLife(creature.getPower().getValue(), game, false); + return true; + } + } + } + return false; + } + + } +} diff --git a/Mage.Sets/src/mage/cards/d/DimirDoppelganger.java b/Mage.Sets/src/mage/cards/d/DimirDoppelganger.java index 97b111a526..d0dda81b58 100644 --- a/Mage.Sets/src/mage/cards/d/DimirDoppelganger.java +++ b/Mage.Sets/src/mage/cards/d/DimirDoppelganger.java @@ -29,23 +29,28 @@ package mage.cards.d; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CopyEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Layer; import mage.constants.Outcome; -import mage.constants.SubLayer; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; +import mage.players.Player; import mage.target.common.TargetCardInGraveyard; +import mage.util.functions.ApplyToPermanent; /** * @@ -54,7 +59,7 @@ import mage.target.common.TargetCardInGraveyard; public class DimirDoppelganger extends CardImpl { public DimirDoppelganger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}"); this.subtype.add("Shapeshifter"); this.power = new MageInt(0); @@ -77,14 +82,14 @@ public class DimirDoppelganger extends CardImpl { } } -class DimirDoppelgangerEffect extends ContinuousEffectImpl { +class DimirDoppelgangerEffect extends OneShotEffect { - public DimirDoppelgangerEffect() { - super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); + DimirDoppelgangerEffect() { + super(Outcome.Copy); staticText = "Exile target creature card from a graveyard. {this} becomes a copy of that card and gains this ability"; } - public DimirDoppelgangerEffect(final DimirDoppelgangerEffect effect) { + DimirDoppelgangerEffect(final DimirDoppelgangerEffect effect) { super(effect); } @@ -95,49 +100,48 @@ class DimirDoppelgangerEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(source.getFirstTarget()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (card == null || permanent == null) { - return false; - } - card.moveToExile(null, "Dimir Doppelganger", source.getSourceId(), game); - Card cardToCopy = card.copy(); - cardToCopy.assignNewId(); - permanent.setName(cardToCopy.getName()); - permanent.getPower().setValue(cardToCopy.getPower().getValue()); - permanent.getToughness().setValue(cardToCopy.getToughness().getValue()); - permanent.getColor(game).setColor(cardToCopy.getColor(game)); - permanent.getManaCost().clear(); - permanent.getManaCost().add(cardToCopy.getManaCost()); - permanent.getCardType().clear(); - for (CardType type : cardToCopy.getCardType()) { - if (!permanent.getCardType().contains(type)) { - permanent.getCardType().add(type); + Player controller = game.getPlayer(source.getControllerId()); + Permanent dimirDoppelganger = game.getPermanent(source.getSourceId()); + Permanent newBluePrint = null; + if (controller != null + && dimirDoppelganger != null) { + Card copyFromCard = game.getCard(source.getFirstTarget()); + if (copyFromCard != null) { + Cards cardsToExile = new CardsImpl(); + cardsToExile.add(copyFromCard); + controller.moveCards(cardsToExile, Zone.EXILED, source, game); + newBluePrint = new PermanentCard((Card) copyFromCard, source.getControllerId(), game); + newBluePrint.assignNewId(); + ApplyToPermanent applier = new DimirDoppelgangerApplier(); + applier.apply(game, newBluePrint); + CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, dimirDoppelganger.getId()); + copyEffect.newId(); + copyEffect.setApplier(applier); + Ability newAbility = source.copy(); + copyEffect.init(newAbility, game); + game.addEffect(copyEffect, newAbility); } + return true; } - permanent.getSubtype(game).clear(); - for (String type : cardToCopy.getSubtype(game)) { - if (!permanent.getSubtype(game).contains(type)) { - permanent.getSubtype(game).add(type); - } - } - permanent.getSupertype().clear(); - for (String type : cardToCopy.getSupertype()) { - if (!permanent.getSupertype().contains(type)) { - permanent.getSupertype().add(type); - } - } - permanent.removeAllAbilities(source.getSourceId(), game); - // gains ability of Dimir Doppelganger - Ability dimirDoppelgangerAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}")); - dimirDoppelgangerAbility.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"))); - permanent.addAbility(dimirDoppelgangerAbility, source.getSourceId(), game); + return false; + } +} - for (Ability ability : cardToCopy.getAbilities()) { - if (!permanent.getAbilities().contains(ability)) { - permanent.addAbility(ability, source.getSourceId(), game); - } - } +class DimirDoppelgangerApplier extends ApplyToPermanent { + + @Override + public Boolean apply(Game game, Permanent permanent) { + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}")); + ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"))); + permanent.getAbilities().add(ability); + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}")); + ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"))); + mageObject.getAbilities().add(ability); return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EssenceFlux.java b/Mage.Sets/src/mage/cards/e/EssenceFlux.java index d40cc6e44d..2b226db857 100644 --- a/Mage.Sets/src/mage/cards/e/EssenceFlux.java +++ b/Mage.Sets/src/mage/cards/e/EssenceFlux.java @@ -82,7 +82,7 @@ class EssenceFluxEffect extends OneShotEffect { EssenceFluxEffect() { super(Outcome.Benefit); - staticText = "return that card to the battlefield under its owner's control"; + staticText = "return that card to the battlefield under its owner's control. If it's a Spirit, put a +1/+1 counter on it"; } EssenceFluxEffect(final EssenceFluxEffect effect) { diff --git a/Mage.Sets/src/mage/cards/l/LazavDimirMastermind.java b/Mage.Sets/src/mage/cards/l/LazavDimirMastermind.java index e3b356c817..af79f4ed2e 100644 --- a/Mage.Sets/src/mage/cards/l/LazavDimirMastermind.java +++ b/Mage.Sets/src/mage/cards/l/LazavDimirMastermind.java @@ -29,24 +29,27 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; -import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CopyEffect; import mage.abilities.keyword.HexproofAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SetTargetPointer; -import mage.constants.SubLayer; import mage.constants.TargetController; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; +import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import mage.util.functions.ApplyToPermanent; /** * @@ -67,7 +70,7 @@ public class LazavDimirMastermind extends CardImpl { // Whenever a creature card is put into an opponent's graveyard from anywhere, you may have Lazav, Dimir Mastermind become a copy of that card except its name is still Lazav, Dimir Mastermind, it's legendary in addition to its other types, and it gains hexproof and this ability. this.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility( - new LazavDimirEffect(), true, + new LazavDimirMastermindEffect(), true, new FilterCreatureCard("a creature card"), TargetController.OPPONENT, SetTargetPointer.CARD)); } @@ -82,80 +85,73 @@ public class LazavDimirMastermind extends CardImpl { } } -class LazavDimirEffect extends ContinuousEffectImpl { +class LazavDimirMastermindEffect extends OneShotEffect { - protected Card cardToCopy; - - public LazavDimirEffect() { - super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); - staticText = "have {this} become a copy of that card except its name is still {this}, it's legendary in addition to its other types, and it gains hexproof and this ability"; + LazavDimirMastermindEffect() { + super(Outcome.Copy); + staticText = "you may have {this} become a copy of that card except its name is still {this}, it's legendary in addition to its other types, and it gains hexproof and this ability"; } - public LazavDimirEffect(final LazavDimirEffect effect) { + LazavDimirMastermindEffect(final LazavDimirMastermindEffect effect) { super(effect); - this.cardToCopy = effect.cardToCopy; } @Override - public LazavDimirEffect copy() { - return new LazavDimirEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - Card card = game.getCard(((FixedTarget) getTargetPointer()).getTarget()); - if (card != null) { - cardToCopy = card.copy(); - cardToCopy.assignNewId(); - } else { - discard(); - } + public LazavDimirMastermindEffect copy() { + return new LazavDimirMastermindEffect(this); } @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - discard(); + Player controller = game.getPlayer(source.getControllerId()); + Permanent lazavDimirMastermind = game.getPermanent(source.getSourceId()); + Permanent newBluePrint = null; + if (controller != null + && lazavDimirMastermind != null) { + Card copyFromCard = game.getCard(((FixedTarget) getTargetPointer()).getTarget()); + if (copyFromCard != null) { + newBluePrint = new PermanentCard((Card) copyFromCard, source.getControllerId(), game); + newBluePrint.assignNewId(); + ApplyToPermanent applier = new LazavDimirMastermindApplier(); + applier.apply(game, newBluePrint); + CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, lazavDimirMastermind.getId()); + copyEffect.newId(); + copyEffect.setApplier(applier); + Ability newAbility = source.copy(); + copyEffect.init(newAbility, game); + game.addEffect(copyEffect, newAbility); + } return true; } - permanent.getPower().setValue(cardToCopy.getPower().getValue()); - permanent.getToughness().setValue(cardToCopy.getToughness().getValue()); - permanent.getColor(game).setColor(cardToCopy.getColor(game)); - permanent.getManaCost().clear(); - permanent.getManaCost().add(cardToCopy.getManaCost()); - permanent.getCardType().clear(); - for (CardType type : cardToCopy.getCardType()) { - if (!permanent.getCardType().contains(type)) { - permanent.getCardType().add(type); - } - } - permanent.getSubtype(game).clear(); - for (String type : cardToCopy.getSubtype(game)) { - if (!permanent.getSubtype(game).contains(type)) { - permanent.getSubtype(game).add(type); - } - } - permanent.getSupertype().clear(); - permanent.getSupertype().add("Legendary"); - for (String type : cardToCopy.getSupertype()) { - if (!permanent.getSupertype().contains(type)) { - permanent.getSupertype().add(type); - } - } - permanent.removeAllAbilities(source.getSourceId(), game); - permanent.addAbility(HexproofAbility.getInstance(), source.getSourceId(), game); - permanent.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility( - new LazavDimirEffect(), true, - new FilterCreatureCard("a creature card"), - TargetController.OPPONENT, SetTargetPointer.CARD), source.getSourceId(), game); + return false; + } +} - for (Ability ability : cardToCopy.getAbilities()) { - if (!permanent.getAbilities().contains(ability)) { - permanent.addAbility(ability, source.getSourceId(), game); - } - } +class LazavDimirMastermindApplier extends ApplyToPermanent { + + @Override + public Boolean apply(Game game, Permanent permanent) { + Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility( + new LazavDimirMastermindEffect(), true, + new FilterCreatureCard("a creature card"), + TargetController.OPPONENT, SetTargetPointer.CARD); + permanent.getAbilities().add(ability); + permanent.setName("Lazav, Dimir Mastermind"); + permanent.getSupertype().add("Legendary"); + permanent.getAbilities().add(HexproofAbility.getInstance()); + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility( + new LazavDimirMastermindEffect(), true, + new FilterCreatureCard("a creature card"), + TargetController.OPPONENT, SetTargetPointer.CARD); + mageObject.getAbilities().add(ability); + mageObject.setName("Lazav, Dimir Mastermind"); + mageObject.getSupertype().add("Legendary"); + mageObject.getAbilities().add(HexproofAbility.getInstance()); return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MenacingOgre.java b/Mage.Sets/src/mage/cards/m/MenacingOgre.java new file mode 100644 index 0000000000..b6543ba440 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MenacingOgre.java @@ -0,0 +1,133 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.HashMap; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public class MenacingOgre extends CardImpl { + + public MenacingOgre(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + + this.subtype.add("Ogre"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // When Menacing Ogre enters the battlefield, each player secretly chooses a number. Then those numbers are revealed. Each player with the highest number loses that much life. If you are one of those players, put two +1/+1 counters on Menacing Ogre. + this.addAbility(new EntersBattlefieldTriggeredAbility(new MenacingOgreEffect(), false)); + + } + + public MenacingOgre(final MenacingOgre card) { + super(card); + } + + @Override + public MenacingOgre copy() { + return new MenacingOgre(this); + } +} + +class MenacingOgreEffect extends OneShotEffect { + + public MenacingOgreEffect() { + super(Outcome.Detriment); + this.staticText = "each player secretly chooses a number. Then those numbers are revealed. Each player with the highest number loses that much life. If you are one of those players, put two +1/+1 counters on {this}"; + } + + public MenacingOgreEffect(final MenacingOgreEffect effect) { + super(effect); + } + + @Override + public MenacingOgreEffect copy() { + return new MenacingOgreEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int highestNumber = 0; + int number = 0; + Permanent menacingOgre = game.getPermanent(source.getSourceId()); + String message = "Choose a number."; + HashMap numberChosen = new HashMap<>(); + + //players choose numbers + for (Player player : game.getPlayers().values()) { + if (player != null) { + number = player.getAmount(0, 1000, message, game); + numberChosen.put(player, number); + } + } + //get highest number + for (Player player : numberChosen.keySet()) { + if (highestNumber < numberChosen.get(player)) { + highestNumber = numberChosen.get(player); + } + } + //reveal numbers to players and follow through with effect + for (Player player : game.getPlayers().values()) { + if (player != null) { + game.informPlayers(player.getLogName() + " chose number " + numberChosen.get(player)); + if (numberChosen.get(player) >= highestNumber) { + player.loseLife(highestNumber, game, false); + if (player.getId() == source.getControllerId() + && menacingOgre != null) { + menacingOgre.addCounters(CounterType.P1P1.createInstance(2), source, game); + } + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MistformUltimus.java b/Mage.Sets/src/mage/cards/m/MistformUltimus.java new file mode 100644 index 0000000000..6e14a3d0b8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MistformUltimus.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.keyword.ChangelingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +/** + * + * @author vereena42 + */ +public class MistformUltimus extends CardImpl { + + public MistformUltimus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.supertype.add("Legendary"); + this.subtype.add("Illusion"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Mistform Ultimus is every creature type. + this.subtype.add(ChangelingAbility.ALL_CREATURE_TYPE); // "All Creature Type" + } + + public MistformUltimus(final MistformUltimus card) { + super(card); + } + + @Override + public MistformUltimus copy() { + return new MistformUltimus(this); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NecroticOoze.java b/Mage.Sets/src/mage/cards/n/NecroticOoze.java index 3cc535023f..f27bfff6ca 100644 --- a/Mage.Sets/src/mage/cards/n/NecroticOoze.java +++ b/Mage.Sets/src/mage/cards/n/NecroticOoze.java @@ -31,12 +31,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.Effect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -119,17 +122,11 @@ public class NecroticOoze extends CardImpl { @Override public Set isDependentTo(List allEffectsInLayer) { // the dependent classes needs to be an enclosed class for dependent check of continuous effects - Set dependentTo = null; - for (ContinuousEffect effect : allEffectsInLayer) { - // http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/285211-yixlid-jailer-vs-necrotic-ooze - if (YixlidJailer.class.equals(effect.getClass().getEnclosingClass())) { - if (dependentTo == null) { - dependentTo = new HashSet<>(); - } - dependentTo.add(effect.getId()); - } - } - return dependentTo; + return allEffectsInLayer.stream() + .filter(effect -> YixlidJailer.class.equals(effect.getClass().getEnclosingClass())) + .map(Effect::getId) + .collect(Collectors.toSet()); + } } diff --git a/Mage.Sets/src/mage/cards/o/ObNixilisTheFallen.java b/Mage.Sets/src/mage/cards/o/ObNixilisTheFallen.java index 0917bd35c1..1993f06c40 100644 --- a/Mage.Sets/src/mage/cards/o/ObNixilisTheFallen.java +++ b/Mage.Sets/src/mage/cards/o/ObNixilisTheFallen.java @@ -25,19 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.o; import java.util.UUID; - -import mage.constants.CardType; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.LandfallAbility; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; import mage.counters.CounterType; import mage.target.TargetPlayer; @@ -47,21 +45,23 @@ import mage.target.TargetPlayer; */ public class ObNixilisTheFallen extends CardImpl { - public ObNixilisTheFallen (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + public ObNixilisTheFallen(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.supertype.add("Legendary"); this.subtype.add("Demon"); this.power = new MageInt(3); this.toughness = new MageInt(3); + // Landfall - Whenever a land enters the battlefield under your control, you may have target player lose 3 life. + // If you do, put three +1/+1 counters on Ob Nixilis, the Fallen. Ability ability = new LandfallAbility(new LoseLifeTargetEffect(3), true); ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3))); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } - public ObNixilisTheFallen (final ObNixilisTheFallen card) { + public ObNixilisTheFallen(final ObNixilisTheFallen card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java index 42e9a524c5..92d11254b4 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTyranny.java @@ -52,8 +52,7 @@ import mage.target.targetpointer.FixedTarget; public class PhyrexianTyranny extends CardImpl { public PhyrexianTyranny(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}{B}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{B}{R}"); // Whenever a player draws a card, that player loses 2 life unless he or she pays {2}. this.addAbility(new PhyrexianTyrannyTriggeredAbility()); @@ -70,15 +69,15 @@ public class PhyrexianTyranny extends CardImpl { } class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl { - + PhyrexianTyrannyTriggeredAbility() { super(Zone.BATTLEFIELD, new PhyrexianTyrannyEffect(), false); } - + PhyrexianTyrannyTriggeredAbility(final PhyrexianTyrannyTriggeredAbility ability) { super(ability); } - + @Override public PhyrexianTyrannyTriggeredAbility copy() { return new PhyrexianTyrannyTriggeredAbility(this); @@ -88,7 +87,7 @@ class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == EventType.DREW_CARD; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { for (Effect effect : this.getEffects()) { @@ -98,7 +97,7 @@ class PhyrexianTyrannyTriggeredAbility extends TriggeredAbilityImpl { } return true; } - + @Override public String getRule() { return "Whenever a player draws a card, that player loses 2 life unless he or she pays {2}"; @@ -127,7 +126,7 @@ class PhyrexianTyrannyEffect extends OneShotEffect { if (player != null) { Cost cost = new GenericManaCost(2); if (!cost.pay(source, game, player.getId(), player.getId(), false, null)) { - player.damage(2, source.getSourceId(), game, false, true); + player.loseLife(2, game, false); } return true; } diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java index ab98fecde2..1daaa1699a 100644 --- a/Mage.Sets/src/mage/sets/Homelands.java +++ b/Mage.Sets/src/mage/sets/Homelands.java @@ -96,7 +96,6 @@ public class Homelands extends ExpansionSet { cards.add(new SetCardInfo("Clockwork Gnomes", 127, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class)); cards.add(new SetCardInfo("Coral Reef", 29, Rarity.COMMON, mage.cards.c.CoralReef.class)); cards.add(new SetCardInfo("Dark Maze", 31, Rarity.COMMON, mage.cards.d.DarkMaze.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Dark Maze", 31, Rarity.COMMON, mage.cards.d.DarkMaze.class, new CardGraphicInfo(null, true))); cards.add(new SetCardInfo("Death Speakers", 109, Rarity.UNCOMMON, mage.cards.d.DeathSpeakers.class)); cards.add(new SetCardInfo("Didgeridoo", 130, Rarity.RARE, mage.cards.d.Didgeridoo.class)); cards.add(new SetCardInfo("Drudge Spell", 6, Rarity.UNCOMMON, mage.cards.d.DrudgeSpell.class)); diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index 7f71a2612f..aad668e264 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -127,6 +127,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Magma Sliver", 107, Rarity.RARE, mage.cards.m.MagmaSliver.class)); cards.add(new SetCardInfo("Merchant of Secrets", 44, Rarity.COMMON, mage.cards.m.MerchantOfSecrets.class)); cards.add(new SetCardInfo("Mistform Sliver", 46, Rarity.COMMON, mage.cards.m.MistformSliver.class)); + cards.add(new SetCardInfo("Mistform Ultimus", 47, Rarity.RARE, mage.cards.m.MistformUltimus.class)); cards.add(new SetCardInfo("Nantuko Vigilante", 132, Rarity.COMMON, mage.cards.n.NantukoVigilante.class)); cards.add(new SetCardInfo("Needleshot Gourna", 133, Rarity.COMMON, mage.cards.n.NeedleshotGourna.class)); cards.add(new SetCardInfo("Noxious Ghoul", 77, Rarity.UNCOMMON, mage.cards.n.NoxiousGhoul.class)); diff --git a/Mage.Sets/src/mage/sets/MastersEditionIV.java b/Mage.Sets/src/mage/sets/MastersEditionIV.java index ed9a0246d7..73ac2e4dd7 100644 --- a/Mage.Sets/src/mage/sets/MastersEditionIV.java +++ b/Mage.Sets/src/mage/sets/MastersEditionIV.java @@ -216,10 +216,9 @@ public class MastersEditionIV extends ExpansionSet { cards.add(new SetCardInfo("Regrowth", 163, Rarity.RARE, mage.cards.r.Regrowth.class)); cards.add(new SetCardInfo("Righteous Charge", 23, Rarity.COMMON, mage.cards.r.RighteousCharge.class)); cards.add(new SetCardInfo("Ring of Renewal", 224, Rarity.RARE, mage.cards.r.RingOfRenewal.class)); - cards.add(new SetCardInfo("Rock Hydra", 133, Rarity.RARE, mage.cards.r.RockHydra.class)); - cards.add(new SetCardInfo("Rockslide Ambush", 134, Rarity.COMMON, mage.cards.r.RockslideAmbush.class)); cards.add(new SetCardInfo("Roc of Kher Ridges", 132, Rarity.UNCOMMON, mage.cards.r.RocOfKherRidges.class)); cards.add(new SetCardInfo("Rock Hydra", 133, Rarity.RARE, mage.cards.r.RockHydra.class)); + cards.add(new SetCardInfo("Rockslide Ambush", 134, Rarity.COMMON, mage.cards.r.RockslideAmbush.class)); cards.add(new SetCardInfo("Sandstorm", 164, Rarity.COMMON, mage.cards.s.Sandstorm.class)); cards.add(new SetCardInfo("Savannah", 250, Rarity.RARE, mage.cards.s.Savannah.class)); cards.add(new SetCardInfo("Savannah Lions", 24, Rarity.UNCOMMON, mage.cards.s.SavannahLions.class)); diff --git a/Mage.Sets/src/mage/sets/Onslaught.java b/Mage.Sets/src/mage/sets/Onslaught.java index ae643c0696..bbcb3f43eb 100644 --- a/Mage.Sets/src/mage/sets/Onslaught.java +++ b/Mage.Sets/src/mage/sets/Onslaught.java @@ -55,7 +55,6 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Blistering Firecat", 189, Rarity.RARE, mage.cards.b.BlisteringFirecat.class)); cards.add(new SetCardInfo("Bloodline Shaman", 249, Rarity.UNCOMMON, mage.cards.b.BloodlineShaman.class)); cards.add(new SetCardInfo("Bloodstained Mire", 313, Rarity.RARE, mage.cards.b.BloodstainedMire.class, new CardGraphicInfo(new ObjectColor("RB"), null,false))); - cards.add(new SetCardInfo("Bloodline Shaman", 249, Rarity.UNCOMMON, mage.cards.b.BloodlineShaman.class)); cards.add(new SetCardInfo("Boneknitter", 128, Rarity.UNCOMMON, mage.cards.b.Boneknitter.class)); cards.add(new SetCardInfo("Brightstone Ritual", 191, Rarity.COMMON, mage.cards.b.BrightstoneRitual.class)); cards.add(new SetCardInfo("Broodhatch Nantuko", 250, Rarity.UNCOMMON, mage.cards.b.BroodhatchNantuko.class)); @@ -182,6 +181,7 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Lonely Sandbar", 320, Rarity.COMMON, mage.cards.l.LonelySandbar.class)); cards.add(new SetCardInfo("Mage's Guile", 91, Rarity.COMMON, mage.cards.m.MagesGuile.class)); cards.add(new SetCardInfo("Mana Echoes", 218, Rarity.RARE, mage.cards.m.ManaEchoes.class)); + cards.add(new SetCardInfo("Menacing Ogre", 219, Rarity.RARE, mage.cards.m.MenacingOgre.class)); cards.add(new SetCardInfo("Misery Charm", 158, Rarity.COMMON, mage.cards.m.MiseryCharm.class)); cards.add(new SetCardInfo("Mistform Mutant", 95, Rarity.UNCOMMON, mage.cards.m.MistformMutant.class)); cards.add(new SetCardInfo("Mobilization", 44, Rarity.RARE, mage.cards.m.Mobilization.class)); @@ -303,18 +303,12 @@ public class Onslaught extends ExpansionSet { cards.add(new SetCardInfo("Wheel and Deal", 121, Rarity.RARE, mage.cards.w.WheelAndDeal.class)); cards.add(new SetCardInfo("Whipcorder", 60, Rarity.UNCOMMON, mage.cards.w.Whipcorder.class)); cards.add(new SetCardInfo("Windswept Heath", 328, Rarity.RARE, mage.cards.w.WindsweptHeath.class, new CardGraphicInfo(new ObjectColor("GW"), null, false))); - cards.add(new SetCardInfo("Bloodline Shaman", 249, Rarity.UNCOMMON, mage.cards.b.BloodlineShaman.class)); - cards.add(new SetCardInfo("Trade Secrets", 118, Rarity.RARE, mage.cards.t.TradeSecrets.class)); - cards.add(new SetCardInfo("Venomspout Brackus", 295, Rarity.UNCOMMON, mage.cards.v.VenomspoutBrackus.class)); cards.add(new SetCardInfo("Wirewood Elf", 301, Rarity.COMMON, mage.cards.w.WirewoodElf.class)); cards.add(new SetCardInfo("Wirewood Herald", 302, Rarity.COMMON, mage.cards.w.WirewoodHerald.class)); cards.add(new SetCardInfo("Wirewood Lodge", 329, Rarity.RARE, mage.cards.w.WirewoodLodge.class)); cards.add(new SetCardInfo("Wirewood Pride", 303, Rarity.COMMON, mage.cards.w.WirewoodPride.class)); cards.add(new SetCardInfo("Wirewood Savage", 304, Rarity.COMMON, mage.cards.w.WirewoodSavage.class)); cards.add(new SetCardInfo("Wooded Foothills", 330, Rarity.RARE, mage.cards.w.WoodedFoothills.class, new CardGraphicInfo(new ObjectColor("RG"), null, false))); - cards.add(new SetCardInfo("Bloodline Shaman", 249, Rarity.UNCOMMON, mage.cards.b.BloodlineShaman.class)); - cards.add(new SetCardInfo("Trade Secrets", 118, Rarity.RARE, mage.cards.t.TradeSecrets.class)); - cards.add(new SetCardInfo("Venomspout Brackus", 295, Rarity.UNCOMMON, mage.cards.v.VenomspoutBrackus.class)); cards.add(new SetCardInfo("Words of War", 244, Rarity.RARE, mage.cards.w.WordsOfWar.class)); cards.add(new SetCardInfo("Words of Wind", 122, Rarity.RARE, mage.cards.w.WordsOfWind.class)); cards.add(new SetCardInfo("Words of Worship", 61, Rarity.RARE, mage.cards.w.WordsOfWorship.class)); diff --git a/Mage.Sets/src/mage/sets/Planechase.java b/Mage.Sets/src/mage/sets/Planechase.java index 4073fda9ee..3b67d5da14 100644 --- a/Mage.Sets/src/mage/sets/Planechase.java +++ b/Mage.Sets/src/mage/sets/Planechase.java @@ -1,219 +1,220 @@ -/* -* 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; - -import mage.constants.SetType; -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.cards.CardGraphicInfo; - -/** - * - * @author BetaSteward_at_googlemail.com - */ -public class Planechase extends ExpansionSet { - - private static final Planechase fINSTANCE = new Planechase(); - - public static Planechase getInstance() { - return fINSTANCE; - } - - private Planechase() { - super("Planechase", "HOP", ExpansionSet.buildDate(2009, 8, 4), SetType.SUPPLEMENTAL); - this.blockName = "Command Zone"; - cards.add(new SetCardInfo("Akroma's Vengeance", 1, Rarity.RARE, mage.cards.a.AkromasVengeance.class)); - cards.add(new SetCardInfo("Ancient Den", 130, Rarity.COMMON, mage.cards.a.AncientDen.class)); - cards.add(new SetCardInfo("Arcbound Crusher", 105, Rarity.UNCOMMON, mage.cards.a.ArcboundCrusher.class)); - cards.add(new SetCardInfo("Arcbound Slith", 106, Rarity.UNCOMMON, mage.cards.a.ArcboundSlith.class)); - cards.add(new SetCardInfo("Arc Lightning", 46, Rarity.COMMON, mage.cards.a.ArcLightning.class)); - cards.add(new SetCardInfo("Arsenal Thresher", 96, Rarity.COMMON, mage.cards.a.ArsenalThresher.class)); - cards.add(new SetCardInfo("Ascendant Evincar", 17, Rarity.RARE, mage.cards.a.AscendantEvincar.class)); - cards.add(new SetCardInfo("Balefire Liege", 97, Rarity.RARE, mage.cards.b.BalefireLiege.class)); - cards.add(new SetCardInfo("Battlegate Mimic", 98, Rarity.COMMON, mage.cards.b.BattlegateMimic.class)); - cards.add(new SetCardInfo("Beacon of Unrest", 18, Rarity.RARE, mage.cards.b.BeaconOfUnrest.class)); - cards.add(new SetCardInfo("Beast Hunt", 68, Rarity.COMMON, mage.cards.b.BeastHunt.class)); - cards.add(new SetCardInfo("Beseech the Queen", 19, Rarity.UNCOMMON, mage.cards.b.BeseechTheQueen.class)); - cards.add(new SetCardInfo("Blaze", 47, Rarity.UNCOMMON, mage.cards.b.Blaze.class)); - cards.add(new SetCardInfo("Bogardan Firefiend", 48, Rarity.COMMON, mage.cards.b.BogardanFirefiend.class)); - cards.add(new SetCardInfo("Bogardan Rager", 49, Rarity.COMMON, mage.cards.b.BogardanRager.class)); - cards.add(new SetCardInfo("Boros Garrison", 131, Rarity.COMMON, mage.cards.b.BorosGarrison.class)); - cards.add(new SetCardInfo("Boros Guildmage", 99, Rarity.UNCOMMON, mage.cards.b.BorosGuildmage.class)); - cards.add(new SetCardInfo("Boros Signet", 107, Rarity.COMMON, mage.cards.b.BorosSignet.class)); - cards.add(new SetCardInfo("Boros Swiftblade", 82, Rarity.UNCOMMON, mage.cards.b.BorosSwiftblade.class)); - cards.add(new SetCardInfo("Bosh, Iron Golem", 108, Rarity.RARE, mage.cards.b.BoshIronGolem.class)); - cards.add(new SetCardInfo("Branching Bolt", 83, Rarity.COMMON, mage.cards.b.BranchingBolt.class)); - cards.add(new SetCardInfo("Briarhorn", 69, Rarity.UNCOMMON, mage.cards.b.Briarhorn.class)); - cards.add(new SetCardInfo("Broodstar", 8, Rarity.RARE, mage.cards.b.Broodstar.class)); - cards.add(new SetCardInfo("Browbeat", 50, Rarity.UNCOMMON, mage.cards.b.Browbeat.class)); - cards.add(new SetCardInfo("Bull Cerodon", 84, Rarity.UNCOMMON, mage.cards.b.BullCerodon.class)); - cards.add(new SetCardInfo("Cabal Coffers", 132, Rarity.UNCOMMON, mage.cards.c.CabalCoffers.class)); - cards.add(new SetCardInfo("Cadaverous Knight", 20, Rarity.COMMON, mage.cards.c.CadaverousKnight.class)); - cards.add(new SetCardInfo("Cerodon Yearling", 86, Rarity.COMMON, mage.cards.c.CerodonYearling.class)); - cards.add(new SetCardInfo("Cinder Elemental", 51, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class)); - cards.add(new SetCardInfo("Cone of Flame", 52, Rarity.UNCOMMON, mage.cards.c.ConeOfFlame.class)); - cards.add(new SetCardInfo("Congregate", 2, Rarity.COMMON, mage.cards.c.Congregate.class)); - cards.add(new SetCardInfo("Consume Spirit", 21, Rarity.UNCOMMON, mage.cards.c.ConsumeSpirit.class)); - cards.add(new SetCardInfo("Copper Myr", 109, Rarity.COMMON, mage.cards.c.CopperMyr.class)); - cards.add(new SetCardInfo("Corpse Harvester", 22, Rarity.UNCOMMON, mage.cards.c.CorpseHarvester.class)); - cards.add(new SetCardInfo("Cranial Plating", 110, Rarity.COMMON, mage.cards.c.CranialPlating.class)); - cards.add(new SetCardInfo("Cruel Revival", 23, Rarity.COMMON, mage.cards.c.CruelRevival.class)); - cards.add(new SetCardInfo("Dark Ritual", 24, Rarity.COMMON, mage.cards.d.DarkRitual.class)); - cards.add(new SetCardInfo("Darksteel Forge", 111, Rarity.RARE, mage.cards.d.DarksteelForge.class)); - cards.add(new SetCardInfo("Death Baron", 25, Rarity.RARE, mage.cards.d.DeathBaron.class)); - cards.add(new SetCardInfo("Door to Nothingness", 112, Rarity.RARE, mage.cards.d.DoorToNothingness.class)); - cards.add(new SetCardInfo("Double Cleave", 100, Rarity.COMMON, mage.cards.d.DoubleCleave.class)); - cards.add(new SetCardInfo("Dregscape Zombie", 26, Rarity.COMMON, mage.cards.d.DregscapeZombie.class)); - cards.add(new SetCardInfo("Duergar Hedge-Mage", 101, Rarity.UNCOMMON, mage.cards.d.DuergarHedgeMage.class)); - cards.add(new SetCardInfo("Etched Oracle", 113, Rarity.UNCOMMON, mage.cards.e.EtchedOracle.class)); - cards.add(new SetCardInfo("Explosive Vegetation", 70, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); - cards.add(new SetCardInfo("Fabricate", 9, Rarity.UNCOMMON, mage.cards.f.Fabricate.class)); - cards.add(new SetCardInfo("Fertile Ground", 71, Rarity.COMMON, mage.cards.f.FertileGround.class)); - cards.add(new SetCardInfo("Fertilid", 72, Rarity.COMMON, mage.cards.f.Fertilid.class)); - cards.add(new SetCardInfo("Festering Goblin", 27, Rarity.COMMON, mage.cards.f.FesteringGoblin.class)); - cards.add(new SetCardInfo("Fires of Yavimaya", 87, Rarity.UNCOMMON, mage.cards.f.FiresOfYavimaya.class)); - cards.add(new SetCardInfo("Flamekin Harbinger", 53, Rarity.UNCOMMON, mage.cards.f.FlamekinHarbinger.class)); - cards.add(new SetCardInfo("Flametongue Kavu", 54, Rarity.UNCOMMON, mage.cards.f.FlametongueKavu.class)); - cards.add(new SetCardInfo("Forest", 165, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 166, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 167, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 168, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 169, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forgotten Ancient", 73, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); - cards.add(new SetCardInfo("Furnace of Rath", 55, Rarity.RARE, mage.cards.f.FurnaceOfRath.class)); - cards.add(new SetCardInfo("Glory of Warfare", 88, Rarity.RARE, mage.cards.g.GloryOfWarfare.class)); - cards.add(new SetCardInfo("Goblin Offensive", 56, Rarity.UNCOMMON, mage.cards.g.GoblinOffensive.class)); - cards.add(new SetCardInfo("Gold Myr", 114, Rarity.COMMON, mage.cards.g.GoldMyr.class)); - cards.add(new SetCardInfo("Gravedigger", 29, Rarity.COMMON, mage.cards.g.Gravedigger.class)); - cards.add(new SetCardInfo("Grave Pact", 28, Rarity.RARE, mage.cards.g.GravePact.class)); - cards.add(new SetCardInfo("Great Furnace", 133, Rarity.COMMON, mage.cards.g.GreatFurnace.class)); - cards.add(new SetCardInfo("Gruul Turf", 134, Rarity.COMMON, mage.cards.g.GruulTurf.class)); - cards.add(new SetCardInfo("Hearthfire Hobgoblin", 102, Rarity.UNCOMMON, mage.cards.h.HearthfireHobgoblin.class)); - cards.add(new SetCardInfo("Helldozer", 30, Rarity.RARE, mage.cards.h.Helldozer.class)); - cards.add(new SetCardInfo("Hideous End", 31, Rarity.COMMON, mage.cards.h.HideousEnd.class)); - cards.add(new SetCardInfo("Hull Breach", 89, Rarity.COMMON, mage.cards.h.HullBreach.class)); - cards.add(new SetCardInfo("Incremental Blight", 32, Rarity.UNCOMMON, mage.cards.i.IncrementalBlight.class)); - cards.add(new SetCardInfo("Innocent Blood", 33, Rarity.COMMON, mage.cards.i.InnocentBlood.class)); - cards.add(new SetCardInfo("Insurrection", 57, Rarity.RARE, mage.cards.i.Insurrection.class)); - cards.add(new SetCardInfo("Iron Myr", 115, Rarity.COMMON, mage.cards.i.IronMyr.class)); - cards.add(new SetCardInfo("Island", 147, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 148, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 149, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 150, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Ivy Elemental", 74, Rarity.RARE, mage.cards.i.IvyElemental.class)); - cards.add(new SetCardInfo("Keep Watch", 10, Rarity.COMMON, mage.cards.k.KeepWatch.class)); - cards.add(new SetCardInfo("Keldon Champion", 58, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); - cards.add(new SetCardInfo("Kor Sanctifiers", 3, Rarity.COMMON, mage.cards.k.KorSanctifiers.class)); - cards.add(new SetCardInfo("Leaden Myr", 116, Rarity.COMMON, mage.cards.l.LeadenMyr.class)); - cards.add(new SetCardInfo("Leechridden Swamp", 135, Rarity.UNCOMMON, mage.cards.l.LeechriddenSwamp.class)); - cards.add(new SetCardInfo("Lightning Helix", 90, Rarity.UNCOMMON, mage.cards.l.LightningHelix.class)); - cards.add(new SetCardInfo("Living Hive", 75, Rarity.RARE, mage.cards.l.LivingHive.class)); - cards.add(new SetCardInfo("Lodestone Myr", 117, Rarity.RARE, mage.cards.l.LodestoneMyr.class)); - cards.add(new SetCardInfo("Loxodon Warhammer", 118, Rarity.RARE, mage.cards.l.LoxodonWarhammer.class)); - cards.add(new SetCardInfo("Mage Slayer", 91, Rarity.UNCOMMON, mage.cards.m.MageSlayer.class)); - cards.add(new SetCardInfo("Mask of Memory", 119, Rarity.UNCOMMON, mage.cards.m.MaskOfMemory.class)); - cards.add(new SetCardInfo("Master of Etherium", 11, Rarity.RARE, mage.cards.m.MasterOfEtherium.class)); - cards.add(new SetCardInfo("Mountain", 156, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 157, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 158, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 159, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 160, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 161, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 162, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 163, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 164, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Myr Enforcer", 120, Rarity.COMMON, mage.cards.m.MyrEnforcer.class)); - cards.add(new SetCardInfo("Nefashu", 34, Rarity.RARE, mage.cards.n.Nefashu.class)); - cards.add(new SetCardInfo("Noxious Ghoul", 35, Rarity.UNCOMMON, mage.cards.n.NoxiousGhoul.class)); - cards.add(new SetCardInfo("Nuisance Engine", 121, Rarity.UNCOMMON, mage.cards.n.NuisanceEngine.class)); - cards.add(new SetCardInfo("Oblivion Ring", 4, Rarity.COMMON, mage.cards.o.OblivionRing.class)); - cards.add(new SetCardInfo("Order // Chaos", 104, Rarity.UNCOMMON, mage.cards.o.OrderChaos.class)); - cards.add(new SetCardInfo("Orim's Thunder", 5, Rarity.COMMON, mage.cards.o.OrimsThunder.class)); - cards.add(new SetCardInfo("Pentad Prism", 122, Rarity.COMMON, mage.cards.p.PentadPrism.class)); - cards.add(new SetCardInfo("Pentavus", 123, Rarity.RARE, mage.cards.p.Pentavus.class)); - cards.add(new SetCardInfo("Phyrexian Arena", 36, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); - cards.add(new SetCardInfo("Phyrexian Ghoul", 37, Rarity.COMMON, mage.cards.p.PhyrexianGhoul.class)); - cards.add(new SetCardInfo("Plains", 142, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 143, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 144, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 145, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 146, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Prison Term", 6, Rarity.UNCOMMON, mage.cards.p.PrisonTerm.class)); - cards.add(new SetCardInfo("Profane Command", 38, Rarity.RARE, mage.cards.p.ProfaneCommand.class)); - cards.add(new SetCardInfo("Pyrotechnics", 60, Rarity.UNCOMMON, mage.cards.p.Pyrotechnics.class)); - cards.add(new SetCardInfo("Qumulox", 12, Rarity.UNCOMMON, mage.cards.q.Qumulox.class)); - cards.add(new SetCardInfo("Rampant Growth", 76, Rarity.COMMON, mage.cards.r.RampantGrowth.class)); - cards.add(new SetCardInfo("Razia, Boros Archangel", 92, Rarity.RARE, mage.cards.r.RaziaBorosArchangel.class)); - cards.add(new SetCardInfo("Reckless Charge", 61, Rarity.COMMON, mage.cards.r.RecklessCharge.class)); - cards.add(new SetCardInfo("Relentless Assault", 62, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); - cards.add(new SetCardInfo("Relic of Progenitus", 124, Rarity.COMMON, mage.cards.r.RelicOfProgenitus.class)); - cards.add(new SetCardInfo("Rockslide Elemental", 63, Rarity.UNCOMMON, mage.cards.r.RockslideElemental.class)); - cards.add(new SetCardInfo("Rolling Thunder", 64, Rarity.COMMON, mage.cards.r.RollingThunder.class)); - cards.add(new SetCardInfo("Rorix Bladewing", 65, Rarity.RARE, mage.cards.r.RorixBladewing.class)); - cards.add(new SetCardInfo("Rotting Rats", 39, Rarity.COMMON, mage.cards.r.RottingRats.class)); - cards.add(new SetCardInfo("Rumbling Slum", 93, Rarity.RARE, mage.cards.r.RumblingSlum.class)); - cards.add(new SetCardInfo("Sarcomite Myr", 13, Rarity.COMMON, mage.cards.s.SarcomiteMyr.class)); - cards.add(new SetCardInfo("Savage Twister", 94, Rarity.UNCOMMON, mage.cards.s.SavageTwister.class)); - cards.add(new SetCardInfo("Search for Tomorrow", 77, Rarity.COMMON, mage.cards.s.SearchForTomorrow.class)); - cards.add(new SetCardInfo("Seat of the Synod", 136, Rarity.COMMON, mage.cards.s.SeatOfTheSynod.class)); - cards.add(new SetCardInfo("Serum Tank", 125, Rarity.UNCOMMON, mage.cards.s.SerumTank.class)); - cards.add(new SetCardInfo("Shepherd of Rot", 40, Rarity.COMMON, mage.cards.s.ShepherdOfRot.class)); - cards.add(new SetCardInfo("Shivan Oasis", 137, Rarity.UNCOMMON, mage.cards.s.ShivanOasis.class)); - cards.add(new SetCardInfo("Silverglade Elemental", 78, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class)); - cards.add(new SetCardInfo("Silver Myr", 126, Rarity.COMMON, mage.cards.s.SilverMyr.class)); - cards.add(new SetCardInfo("Skeleton Shard", 127, Rarity.UNCOMMON, mage.cards.s.SkeletonShard.class)); - cards.add(new SetCardInfo("Sludge Strider", 95, Rarity.UNCOMMON, mage.cards.s.SludgeStrider.class)); - cards.add(new SetCardInfo("Smokebraider", 66, Rarity.COMMON, mage.cards.s.Smokebraider.class)); - cards.add(new SetCardInfo("Soulless One", 41, Rarity.UNCOMMON, mage.cards.s.SoullessOne.class)); - cards.add(new SetCardInfo("Soul Warden", 7, Rarity.COMMON, mage.cards.s.SoulWarden.class)); - cards.add(new SetCardInfo("Sunhome, Fortress of the Legion", 138, Rarity.UNCOMMON, mage.cards.s.SunhomeFortressOfTheLegion.class)); - cards.add(new SetCardInfo("Suntouched Myr", 128, Rarity.COMMON, mage.cards.s.SuntouchedMyr.class)); - cards.add(new SetCardInfo("Swamp", 151, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 152, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 153, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 154, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 155, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Syphon Mind", 42, Rarity.COMMON, mage.cards.s.SyphonMind.class)); - cards.add(new SetCardInfo("Syphon Soul", 43, Rarity.COMMON, mage.cards.s.SyphonSoul.class)); - cards.add(new SetCardInfo("Taurean Mauler", 67, Rarity.RARE, mage.cards.t.TaureanMauler.class)); - cards.add(new SetCardInfo("Terramorphic Expanse", 139, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); - cards.add(new SetCardInfo("Thirst for Knowledge", 14, Rarity.UNCOMMON, mage.cards.t.ThirstForKnowledge.class)); - cards.add(new SetCardInfo("Tornado Elemental", 79, Rarity.RARE, mage.cards.t.TornadoElemental.class)); - cards.add(new SetCardInfo("Tree of Tales", 140, Rarity.COMMON, mage.cards.t.TreeOfTales.class)); - cards.add(new SetCardInfo("Tribal Unity", 80, Rarity.UNCOMMON, mage.cards.t.TribalUnity.class)); - cards.add(new SetCardInfo("Undead Warchief", 44, Rarity.UNCOMMON, mage.cards.u.UndeadWarchief.class)); - cards.add(new SetCardInfo("Vault of Whispers", 141, Rarity.COMMON, mage.cards.v.VaultOfWhispers.class)); - cards.add(new SetCardInfo("Vedalken Engineer", 15, Rarity.COMMON, mage.cards.v.VedalkenEngineer.class)); - cards.add(new SetCardInfo("Verdant Force", 81, Rarity.RARE, mage.cards.v.VerdantForce.class)); - cards.add(new SetCardInfo("Whiplash Trap", 16, Rarity.COMMON, mage.cards.w.WhiplashTrap.class)); - cards.add(new SetCardInfo("Withered Wretch", 45, Rarity.UNCOMMON, mage.cards.w.WitheredWretch.class)); - cards.add(new SetCardInfo("Wizard Replica", 129, Rarity.COMMON, mage.cards.w.WizardReplica.class)); - } - -} +/* +* 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; + +import mage.constants.SetType; +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.cards.CardGraphicInfo; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class Planechase extends ExpansionSet { + + private static final Planechase fINSTANCE = new Planechase(); + + public static Planechase getInstance() { + return fINSTANCE; + } + + private Planechase() { + super("Planechase", "HOP", ExpansionSet.buildDate(2009, 8, 4), SetType.SUPPLEMENTAL); + this.blockName = "Command Zone"; + cards.add(new SetCardInfo("Akroma's Vengeance", 1, Rarity.RARE, mage.cards.a.AkromasVengeance.class)); + cards.add(new SetCardInfo("Ancient Den", 130, Rarity.COMMON, mage.cards.a.AncientDen.class)); + cards.add(new SetCardInfo("Arcbound Crusher", 105, Rarity.UNCOMMON, mage.cards.a.ArcboundCrusher.class)); + cards.add(new SetCardInfo("Arcbound Slith", 106, Rarity.UNCOMMON, mage.cards.a.ArcboundSlith.class)); + cards.add(new SetCardInfo("Arc Lightning", 46, Rarity.COMMON, mage.cards.a.ArcLightning.class)); + cards.add(new SetCardInfo("Arsenal Thresher", 96, Rarity.COMMON, mage.cards.a.ArsenalThresher.class)); + cards.add(new SetCardInfo("Ascendant Evincar", 17, Rarity.RARE, mage.cards.a.AscendantEvincar.class)); + cards.add(new SetCardInfo("Balefire Liege", 97, Rarity.RARE, mage.cards.b.BalefireLiege.class)); + cards.add(new SetCardInfo("Battlegate Mimic", 98, Rarity.COMMON, mage.cards.b.BattlegateMimic.class)); + cards.add(new SetCardInfo("Beacon of Unrest", 18, Rarity.RARE, mage.cards.b.BeaconOfUnrest.class)); + cards.add(new SetCardInfo("Beast Hunt", 68, Rarity.COMMON, mage.cards.b.BeastHunt.class)); + cards.add(new SetCardInfo("Beseech the Queen", 19, Rarity.UNCOMMON, mage.cards.b.BeseechTheQueen.class)); + cards.add(new SetCardInfo("Blaze", 47, Rarity.UNCOMMON, mage.cards.b.Blaze.class)); + cards.add(new SetCardInfo("Bogardan Firefiend", 48, Rarity.COMMON, mage.cards.b.BogardanFirefiend.class)); + cards.add(new SetCardInfo("Bogardan Rager", 49, Rarity.COMMON, mage.cards.b.BogardanRager.class)); + cards.add(new SetCardInfo("Boros Garrison", 131, Rarity.COMMON, mage.cards.b.BorosGarrison.class)); + cards.add(new SetCardInfo("Boros Guildmage", 99, Rarity.UNCOMMON, mage.cards.b.BorosGuildmage.class)); + cards.add(new SetCardInfo("Boros Signet", 107, Rarity.COMMON, mage.cards.b.BorosSignet.class)); + cards.add(new SetCardInfo("Boros Swiftblade", 82, Rarity.UNCOMMON, mage.cards.b.BorosSwiftblade.class)); + cards.add(new SetCardInfo("Bosh, Iron Golem", 108, Rarity.RARE, mage.cards.b.BoshIronGolem.class)); + cards.add(new SetCardInfo("Branching Bolt", 83, Rarity.COMMON, mage.cards.b.BranchingBolt.class)); + cards.add(new SetCardInfo("Briarhorn", 69, Rarity.UNCOMMON, mage.cards.b.Briarhorn.class)); + cards.add(new SetCardInfo("Broodstar", 8, Rarity.RARE, mage.cards.b.Broodstar.class)); + cards.add(new SetCardInfo("Browbeat", 50, Rarity.UNCOMMON, mage.cards.b.Browbeat.class)); + cards.add(new SetCardInfo("Bull Cerodon", 84, Rarity.UNCOMMON, mage.cards.b.BullCerodon.class)); + cards.add(new SetCardInfo("Cabal Coffers", 132, Rarity.UNCOMMON, mage.cards.c.CabalCoffers.class)); + cards.add(new SetCardInfo("Cadaverous Knight", 20, Rarity.COMMON, mage.cards.c.CadaverousKnight.class)); + cards.add(new SetCardInfo("Cerodon Yearling", 86, Rarity.COMMON, mage.cards.c.CerodonYearling.class)); + cards.add(new SetCardInfo("Cinder Elemental", 51, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class)); + cards.add(new SetCardInfo("Cone of Flame", 52, Rarity.UNCOMMON, mage.cards.c.ConeOfFlame.class)); + cards.add(new SetCardInfo("Congregate", 2, Rarity.COMMON, mage.cards.c.Congregate.class)); + cards.add(new SetCardInfo("Consume Spirit", 21, Rarity.UNCOMMON, mage.cards.c.ConsumeSpirit.class)); + cards.add(new SetCardInfo("Copper Myr", 109, Rarity.COMMON, mage.cards.c.CopperMyr.class)); + cards.add(new SetCardInfo("Corpse Harvester", 22, Rarity.UNCOMMON, mage.cards.c.CorpseHarvester.class)); + cards.add(new SetCardInfo("Cranial Plating", 110, Rarity.COMMON, mage.cards.c.CranialPlating.class)); + cards.add(new SetCardInfo("Cruel Revival", 23, Rarity.COMMON, mage.cards.c.CruelRevival.class)); + cards.add(new SetCardInfo("Dark Ritual", 24, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Darksteel Forge", 111, Rarity.RARE, mage.cards.d.DarksteelForge.class)); + cards.add(new SetCardInfo("Death Baron", 25, Rarity.RARE, mage.cards.d.DeathBaron.class)); + cards.add(new SetCardInfo("Door to Nothingness", 112, Rarity.RARE, mage.cards.d.DoorToNothingness.class)); + cards.add(new SetCardInfo("Double Cleave", 100, Rarity.COMMON, mage.cards.d.DoubleCleave.class)); + cards.add(new SetCardInfo("Dregscape Zombie", 26, Rarity.COMMON, mage.cards.d.DregscapeZombie.class)); + cards.add(new SetCardInfo("Duergar Hedge-Mage", 101, Rarity.UNCOMMON, mage.cards.d.DuergarHedgeMage.class)); + cards.add(new SetCardInfo("Etched Oracle", 113, Rarity.UNCOMMON, mage.cards.e.EtchedOracle.class)); + cards.add(new SetCardInfo("Explosive Vegetation", 70, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); + cards.add(new SetCardInfo("Fabricate", 9, Rarity.UNCOMMON, mage.cards.f.Fabricate.class)); + cards.add(new SetCardInfo("Fertile Ground", 71, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Fertilid", 72, Rarity.COMMON, mage.cards.f.Fertilid.class)); + cards.add(new SetCardInfo("Festering Goblin", 27, Rarity.COMMON, mage.cards.f.FesteringGoblin.class)); + cards.add(new SetCardInfo("Fires of Yavimaya", 87, Rarity.UNCOMMON, mage.cards.f.FiresOfYavimaya.class)); + cards.add(new SetCardInfo("Flamekin Harbinger", 53, Rarity.UNCOMMON, mage.cards.f.FlamekinHarbinger.class)); + cards.add(new SetCardInfo("Flametongue Kavu", 54, Rarity.UNCOMMON, mage.cards.f.FlametongueKavu.class)); + cards.add(new SetCardInfo("Forest", 165, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 166, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 167, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 168, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 169, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forgotten Ancient", 73, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); + cards.add(new SetCardInfo("Furnace of Rath", 55, Rarity.RARE, mage.cards.f.FurnaceOfRath.class)); + cards.add(new SetCardInfo("Glory of Warfare", 88, Rarity.RARE, mage.cards.g.GloryOfWarfare.class)); + cards.add(new SetCardInfo("Goblin Offensive", 56, Rarity.UNCOMMON, mage.cards.g.GoblinOffensive.class)); + cards.add(new SetCardInfo("Gold Myr", 114, Rarity.COMMON, mage.cards.g.GoldMyr.class)); + cards.add(new SetCardInfo("Gravedigger", 29, Rarity.COMMON, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Grave Pact", 28, Rarity.RARE, mage.cards.g.GravePact.class)); + cards.add(new SetCardInfo("Great Furnace", 133, Rarity.COMMON, mage.cards.g.GreatFurnace.class)); + cards.add(new SetCardInfo("Gruul Turf", 134, Rarity.COMMON, mage.cards.g.GruulTurf.class)); + cards.add(new SetCardInfo("Hearthfire Hobgoblin", 102, Rarity.UNCOMMON, mage.cards.h.HearthfireHobgoblin.class)); + cards.add(new SetCardInfo("Helldozer", 30, Rarity.RARE, mage.cards.h.Helldozer.class)); + cards.add(new SetCardInfo("Hideous End", 31, Rarity.COMMON, mage.cards.h.HideousEnd.class)); + cards.add(new SetCardInfo("Hull Breach", 89, Rarity.COMMON, mage.cards.h.HullBreach.class)); + cards.add(new SetCardInfo("Incremental Blight", 32, Rarity.UNCOMMON, mage.cards.i.IncrementalBlight.class)); + cards.add(new SetCardInfo("Innocent Blood", 33, Rarity.COMMON, mage.cards.i.InnocentBlood.class)); + cards.add(new SetCardInfo("Insurrection", 57, Rarity.RARE, mage.cards.i.Insurrection.class)); + cards.add(new SetCardInfo("Iron Myr", 115, Rarity.COMMON, mage.cards.i.IronMyr.class)); + cards.add(new SetCardInfo("Island", 147, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 148, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 149, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 150, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Ivy Elemental", 74, Rarity.RARE, mage.cards.i.IvyElemental.class)); + cards.add(new SetCardInfo("Keep Watch", 10, Rarity.COMMON, mage.cards.k.KeepWatch.class)); + cards.add(new SetCardInfo("Keldon Champion", 58, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); + cards.add(new SetCardInfo("Kor Sanctifiers", 3, Rarity.COMMON, mage.cards.k.KorSanctifiers.class)); + cards.add(new SetCardInfo("Leaden Myr", 116, Rarity.COMMON, mage.cards.l.LeadenMyr.class)); + cards.add(new SetCardInfo("Leechridden Swamp", 135, Rarity.UNCOMMON, mage.cards.l.LeechriddenSwamp.class)); + cards.add(new SetCardInfo("Lightning Helix", 90, Rarity.UNCOMMON, mage.cards.l.LightningHelix.class)); + cards.add(new SetCardInfo("Living Hive", 75, Rarity.RARE, mage.cards.l.LivingHive.class)); + cards.add(new SetCardInfo("Lodestone Myr", 117, Rarity.RARE, mage.cards.l.LodestoneMyr.class)); + cards.add(new SetCardInfo("Loxodon Warhammer", 118, Rarity.RARE, mage.cards.l.LoxodonWarhammer.class)); + cards.add(new SetCardInfo("Mage Slayer", 91, Rarity.UNCOMMON, mage.cards.m.MageSlayer.class)); + cards.add(new SetCardInfo("Mask of Memory", 119, Rarity.UNCOMMON, mage.cards.m.MaskOfMemory.class)); + cards.add(new SetCardInfo("Master of Etherium", 11, Rarity.RARE, mage.cards.m.MasterOfEtherium.class)); + cards.add(new SetCardInfo("Menacing Ogre", 59, Rarity.RARE, mage.cards.m.MenacingOgre.class)); + cards.add(new SetCardInfo("Mountain", 156, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 157, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 158, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 159, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 160, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 161, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 162, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 163, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 164, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Myr Enforcer", 120, Rarity.COMMON, mage.cards.m.MyrEnforcer.class)); + cards.add(new SetCardInfo("Nefashu", 34, Rarity.RARE, mage.cards.n.Nefashu.class)); + cards.add(new SetCardInfo("Noxious Ghoul", 35, Rarity.UNCOMMON, mage.cards.n.NoxiousGhoul.class)); + cards.add(new SetCardInfo("Nuisance Engine", 121, Rarity.UNCOMMON, mage.cards.n.NuisanceEngine.class)); + cards.add(new SetCardInfo("Oblivion Ring", 4, Rarity.COMMON, mage.cards.o.OblivionRing.class)); + cards.add(new SetCardInfo("Order // Chaos", 104, Rarity.UNCOMMON, mage.cards.o.OrderChaos.class)); + cards.add(new SetCardInfo("Orim's Thunder", 5, Rarity.COMMON, mage.cards.o.OrimsThunder.class)); + cards.add(new SetCardInfo("Pentad Prism", 122, Rarity.COMMON, mage.cards.p.PentadPrism.class)); + cards.add(new SetCardInfo("Pentavus", 123, Rarity.RARE, mage.cards.p.Pentavus.class)); + cards.add(new SetCardInfo("Phyrexian Arena", 36, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); + cards.add(new SetCardInfo("Phyrexian Ghoul", 37, Rarity.COMMON, mage.cards.p.PhyrexianGhoul.class)); + cards.add(new SetCardInfo("Plains", 142, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 143, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 144, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 145, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 146, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Prison Term", 6, Rarity.UNCOMMON, mage.cards.p.PrisonTerm.class)); + cards.add(new SetCardInfo("Profane Command", 38, Rarity.RARE, mage.cards.p.ProfaneCommand.class)); + cards.add(new SetCardInfo("Pyrotechnics", 60, Rarity.UNCOMMON, mage.cards.p.Pyrotechnics.class)); + cards.add(new SetCardInfo("Qumulox", 12, Rarity.UNCOMMON, mage.cards.q.Qumulox.class)); + cards.add(new SetCardInfo("Rampant Growth", 76, Rarity.COMMON, mage.cards.r.RampantGrowth.class)); + cards.add(new SetCardInfo("Razia, Boros Archangel", 92, Rarity.RARE, mage.cards.r.RaziaBorosArchangel.class)); + cards.add(new SetCardInfo("Reckless Charge", 61, Rarity.COMMON, mage.cards.r.RecklessCharge.class)); + cards.add(new SetCardInfo("Relentless Assault", 62, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); + cards.add(new SetCardInfo("Relic of Progenitus", 124, Rarity.COMMON, mage.cards.r.RelicOfProgenitus.class)); + cards.add(new SetCardInfo("Rockslide Elemental", 63, Rarity.UNCOMMON, mage.cards.r.RockslideElemental.class)); + cards.add(new SetCardInfo("Rolling Thunder", 64, Rarity.COMMON, mage.cards.r.RollingThunder.class)); + cards.add(new SetCardInfo("Rorix Bladewing", 65, Rarity.RARE, mage.cards.r.RorixBladewing.class)); + cards.add(new SetCardInfo("Rotting Rats", 39, Rarity.COMMON, mage.cards.r.RottingRats.class)); + cards.add(new SetCardInfo("Rumbling Slum", 93, Rarity.RARE, mage.cards.r.RumblingSlum.class)); + cards.add(new SetCardInfo("Sarcomite Myr", 13, Rarity.COMMON, mage.cards.s.SarcomiteMyr.class)); + cards.add(new SetCardInfo("Savage Twister", 94, Rarity.UNCOMMON, mage.cards.s.SavageTwister.class)); + cards.add(new SetCardInfo("Search for Tomorrow", 77, Rarity.COMMON, mage.cards.s.SearchForTomorrow.class)); + cards.add(new SetCardInfo("Seat of the Synod", 136, Rarity.COMMON, mage.cards.s.SeatOfTheSynod.class)); + cards.add(new SetCardInfo("Serum Tank", 125, Rarity.UNCOMMON, mage.cards.s.SerumTank.class)); + cards.add(new SetCardInfo("Shepherd of Rot", 40, Rarity.COMMON, mage.cards.s.ShepherdOfRot.class)); + cards.add(new SetCardInfo("Shivan Oasis", 137, Rarity.UNCOMMON, mage.cards.s.ShivanOasis.class)); + cards.add(new SetCardInfo("Silverglade Elemental", 78, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class)); + cards.add(new SetCardInfo("Silver Myr", 126, Rarity.COMMON, mage.cards.s.SilverMyr.class)); + cards.add(new SetCardInfo("Skeleton Shard", 127, Rarity.UNCOMMON, mage.cards.s.SkeletonShard.class)); + cards.add(new SetCardInfo("Sludge Strider", 95, Rarity.UNCOMMON, mage.cards.s.SludgeStrider.class)); + cards.add(new SetCardInfo("Smokebraider", 66, Rarity.COMMON, mage.cards.s.Smokebraider.class)); + cards.add(new SetCardInfo("Soulless One", 41, Rarity.UNCOMMON, mage.cards.s.SoullessOne.class)); + cards.add(new SetCardInfo("Soul Warden", 7, Rarity.COMMON, mage.cards.s.SoulWarden.class)); + cards.add(new SetCardInfo("Sunhome, Fortress of the Legion", 138, Rarity.UNCOMMON, mage.cards.s.SunhomeFortressOfTheLegion.class)); + cards.add(new SetCardInfo("Suntouched Myr", 128, Rarity.COMMON, mage.cards.s.SuntouchedMyr.class)); + cards.add(new SetCardInfo("Swamp", 151, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 152, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 153, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 154, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 155, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Syphon Mind", 42, Rarity.COMMON, mage.cards.s.SyphonMind.class)); + cards.add(new SetCardInfo("Syphon Soul", 43, Rarity.COMMON, mage.cards.s.SyphonSoul.class)); + cards.add(new SetCardInfo("Taurean Mauler", 67, Rarity.RARE, mage.cards.t.TaureanMauler.class)); + cards.add(new SetCardInfo("Terramorphic Expanse", 139, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); + cards.add(new SetCardInfo("Thirst for Knowledge", 14, Rarity.UNCOMMON, mage.cards.t.ThirstForKnowledge.class)); + cards.add(new SetCardInfo("Tornado Elemental", 79, Rarity.RARE, mage.cards.t.TornadoElemental.class)); + cards.add(new SetCardInfo("Tree of Tales", 140, Rarity.COMMON, mage.cards.t.TreeOfTales.class)); + cards.add(new SetCardInfo("Tribal Unity", 80, Rarity.UNCOMMON, mage.cards.t.TribalUnity.class)); + cards.add(new SetCardInfo("Undead Warchief", 44, Rarity.UNCOMMON, mage.cards.u.UndeadWarchief.class)); + cards.add(new SetCardInfo("Vault of Whispers", 141, Rarity.COMMON, mage.cards.v.VaultOfWhispers.class)); + cards.add(new SetCardInfo("Vedalken Engineer", 15, Rarity.COMMON, mage.cards.v.VedalkenEngineer.class)); + cards.add(new SetCardInfo("Verdant Force", 81, Rarity.RARE, mage.cards.v.VerdantForce.class)); + cards.add(new SetCardInfo("Whiplash Trap", 16, Rarity.COMMON, mage.cards.w.WhiplashTrap.class)); + cards.add(new SetCardInfo("Withered Wretch", 45, Rarity.UNCOMMON, mage.cards.w.WitheredWretch.class)); + cards.add(new SetCardInfo("Wizard Replica", 129, Rarity.COMMON, mage.cards.w.WizardReplica.class)); + } + +} diff --git a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java index 2be2711c2e..86fe479084 100644 --- a/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java +++ b/Mage.Sets/src/mage/sets/RavnicaCityOfGuilds.java @@ -89,6 +89,7 @@ public class RavnicaCityOfGuilds extends ExpansionSet { cards.add(new SetCardInfo("Clinging Darkness", 80, Rarity.COMMON, mage.cards.c.ClingingDarkness.class)); cards.add(new SetCardInfo("Cloudstone Curio", 257, Rarity.RARE, mage.cards.c.CloudstoneCurio.class)); cards.add(new SetCardInfo("Clutch of the Undercity", 197, Rarity.UNCOMMON, mage.cards.c.ClutchOfTheUndercity.class)); + cards.add(new SetCardInfo("Coalhauler Swine", 119, Rarity.COMMON, mage.cards.c.CoalhaulerSwine.class)); cards.add(new SetCardInfo("Compulsive Research", 40, Rarity.COMMON, mage.cards.c.CompulsiveResearch.class)); cards.add(new SetCardInfo("Concerted Effort", 8, Rarity.RARE, mage.cards.c.ConcertedEffort.class)); cards.add(new SetCardInfo("Conclave Equenaut", 9, Rarity.COMMON, mage.cards.c.ConclaveEquenaut.class)); diff --git a/Mage.Sets/src/mage/sets/RevisedEdition.java b/Mage.Sets/src/mage/sets/RevisedEdition.java index 73a2cb5fcc..db1fd03ab4 100644 --- a/Mage.Sets/src/mage/sets/RevisedEdition.java +++ b/Mage.Sets/src/mage/sets/RevisedEdition.java @@ -231,10 +231,9 @@ public class RevisedEdition extends ExpansionSet { cards.add(new SetCardInfo("Resurrection", 218, Rarity.UNCOMMON, mage.cards.r.Resurrection.class)); cards.add(new SetCardInfo("Reverse Damage", 219, Rarity.RARE, mage.cards.r.ReverseDamage.class)); cards.add(new SetCardInfo("Righteousness", 221, Rarity.RARE, mage.cards.r.Righteousness.class)); - cards.add(new SetCardInfo("Rock Hydra", 172, Rarity.RARE, mage.cards.r.RockHydra.class)); - cards.add(new SetCardInfo("Rocket Launcher", 272, Rarity.RARE, mage.cards.r.RocketLauncher.class)); cards.add(new SetCardInfo("Roc of Kher Ridges", 171, Rarity.RARE, mage.cards.r.RocOfKherRidges.class)); cards.add(new SetCardInfo("Rock Hydra", 172, Rarity.RARE, mage.cards.r.RockHydra.class)); + cards.add(new SetCardInfo("Rocket Launcher", 272, Rarity.RARE, mage.cards.r.RocketLauncher.class)); cards.add(new SetCardInfo("Rod of Ruin", 273, Rarity.UNCOMMON, mage.cards.r.RodOfRuin.class)); cards.add(new SetCardInfo("Royal Assassin", 33, Rarity.RARE, mage.cards.r.RoyalAssassin.class)); cards.add(new SetCardInfo("Sacrifice", 34, Rarity.UNCOMMON, mage.cards.s.Sacrifice.class)); diff --git a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java index 17b166f29a..deba2b69bd 100644 --- a/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java +++ b/Mage.Sets/src/mage/sets/TimeSpiralTimeshifted.java @@ -105,6 +105,7 @@ public class TimeSpiralTimeshifted extends ExpansionSet { cards.add(new SetCardInfo("Merieke Ri Berit", 95, Rarity.SPECIAL, mage.cards.m.MeriekeRiBerit.class)); cards.add(new SetCardInfo("Mindless Automaton", 111, Rarity.SPECIAL, mage.cards.m.MindlessAutomaton.class)); cards.add(new SetCardInfo("Mirari", 112, Rarity.SPECIAL, mage.cards.m.Mirari.class)); + cards.add(new SetCardInfo("Mistform Ultimus", 26, Rarity.SPECIAL, mage.cards.m.MistformUltimus.class)); cards.add(new SetCardInfo("Moorish Cavalry", 11, Rarity.COMMON, mage.cards.m.MoorishCavalry.class)); cards.add(new SetCardInfo("Mystic Enforcer", 96, Rarity.SPECIAL, mage.cards.m.MysticEnforcer.class)); cards.add(new SetCardInfo("Mystic Snake", 97, Rarity.COMMON, mage.cards.m.MysticSnake.class)); diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 25b49f8b70..21c171445c 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -68,6 +68,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("Creeping Mold", 53, Rarity.UNCOMMON, mage.cards.c.CreepingMold.class)); cards.add(new SetCardInfo("Crypt Rats", 5, Rarity.COMMON, mage.cards.c.CryptRats.class)); cards.add(new SetCardInfo("Daraja Griffin", 102, Rarity.UNCOMMON, mage.cards.d.DarajaGriffin.class)); + cards.add(new SetCardInfo("Death Watch", 7, Rarity.COMMON, mage.cards.d.DeathWatch.class)); cards.add(new SetCardInfo("Desertion", 30, Rarity.RARE, mage.cards.d.Desertion.class)); cards.add(new SetCardInfo("Diamond Kaleidoscope", 143, Rarity.RARE, mage.cards.d.DiamondKaleidoscope.class)); cards.add(new SetCardInfo("Dormant Volcano", 161, Rarity.UNCOMMON, mage.cards.d.DormantVolcano.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CrewTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CrewTest.java index 4d9e6c830e..df510eb126 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CrewTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CrewTest.java @@ -92,12 +92,12 @@ public class CrewTest extends CardTestPlayerBase { setChoice(playerA, "Speedway Fanatic"); // Return all creatures to there owners hands - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Evacuation"); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Evacuation"); // (Re)Cast Smugglers Copter - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Smuggler's Copter"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Smuggler's Copter"); - setStopAt(1, PhaseStep.BEGIN_COMBAT); + setStopAt(1, PhaseStep.END_TURN); execute(); // Only crewed vehicles have card type creature diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java new file mode 100644 index 0000000000..2555155884 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DamageEffectsTest.java @@ -0,0 +1,98 @@ +/* + * 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.replacement; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class DamageEffectsTest extends CardTestPlayerBase { + + /** + * Just encountered another bug. With Wurmcoil Engine out and with a + * Gratuitous Violence on the field, I only gained 6 life on blocking rather + * than 12 life. + */ + @Test + public void testDamageIsDoubledWithLifelink() { + // Landfall - Whenever a land enters the battlefield under your control, you may have target player lose 3 life. + // If you do, put three +1/+1 counters on Ob Nixilis, the Fallen. + addCard(Zone.BATTLEFIELD, playerB, "Ob Nixilis, the Fallen"); + addCard(Zone.HAND, playerB, "Mountain"); + + // Deathtouch, lifelink + // When Wurmcoil Engine dies, create a 3/3 colorless Wurm artifact creature token with deathtouch and a 3/3 colorless Wurm artifact creature token with lifelink. + addCard(Zone.BATTLEFIELD, playerA, "Wurmcoil Engine"); + // If a creature you control would deal damage to a creature or player, it deals double that damage to that creature or player instead. + addCard(Zone.BATTLEFIELD, playerA, "Gratuitous Violence"); + + playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Mountain"); + setChoice(playerB, "Yes"); + addTarget(playerB, playerA); + + attack(2, playerB, "Ob Nixilis, the Fallen"); + block(2, playerA, "Wurmcoil Engine", "Ob Nixilis, the Fallen"); + + setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerB, "Ob Nixilis, the Fallen", 1); + + assertGraveyardCount(playerA, "Wurmcoil Engine", 1); + assertPermanentCount(playerA, "Wurm", 2); + + assertLife(playerB, 20); + assertLife(playerA, 29); // -2 from Ob Nixilis + 12 from double damage with lifelink from Wurmcoil Engine + + } + + @Test + public void testDamageToPlayer() { + // Deathtouch, lifelink + // When Wurmcoil Engine dies, create a 3/3 colorless Wurm artifact creature token with deathtouch and a 3/3 colorless Wurm artifact creature token with lifelink. + addCard(Zone.BATTLEFIELD, playerA, "Wurmcoil Engine"); + // If a creature you control would deal damage to a creature or player, it deals double that damage to that creature or player instead. + addCard(Zone.BATTLEFIELD, playerA, "Gratuitous Violence"); + + attack(1, playerA, "Wurmcoil Engine"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Wurmcoil Engine", 1); + + assertLife(playerB, 8); + assertLife(playerA, 32); + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChandraPyromasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChandraPyromasterTest.java index f886a1dfbf..ee9f0bf6bb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChandraPyromasterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChandraPyromasterTest.java @@ -43,6 +43,29 @@ public class ChandraPyromasterTest extends CardTestPlayerBase { assertGraveyardCount(playerB, "Silvercoat Lion", 1); } + + @Test + public void testAbility2AncestralVision() { + addCard(Zone.BATTLEFIELD, playerA, "Chandra, Pyromaster"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + + skipInitShuffling(); + addCard(Zone.LIBRARY, playerA, "Ancestral Vision"); + + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+0: Exile the top card of your library. You may play it this turn."); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertPermanentCount(playerA, "Chandra, Pyromaster", 1); + assertGraveyardCount(playerA, "Ancestral Vision", 0); + + assertExileCount(playerA, "Ancestral Vision", 1); + } @Test public void testAbility2CastCardFromExileWithOverlaod() { diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java index 27d980f32f..00ee97cd16 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestBase.java @@ -28,7 +28,6 @@ import org.mage.test.player.TestPlayer; import java.io.File; import java.io.FileNotFoundException; import java.io.FilenameFilter; -import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -297,7 +296,8 @@ public abstract class MageTestBase { } protected Player createPlayer(String name, String playerType) { - return PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, 5); + Optional playerOptional = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, 5); + return playerOptional.orElseThrow(() -> new NullPointerException("PlayerFactory error - player is not created")); } protected Player createRandomPlayer(String name) { 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 3d819e72d3..736eb4d976 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 @@ -860,6 +860,25 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement Assert.assertEquals("(Exile) Card counts for player " + owner.getName() + " is not equal.", count, actualCount); } + /** + * Assert card count in player's exile. + * + * @param owner {@link Player} who's exile should be counted. + * @param cardName Name of the cards that should be counted. + * @param count Expected count. + */ + public void assertExileCount(Player owner, String cardName, int count) throws AssertionError { + int actualCount = 0; + for (ExileZone exile : currentGame.getExile().getExileZones()) { + for (Card card : exile.getCards(currentGame)) { + if (card.getOwnerId().equals(owner.getId()) && card.getName().equals(cardName)) { + actualCount++; + } + } + } + Assert.assertEquals("(Exile " + owner.getName() + ") Card counts are not equal (" + cardName + ')', count, actualCount); + } + /** * Assert card count in player's graveyard. * diff --git a/Mage/src/main/java/mage/abilities/common/AttacksAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksAttachedTriggeredAbility.java index 97c5d2ac80..0efaa22f9c 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksAttachedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksAttachedTriggeredAbility.java @@ -88,11 +88,7 @@ public class AttacksAttachedTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { StringBuilder sb = new StringBuilder("Whenever "); - if (attachmentType.equals(AttachmentType.EQUIPMENT)) { - sb.append("equipped"); - } else { - sb.append("enchanted"); - } + sb.append(attachmentType.verb().toLowerCase()); return sb.append(" creature attacks, ").append(super.getRule()).toString(); } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/AfterUpkeepStepCondtion.java b/Mage/src/main/java/mage/abilities/condition/common/AfterUpkeepStepCondtion.java index c0ef7381d1..b3c60a479e 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/AfterUpkeepStepCondtion.java +++ b/Mage/src/main/java/mage/abilities/condition/common/AfterUpkeepStepCondtion.java @@ -23,8 +23,7 @@ public class AfterUpkeepStepCondtion implements Condition { @Override public boolean apply(Game game, Ability source) { - return !(game.getStep().getType() == PhaseStep.UNTAP - || game.getStep().getType() == PhaseStep.UPKEEP); + return game.getStep().getType().isAfter(PhaseStep.UPKEEP); } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/BeforeBlockersAreDeclaredCondition.java b/Mage/src/main/java/mage/abilities/condition/common/BeforeBlockersAreDeclaredCondition.java index c0326e5bb4..c7f30b3fea 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/BeforeBlockersAreDeclaredCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/BeforeBlockersAreDeclaredCondition.java @@ -26,10 +26,7 @@ public class BeforeBlockersAreDeclaredCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return !(game.getStep().getType().equals(PhaseStep.DECLARE_BLOCKERS) - || game.getStep().getType().equals(PhaseStep.FIRST_COMBAT_DAMAGE) - || game.getStep().getType().equals(PhaseStep.COMBAT_DAMAGE) - || game.getStep().getType().equals(PhaseStep.END_COMBAT)); + return game.getStep().getType().isBefore(PhaseStep.DECLARE_BLOCKERS); } @Override diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java index 1e541429cc..6f69afd8e6 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java @@ -27,11 +27,6 @@ */ package mage.abilities.costs.mana; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.costs.Cost; @@ -45,13 +40,15 @@ import mage.players.Player; import mage.target.Targets; import mage.util.ManaUtil; +import java.util.*; + /** * @author BetaSteward_at_googlemail.com * @param */ public class ManaCostsImpl extends ArrayList implements ManaCosts { - protected UUID id; + protected final UUID id; protected String text = null; private static Map costs = new HashMap<>(); @@ -323,7 +320,7 @@ public class ManaCostsImpl extends ArrayList implements M if (mana == null || mana.isEmpty()) { return; } - String[] symbols = mana.split("^\\{|\\}\\{|\\}$"); + String[] symbols = mana.split("^\\{|}\\{|}$"); int modifierForX = 0; for (String symbol : symbols) { if (!symbol.isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalAsThoughEffect.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalAsThoughEffect.java index 2538b583cf..94c2caf4ad 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalAsThoughEffect.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalAsThoughEffect.java @@ -28,6 +28,7 @@ package mage.abilities.decorator; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.condition.Condition; import mage.abilities.effects.AsThoughEffect; @@ -36,10 +37,9 @@ import mage.constants.Duration; import mage.game.Game; /** - * * @author LevelX2 */ -public class ConditionalAsThoughEffect extends AsThoughEffectImpl { +public class ConditionalAsThoughEffect extends AsThoughEffectImpl { protected AsThoughEffect effect; protected AsThoughEffect otherwiseEffect; @@ -59,9 +59,9 @@ public class ConditionalAsThoughEffect extends AsThoughEffectImpl { public ConditionalAsThoughEffect(final ConditionalAsThoughEffect effect) { super(effect); - this.effect = (AsThoughEffect) effect.effect.copy(); + this.effect = effect.effect.copy(); if (effect.otherwiseEffect != null) { - this.otherwiseEffect = (AsThoughEffect) effect.otherwiseEffect.copy(); + this.otherwiseEffect = effect.otherwiseEffect.copy(); } this.condition = effect.condition; this.conditionState = effect.conditionState; diff --git a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java index d0382e571c..0916c4f730 100644 --- a/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/AuraReplacementEffect.java @@ -28,6 +28,7 @@ package mage.abilities.effects; import java.util.UUID; + import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; @@ -55,10 +56,10 @@ import mage.target.common.TargetCardInGraveyard; * was not cast (so from Zone != Hand), this effect gets the target to whitch to * attach it and adds the Aura the the battlefield and attachs it to the target. * The "attachTo:" value in game state has to be set therefore. - * + *

* If no "attachTo:" value is defined, the controlling player has to chose the * aura target. - * + *

* This effect is automatically added to ContinuousEffects at the start of a * game * @@ -204,15 +205,15 @@ public class AuraReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (((ZoneChangeEvent) event).getToZone().equals(Zone.BATTLEFIELD) - && !(((ZoneChangeEvent) event).getFromZone().equals(Zone.STACK))) { + if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD + && (((ZoneChangeEvent) event).getFromZone() != Zone.STACK)) { Card card = game.getCard(event.getTargetId()); if (card != null && (card.getCardType().contains(CardType.ENCHANTMENT) && card.hasSubtype("Aura", game) || // in case of transformable enchantments (game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()) != null - && card.getSecondCardFace() != null - && card.getSecondCardFace().getCardType().contains(CardType.ENCHANTMENT) - && card.getSecondCardFace().hasSubtype("Aura", game)))) { + && card.getSecondCardFace() != null + && card.getSecondCardFace().getCardType().contains(CardType.ENCHANTMENT) + && card.getSecondCardFace().hasSubtype("Aura", game)))) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java index c3027ce821..52cb239bd2 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectImpl.java @@ -33,6 +33,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; + import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.MageSingleton; @@ -51,7 +53,6 @@ import mage.game.Game; import mage.players.Player; /** - * * @author BetaSteward_at_googlemail.com */ public abstract class ContinuousEffectImpl extends EffectImpl implements ContinuousEffect { @@ -171,9 +172,9 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu public void init(Ability source, Game game) { targetPointer.init(game, source); //20100716 - 611.2c - if (AbilityType.ACTIVATED.equals(source.getAbilityType()) - || AbilityType.SPELL.equals(source.getAbilityType()) - || AbilityType.TRIGGERED.equals(source.getAbilityType())) { + if (AbilityType.ACTIVATED == source.getAbilityType() + || AbilityType.SPELL == source.getAbilityType() + || AbilityType.TRIGGERED == source.getAbilityType()) { if (layer != null) { switch (layer) { case CopyEffects_1: @@ -197,7 +198,7 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu @Override public boolean isInactive(Ability source, Game game) { - if (duration.equals(Duration.UntilYourNextTurn)) { + if (duration == Duration.UntilYourNextTurn) { Player player = game.getPlayer(startingControllerId); if (player != null) { if (player.isInGame()) { @@ -271,19 +272,13 @@ public abstract class ContinuousEffectImpl extends EffectImpl implements Continu @Override public Set isDependentTo(List allEffectsInLayer) { if (dependendToType != null) { - // the dependent classes needs to be an enclosed class for dependent check of continuous effects - Set dependentTo = null; - for (ContinuousEffect effect : allEffectsInLayer) { - if (effect.getDependencyTypes().contains(dependendToType)) { - if (dependentTo == null) { - dependentTo = new HashSet<>(); - } - dependentTo.add(effect.getId()); - } - } - return dependentTo; + return allEffectsInLayer.stream() + .filter(effect -> effect.getDependencyTypes().contains(dependendToType)) + .map(Effect::getId) + .collect(Collectors.toSet()); + } - return null; + return new HashSet<>(); } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index c5da9a1849..cd041b6d59 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -27,40 +27,12 @@ */ package mage.abilities.effects; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.UUID; import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.ActivatedAbility; -import mage.abilities.MageSingleton; -import mage.abilities.SpellAbility; -import mage.abilities.StaticAbility; +import mage.abilities.*; import mage.abilities.keyword.SpliceOntoArcaneAbility; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.constants.AbilityType; -import mage.constants.AsThoughEffectType; -import mage.constants.CostModificationType; -import mage.constants.Duration; -import mage.constants.EffectType; -import mage.constants.Layer; -import mage.constants.ManaType; -import mage.constants.Outcome; -import mage.constants.SpellAbilityType; -import mage.constants.SubLayer; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; @@ -77,8 +49,11 @@ import mage.players.Player; import mage.target.common.TargetCardInHand; import org.apache.log4j.Logger; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; + /** - * * @author BetaSteward_at_googlemail.com */ public class ContinuousEffects implements Serializable { @@ -218,7 +193,7 @@ public class ContinuousEffects implements Serializable { case WhileOnStack: case WhileInGraveyard: HashSet abilities = layeredEffects.getAbility(effect.getId()); - if (abilities != null) { + if (!abilities.isEmpty()) { for (Ability ability : abilities) { // If e.g. triggerd abilities (non static) created the effect, the ability must not be in usable zone (e.g. Unearth giving Haste effect) if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, null)) { @@ -358,7 +333,6 @@ public class ContinuousEffects implements Serializable { } /** - * * @param event * @param game * @return a list of all {@link ReplacementEffect} that apply to the current @@ -717,7 +691,8 @@ public class ContinuousEffects implements Serializable { spliceAbilities.remove(selectedAbility); } } - } while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", abilityToModify, game)); + } + while (!spliceAbilities.isEmpty() && controller.chooseUse(Outcome.Benefit, "Splice another card?", abilityToModify, game)); controller.revealCards("Spliced cards", cardsToReveal, game); } } @@ -727,10 +702,10 @@ public class ContinuousEffects implements Serializable { * Checks if an event won't happen because of an rule modifying effect * * @param event - * @param targetAbility ability the event is attached to. can be null. + * @param targetAbility ability the event is attached to. can be null. * @param game * @param checkPlayableMode true if the event does not really happen but - * it's checked if the event would be replaced + * it's checked if the event would be replaced * @return */ public boolean preventedByRuleModification(GameEvent event, Ability targetAbility, Game game, boolean checkPlayableMode) { @@ -777,7 +752,7 @@ public class ContinuousEffects implements Serializable { do { HashMap> rEffects = getApplicableReplacementEffects(event, game); // Remove all consumed effects (ability dependant) - for (Iterator it1 = rEffects.keySet().iterator(); it1.hasNext();) { + for (Iterator it1 = rEffects.keySet().iterator(); it1.hasNext(); ) { ReplacementEffect entry = it1.next(); if (consumed.containsKey(entry.getId())) { HashSet consumedAbilitiesIds = consumed.get(entry.getId()); @@ -865,9 +840,8 @@ public class ContinuousEffects implements Serializable { if (consumed.containsKey(rEffect.getId())) { HashSet set = consumed.get(rEffect.getId()); if (rAbility != null) { - if (!set.contains(rAbility.getId())) { - set.add(rAbility.getId()); - } + set.add(rAbility.getId()); + } } else { HashSet set = new HashSet<>(); @@ -936,7 +910,7 @@ public class ContinuousEffects implements Serializable { for (ContinuousEffect effect : layer) { if (activeLayerEffects.contains(effect) && !appliedEffects.contains(effect.getId())) { // Effect does still exist and was not applied yet Set dependentTo = effect.isDependentTo(layer); - if (dependentTo != null && !appliedEffects.containsAll(dependentTo)) { + if (!appliedEffects.containsAll(dependentTo)) { waitingEffects.put(effect, dependentTo); continue; } @@ -959,7 +933,7 @@ public class ContinuousEffects implements Serializable { if (!waitingEffects.isEmpty()) { // check if waiting effects can be applied now - for (Iterator>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext();) { + for (Iterator>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext(); ) { Map.Entry> entry = iterator.next(); if (appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself appliedAbilities = appliedEffectAbilities.get(entry.getKey()); @@ -1039,7 +1013,7 @@ public class ContinuousEffects implements Serializable { for (ContinuousEffect effect : layer) { if (numberOfEffects > 1) { // If an effect is dependent to not applied effects yet of this layer, so wait to apply this effect Set dependentTo = effect.isDependentTo(layer); - if (dependentTo != null && !appliedEffects.containsAll(dependentTo)) { + if (!appliedEffects.containsAll(dependentTo)) { waitingEffects.put(effect, dependentTo); continue; } @@ -1162,17 +1136,16 @@ public class ContinuousEffects implements Serializable { private void setControllerForEffect(ContinuousEffectsList effects, UUID sourceId, UUID controllerId) { for (Effect effect : effects) { HashSet abilities = effects.getAbility(effect.getId()); - if (abilities != null) { - for (Ability ability : abilities) { - if (ability.getSourceId() != null) { - if (ability.getSourceId().equals(sourceId)) { - ability.setControllerId(controllerId); - } - } else if (!ability.getZone().equals(Zone.COMMAND)) { - logger.fatal("Continuous effect for ability with no sourceId Ability: " + ability); + for (Ability ability : abilities) { + if (ability.getSourceId() != null) { + if (ability.getSourceId().equals(sourceId)) { + ability.setControllerId(controllerId); } + } else if (ability.getZone() != Zone.COMMAND) { + logger.fatal("Continuous effect for ability with no sourceId Ability: " + ability); } } + } } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectsList.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectsList.java index 234a30e456..0fad03c7bc 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffectsList.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffectsList.java @@ -34,6 +34,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.MageSingleton; import mage.constants.Duration; @@ -41,9 +42,8 @@ import mage.game.Game; import org.apache.log4j.Logger; /** - * - * @author BetaSteward_at_googlemail.com * @param + * @author BetaSteward_at_googlemail.com */ public class ContinuousEffectsList extends ArrayList { @@ -74,7 +74,7 @@ public class ContinuousEffectsList extends ArrayList } public void removeEndOfTurnEffects() { - for (Iterator i = this.iterator(); i.hasNext();) { + for (Iterator i = this.iterator(); i.hasNext(); ) { T entry = i.next(); if (entry.getDuration() == Duration.EndOfTurn) { i.remove(); @@ -84,7 +84,7 @@ public class ContinuousEffectsList extends ArrayList } public void removeEndOfCombatEffects() { - for (Iterator i = this.iterator(); i.hasNext();) { + for (Iterator i = this.iterator(); i.hasNext(); ) { T entry = i.next(); if (entry.getDuration() == Duration.EndOfCombat) { i.remove(); @@ -94,7 +94,7 @@ public class ContinuousEffectsList extends ArrayList } public void removeInactiveEffects(Game game) { - for (Iterator i = this.iterator(); i.hasNext();) { + for (Iterator i = this.iterator(); i.hasNext(); ) { T entry = i.next(); if (isInactive(entry, game)) { i.remove(); @@ -169,7 +169,7 @@ public class ContinuousEffectsList extends ArrayList } public HashSet getAbility(UUID effectId) { - return effectAbilityMap.get(effectId); + return effectAbilityMap.getOrDefault(effectId, new HashSet<>()); } public void removeEffects(UUID effectIdToRemove, Set abilitiesToRemove) { @@ -178,7 +178,7 @@ public class ContinuousEffectsList extends ArrayList abilities.removeAll(abilitiesToRemove); } if (abilities == null || abilities.isEmpty()) { - for (Iterator iterator = this.iterator(); iterator.hasNext();) { + for (Iterator iterator = this.iterator(); iterator.hasNext(); ) { ContinuousEffect effect = iterator.next(); if (effect.getId().equals(effectIdToRemove)) { iterator.remove(); diff --git a/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java index 320ddaa08b..ef78e432bb 100644 --- a/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java @@ -97,13 +97,13 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { switch (enterEventType) { case OTHER: - return EventType.ENTERS_THE_BATTLEFIELD.equals(event.getType()); + return EventType.ENTERS_THE_BATTLEFIELD == event.getType(); case SELF: - return EventType.ENTERS_THE_BATTLEFIELD_SELF.equals(event.getType()); + return EventType.ENTERS_THE_BATTLEFIELD_SELF == event.getType(); case CONTROL: - return EventType.ENTERS_THE_BATTLEFIELD_CONTROL.equals(event.getType()); + return EventType.ENTERS_THE_BATTLEFIELD_CONTROL == event.getType(); case COPY: - return EventType.ENTERS_THE_BATTLEFIELD_COPY.equals(event.getType()); + return EventType.ENTERS_THE_BATTLEFIELD_COPY == event.getType(); } return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java b/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java index f1440fb6c6..6b3c56b6fe 100644 --- a/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java +++ b/Mage/src/main/java/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java @@ -44,7 +44,7 @@ import mage.players.Player; */ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectImpl implements PayCostToAttackBlockEffect { - public static enum RestrictType { + public enum RestrictType { ATTACK("attack"), ATTACK_AND_BLOCK("attack or block"), @@ -111,7 +111,7 @@ public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectIm case BLOCK: return event.getType().equals(GameEvent.EventType.DECLARE_BLOCKER); case ATTACK_AND_BLOCK: - return event.getType() == GameEvent.EventType.DECLARE_ATTACKER || event.getType().equals(GameEvent.EventType.DECLARE_BLOCKER); + return event.getType() == GameEvent.EventType.DECLARE_ATTACKER || event.getType() == EventType.DECLARE_BLOCKER; } return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java index c2fee30b9c..4cc5a71ce6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AddCombatAndMainPhaseEffect.java @@ -61,8 +61,8 @@ public class AddCombatAndMainPhaseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { // 15.07.2006 If it's somehow not a main phase when Fury of the Horde resolves, all it does is untap all creatures that attacked that turn. No new phases are created. - if (TurnPhase.PRECOMBAT_MAIN.equals(game.getTurn().getPhaseType()) - || TurnPhase.POSTCOMBAT_MAIN.equals(game.getTurn().getPhaseType())) { + if (game.getTurn().getPhaseType() == TurnPhase.PRECOMBAT_MAIN + || game.getTurn().getPhaseType() == TurnPhase.POSTCOMBAT_MAIN) { // we can't add two turn modes at once, will add additional post combat on delayed trigger resolution TurnMod combat = new TurnMod(source.getControllerId(), TurnPhase.COMBAT, TurnPhase.POSTCOMBAT_MAIN, false); game.getState().getTurnMods().add(combat); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java index e4d0498e14..507910fc0e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java @@ -109,16 +109,12 @@ public class CantBeTargetedAttachedEffect extends ContinuousRuleModifyingEffectI return staticText; } StringBuilder sb = new StringBuilder(); - if (attachmentType.equals(AttachmentType.AURA)) { - sb.append("Enchanted creature"); - } else { - sb.append("Equipped creature"); - } + sb.append(attachmentType.verb() + " creature"); sb.append(" can't be the target of "); sb.append(filterSource.getMessage()); if (!duration.toString().isEmpty()) { sb.append(' '); - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append("this turn"); } else { sb.append(duration.toString()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java index 9cda89ce6b..8f0989f7cb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersNextUntapStepTargetEffect.java @@ -114,7 +114,7 @@ public class DontUntapInControllersNextUntapStepTargetEffect extends ContinuousR public boolean applies(GameEvent event, Ability source, Game game) { // the check if a permanent untap pahse is already handled is needed if multiple effects are added to prevent untap in next untap step of controller // if we don't check it for every untap step of a turn only one effect would be consumed instead of all be valid for the next untap step - if (GameEvent.EventType.UNTAP_STEP.equals(event.getType())) { + if (event.getType() == EventType.UNTAP_STEP) { boolean allHandled = true; for (UUID targetId : getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java index f259f9568d..541bdd908e 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepEnchantedEffect.java @@ -56,7 +56,7 @@ public class DontUntapInControllersUntapStepEnchantedEffect extends ContinuousRu @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (PhaseStep.UNTAP.equals(game.getTurn().getStepType())) { + if (game.getTurn().getStepType() == PhaseStep.UNTAP) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) { Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java index 69118f2ac1..b4e0b50bd2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInControllersUntapStepTargetEffect.java @@ -81,7 +81,7 @@ public class DontUntapInControllersUntapStepTargetEffect extends ContinuousRuleM @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (PhaseStep.UNTAP.equals(game.getTurn().getStepType())) { + if (game.getTurn().getStepType() == PhaseStep.UNTAP) { for (UUID targetId : targetPointer.getTargets(game, source)) { if (event.getTargetId().equals(targetId)) { Permanent permanent = game.getPermanent(targetId); diff --git a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInOpponentsNextUntapStepAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInOpponentsNextUntapStepAllEffect.java index 53a627a1d9..81d25066c5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DontUntapInOpponentsNextUntapStepAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DontUntapInOpponentsNextUntapStepAllEffect.java @@ -107,7 +107,7 @@ public class DontUntapInOpponentsNextUntapStepAllEffect extends ContinuousRuleMo return false; } // remember the turn of the untap step the effect has to be applied - if (GameEvent.EventType.UNTAP_STEP.equals(event.getType())) { + if (event.getType() == EventType.UNTAP_STEP) { if (game.getActivePlayerId().equals(getTargetPointer().getFirst(game, source))) { if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step discard(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index 0d1c9dda85..20ab7c5e7b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -190,7 +190,7 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff if (player.choose(Outcome.DrawCard, cards, target, game)) { Cards pickedCards = new CardsImpl(target.getTargets()); cards.removeAll(pickedCards); - if (targetPickedCards.equals(Zone.LIBRARY) && !putOnTopSelected) { + if (targetPickedCards == Zone.LIBRARY && !putOnTopSelected) { player.putCardsOnBottomOfLibrary(pickedCards, game, source, true); } else { player.moveCards(pickedCards.getCards(game), targetPickedCards, source, game); diff --git a/Mage/src/main/java/mage/abilities/effects/common/RegenerateAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RegenerateAttachedEffect.java index ce6fd70fc1..2bf62a4b5b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/RegenerateAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/RegenerateAttachedEffect.java @@ -40,7 +40,6 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; /** - * * @author jeff */ public class RegenerateAttachedEffect extends ReplacementEffectImpl { @@ -102,13 +101,8 @@ public class RegenerateAttachedEffect extends ReplacementEffectImpl { } return false; } + private void setText() { - StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) { - sb.append("Regenerate enchanted creature"); - } else if (attachmentType == AttachmentType.EQUIPMENT) { - sb.append("Regenerate equipped creature"); - } - staticText = sb.toString(); + staticText = "Regenerate " + attachmentType.verb().toLowerCase() + " creature"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleAttachedEffect.java index 19432669b3..9dac0b88ef 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleAttachedEffect.java @@ -44,11 +44,7 @@ public class AttacksIfAbleAttachedEffect extends RequirementEffect { public AttacksIfAbleAttachedEffect(Duration duration, AttachmentType attachmentType) { super(duration); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature attacks each turn if able"; - } else { - this.staticText = "Equipped creature attacks each turn if able"; - } + this.staticText = attachmentType.verb() + " creature attacks each turn if able"; } public AttacksIfAbleAttachedEffect(final AttacksIfAbleAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java index c4421d7951..c8b8f140f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java @@ -51,7 +51,7 @@ public class BlocksIfAbleAllEffect extends RequirementEffect { super(duration); staticText = new StringBuilder(filter.getMessage()) .append(" block ") - .append(duration.equals(Duration.EndOfTurn) ? "this":"each") + .append(duration == Duration.EndOfTurn ? "this":"each") .append(" turn if able").toString(); this.filter = filter; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java index 0c00164f6a..988c75ff76 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java @@ -36,7 +36,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author LevelX2 */ @@ -44,11 +43,7 @@ public class BlocksIfAbleAttachedEffect extends RequirementEffect { public BlocksIfAbleAttachedEffect(Duration duration, AttachmentType attachmentType) { super(duration); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature blocks each turn if able"; - } else { - this.staticText = "Equipped creature blocks each turn if able"; - } + this.staticText = attachmentType.verb() + " creature blocks each turn if able"; } public BlocksIfAbleAttachedEffect(final BlocksIfAbleAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderAllEffect.java index 1acbd8bba1..8bd2142df4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderAllEffect.java @@ -27,7 +27,6 @@ */ package mage.abilities.effects.common.combat; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; import mage.constants.AsThoughEffectType; @@ -38,18 +37,19 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.UUID; + /** - * * @author Quercitron */ public class CanAttackAsThoughItDidntHaveDefenderAllEffect extends AsThoughEffectImpl { private final FilterPermanent filter; - + public CanAttackAsThoughItDidntHaveDefenderAllEffect(Duration duration) { this(duration, new FilterCreaturePermanent()); } - + public CanAttackAsThoughItDidntHaveDefenderAllEffect(Duration duration, FilterPermanent filter) { super(AsThoughEffectType.ATTACK, duration, Outcome.Benefit); this.filter = filter; @@ -76,12 +76,12 @@ public class CanAttackAsThoughItDidntHaveDefenderAllEffect extends AsThoughEffec Permanent permanent = game.getPermanent(objectId); return permanent != null && filter.match(permanent, game); } - + private String getText() { StringBuilder sb = new StringBuilder(filter.getMessage()); sb.append(" can attack "); - if (!duration.toString().isEmpty()) { - if(Duration.EndOfTurn.equals(duration)) { + if (!duration.toString().isEmpty()) { + if (Duration.EndOfTurn == duration) { sb.append("this turn"); } else { sb.append(duration.toString()); @@ -89,6 +89,6 @@ public class CanAttackAsThoughItDidntHaveDefenderAllEffect extends AsThoughEffec sb.append(' '); } sb.append("as though they didn't have defender"); - return sb.toString(); + return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderSourceEffect.java index cda6bf1b3f..8e8837ae69 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanAttackAsThoughItDidntHaveDefenderSourceEffect.java @@ -44,7 +44,7 @@ public class CanAttackAsThoughItDidntHaveDefenderSourceEffect extends AsThoughEf public CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration duration) { super(AsThoughEffectType.ATTACK, duration, Outcome.Benefit); staticText = "{this} can attack " - + (duration.equals(Duration.EndOfTurn) ? "this turn " : "") + + (duration == Duration.EndOfTurn ? "this turn " : "") + "as though it didn't have defender"; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockOnlyFlyingAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockOnlyFlyingAttachedEffect.java index 9053f62776..27026a5aab 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockOnlyFlyingAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CanBlockOnlyFlyingAttachedEffect.java @@ -37,7 +37,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author LevelX2 */ @@ -45,11 +44,7 @@ public class CanBlockOnlyFlyingAttachedEffect extends RestrictionEffect { public CanBlockOnlyFlyingAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can block only creatures with flying"; - } else { - this.staticText = "Equipped creature can block only creatures with flying"; - } + this.staticText = attachmentType.verb() + " creature can block only creatures with flying"; } public CanBlockOnlyFlyingAttachedEffect(final CanBlockOnlyFlyingAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneAttachedEffect.java index 79a28e2703..ec593c1f16 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAloneAttachedEffect.java @@ -20,11 +20,7 @@ public class CantAttackAloneAttachedEffect extends RestrictionEffect { public CantAttackAloneAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can't attack alone"; - } else { - this.staticText = "Equipped creature can't attack alone"; - } + this.staticText = attachmentType.verb() + " creature can't attack alone"; } public CantAttackAloneAttachedEffect(final CantAttackAloneAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAttachedEffect.java index ebea8a1e29..f2d549aafa 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackAttachedEffect.java @@ -44,11 +44,7 @@ public class CantAttackAttachedEffect extends RestrictionEffect { public CantAttackAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can't attack"; - } else { - this.staticText = "Equipped creature can't attack"; - } + this.staticText = attachmentType.verb() + " creature can't attack"; } public CantAttackAttachedEffect(final CantAttackAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java index 96a726b457..af046779ac 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java @@ -48,7 +48,7 @@ public class CantAttackBlockAllEffect extends RestrictionEffect { StringBuilder sb = new StringBuilder(filter.getMessage()).append(" can't attack or block"); if (!duration.toString().isEmpty()) { sb.append(' '); - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } else { sb.append(' ').append(duration.toString()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java index 5904f32957..ce15c24140 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockAttachedEffect.java @@ -35,18 +35,13 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author LevelX2 */ public class CantAttackBlockAttachedEffect extends RestrictionEffect { public CantAttackBlockAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can't attack or block"; - } else { - this.staticText = "Equipped creature can't attack or block"; - } + this.staticText = attachmentType.verb() + " creature can't attack or block"; } public CantAttackBlockAttachedEffect(final CantAttackBlockAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysAttachedEffect.java index 6d7a9c54d9..877fb04854 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysAttachedEffect.java @@ -46,8 +46,8 @@ public class CantAttackBlockUnlessPaysAttachedEffect extends PayCostToAttackBloc public CantAttackBlockUnlessPaysAttachedEffect(ManaCosts manaCosts, AttachmentType attachmentType) { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK_AND_BLOCK, manaCosts); - staticText = (attachmentType.equals(AttachmentType.AURA) ? "Enchanted " : "Equipped ") - + "creature can't attack or block unless its controller pays " + staticText = attachmentType.verb() + + " creature can't attack or block unless its controller pays " + (manaCosts == null ? "" : manaCosts.getText()); } @@ -59,10 +59,10 @@ public class CantAttackBlockUnlessPaysAttachedEffect extends PayCostToAttackBloc public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { - if (event.getType().equals(EventType.DECLARE_ATTACKER)) { + if (event.getType() == EventType.DECLARE_ATTACKER) { return event.getSourceId().equals(enchantment.getAttachedTo()); } - if (event.getType().equals(EventType.DECLARE_BLOCKER)) { + if (event.getType() == EventType.DECLARE_BLOCKER) { return event.getSourceId().equals(enchantment.getAttachedTo()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysSourceEffect.java index b7969dc5b4..c7408d5897 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackBlockUnlessPaysSourceEffect.java @@ -47,7 +47,7 @@ public class CantAttackBlockUnlessPaysSourceEffect extends PayCostToAttackBlockE super(Duration.WhileOnBattlefield, Outcome.Detriment, restrictType, cost); staticText = "{this} can't " + restrictType.toString() + " unless you " + cost == null ? "" : cost.getText() - + (restrictType.equals(RestrictType.ATTACK) ? " (This cost is paid as attackers are declared.)" : ""); + + (restrictType == RestrictType.ATTACK ? " (This cost is paid as attackers are declared.)" : ""); } public CantAttackBlockUnlessPaysSourceEffect(ManaCosts manaCosts, RestrictType restrictType) { @@ -62,10 +62,10 @@ public class CantAttackBlockUnlessPaysSourceEffect extends PayCostToAttackBlockE @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (!restrictType.equals(RestrictType.BLOCK) && event.getType().equals(EventType.DECLARE_ATTACKER)) { + if (!(restrictType == RestrictType.BLOCK) && event.getType() == EventType.DECLARE_ATTACKER) { return event.getSourceId().equals(source.getSourceId()); } - if (!restrictType.equals(RestrictType.ATTACK) && event.getType().equals(EventType.DECLARE_BLOCKER)) { + if (!(restrictType == RestrictType.ATTACK) && event.getType() == EventType.DECLARE_BLOCKER) { return event.getSourceId().equals(source.getSourceId()); } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java index 69c5101f3f..0a681b2d29 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackControllerAttachedEffect.java @@ -46,11 +46,7 @@ public class CantAttackControllerAttachedEffect extends RestrictionEffect { public CantAttackControllerAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can't attack you or a planeswalker you control"; - } else { - this.staticText = "Equipped creature can't attack you or a planeswalker you control"; - } + this.staticText = attachmentType.verb() + " creature can't attack you or a planeswalker you control"; } public CantAttackControllerAttachedEffect(final CantAttackControllerAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackUnlessPaysAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackUnlessPaysAttachedEffect.java index 5dee2cc0b1..9de2c1cd48 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackUnlessPaysAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackUnlessPaysAttachedEffect.java @@ -46,8 +46,8 @@ public class CantAttackUnlessPaysAttachedEffect extends PayCostToAttackBlockEffe public CantAttackUnlessPaysAttachedEffect(ManaCosts manaCosts, AttachmentType attachmentType) { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK, manaCosts); - staticText = (attachmentType.equals(AttachmentType.AURA) ? "Enchanted " : "Equipped ") - + "creature can't attack unless its controller pays " + staticText = attachmentType.verb() + + " creature can't attack unless its controller pays " + (manaCosts == null ? "" : manaCosts.getText()); } @@ -59,7 +59,7 @@ public class CantAttackUnlessPaysAttachedEffect extends PayCostToAttackBlockEffe public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { - if (event.getType().equals(EventType.DECLARE_ATTACKER)) { + if (event.getType() == EventType.DECLARE_ATTACKER) { return event.getSourceId().equals(enchantment.getAttachedTo()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouAllEffect.java index 82410c702b..7dc4efa76c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouAllEffect.java @@ -59,7 +59,7 @@ public class CantAttackYouAllEffect extends RestrictionEffect { this.alsoPlaneswalker = alsoPlaneswalker; staticText = filterAttacker.getMessage() + " can't attack you" + (alsoPlaneswalker ? " or a planeswalker you control" : "") - + (duration.equals(Duration.UntilYourNextTurn) ? " until your next turn" : ""); + + (duration == Duration.UntilYourNextTurn ? " until your next turn" : ""); } CantAttackYouAllEffect(final CantAttackYouAllEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAllEffect.java index 0a4ca0c1b8..d87d9978ff 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAllEffect.java @@ -47,7 +47,7 @@ public class CantBeBlockedAllEffect extends RestrictionEffect { this.filter = filter; this.staticText = filter.getMessage() + " can't be blocked"; - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { this.staticText += " this turn"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java index d995a52417..862ebd70c1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedAttachedEffect.java @@ -42,11 +42,7 @@ public class CantBeBlockedAttachedEffect extends RestrictionEffect { public CantBeBlockedAttachedEffect(AttachmentType attachmentType) { super(Duration.WhileOnBattlefield); - if (attachmentType.equals(AttachmentType.AURA)) { - this.staticText = "Enchanted creature can't be blocked"; - } else { - this.staticText = "Equipped creature can't be blocked"; - } + this.staticText = attachmentType.verb() + " creature can't be blocked"; } public CantBeBlockedAttachedEffect(CantBeBlockedAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByCreaturesAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByCreaturesAttachedEffect.java index 603ade5201..2e5c8a279a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByCreaturesAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByCreaturesAttachedEffect.java @@ -36,7 +36,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author LevelX2 */ public class CantBeBlockedByCreaturesAttachedEffect extends RestrictionEffect { @@ -47,13 +46,9 @@ public class CantBeBlockedByCreaturesAttachedEffect extends RestrictionEffect { super(duration); this.filter = filter; StringBuilder sb = new StringBuilder(); - if (attachmentType.equals(AttachmentType.AURA)) { - sb.append("Enchanted "); - } else { - sb.append("Equipped "); - } - staticText = sb.append("creature can't be blocked ") - .append(filter.getMessage().startsWith("except by") ? "":"by ").append(filter.getMessage()).toString(); + sb.append(attachmentType.verb()); + staticText = sb.append(" creature can't be blocked ") + .append(filter.getMessage().startsWith("except by") ? "" : "by ").append(filter.getMessage()).toString(); } public CantBeBlockedByCreaturesAttachedEffect(final CantBeBlockedByCreaturesAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java index 2762140573..6fd2ee2115 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAllEffect.java @@ -56,7 +56,7 @@ public class CantBeBlockedByOneAllEffect extends ContinuousEffectImpl { this.amount = amount; this.filter = filter; StringBuilder sb = new StringBuilder("each ").append(filter.getMessage()).append(" can't be blocked "); - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append("this turn "); } sb.append("except by ").append(CardUtil.numberToText(amount)).append(" or more creatures"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java index b28abb1b23..fd5b60d303 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByOneAttachedEffect.java @@ -54,7 +54,7 @@ public class CantBeBlockedByOneAttachedEffect extends ContinuousEffectImpl { super(duration, Outcome.Benefit); this.amount = amount; this.attachmentType = attachmentType; - staticText = (attachmentType.equals(AttachmentType.AURA) ? "Enchanted" : "Equipped") + " creature can't be blocked except by " + amount + " or more creatures"; + staticText = attachmentType.verb() + " creature can't be blocked except by " + amount + " or more creatures"; } public CantBeBlockedByOneAttachedEffect(final CantBeBlockedByOneAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByTargetSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByTargetSourceEffect.java index 1acc83c3b3..20317444d8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByTargetSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedByTargetSourceEffect.java @@ -93,7 +93,7 @@ public class CantBeBlockedByTargetSourceEffect extends RestrictionEffect { sb.append("Target "); } sb.append(target.getTargetName()).append(" can't block {this}"); - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedSourceEffect.java index 65397f268d..3e7a3c2df5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBeBlockedSourceEffect.java @@ -45,7 +45,7 @@ public class CantBeBlockedSourceEffect extends RestrictionEffect { public CantBeBlockedSourceEffect(Duration duration) { super(duration); this.staticText = "{this} can't be blocked"; - if (Duration.EndOfTurn.equals(this.duration)) { + if (this.duration == Duration.EndOfTurn) { this.staticText += " this turn"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java index 6b2206a436..11fcccee32 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAllEffect.java @@ -72,7 +72,7 @@ public class CantBlockAllEffect extends RestrictionEffect { public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); sb.append(filter.getMessage()).append(" can't block"); - if (Duration.EndOfTurn.equals(this.duration)) { + if (this.duration == Duration.EndOfTurn) { sb.append(" this turn"); } return sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java index 50927b66ab..76a23da819 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockAttachedEffect.java @@ -56,11 +56,8 @@ public class CantBlockAttachedEffect extends RestrictionEffect { super(duration); this.filter = filter; StringBuilder sb = new StringBuilder(); - if (attachmentType.equals(AttachmentType.AURA)) { - sb.append("Enchanted creature can't block"); - } else { - sb.append("Equipped creature can't block"); - } + sb.append(attachmentType.verb()); + sb.append(" creature can't block"); if (!filter.getMessage().equals("creature")) { sb.append(' ').append(filter.getMessage()); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockSourceEffect.java index f36ec2805c..ca99b4bcd8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockSourceEffect.java @@ -43,7 +43,7 @@ public class CantBlockSourceEffect extends RestrictionEffect { public CantBlockSourceEffect(Duration duration) { super(duration); this.staticText = "{this} can't block"; - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { this.staticText += " this turn"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockTargetEffect.java index 5e61b12edd..1cb92d7535 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantBlockTargetEffect.java @@ -89,7 +89,7 @@ public class CantBlockTargetEffect extends RestrictionEffect { } sb.append(" can't block"); - if (Duration.EndOfTurn.equals(this.duration)) { + if (this.duration == Duration.EndOfTurn) { sb.append(" this turn"); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllAttachedEffect.java index c64e8a662c..24fa94d0b0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllAttachedEffect.java @@ -29,6 +29,7 @@ package mage.abilities.effects.common.combat; import java.util.UUID; + import mage.constants.AttachmentType; import mage.constants.Duration; import mage.abilities.Ability; @@ -37,7 +38,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author LevelX2 */ public class MustBeBlockedByAllAttachedEffect extends RequirementEffect { @@ -51,7 +51,7 @@ public class MustBeBlockedByAllAttachedEffect extends RequirementEffect { public MustBeBlockedByAllAttachedEffect(Duration duration, AttachmentType attachmentType) { super(duration); this.attachmentType = attachmentType; - staticText = "All creatures able to block " + (attachmentType.equals(AttachmentType.AURA) ? "enchanted":"equipped") + " creature do so"; + staticText = "All creatures able to block " + attachmentType.verb().toLowerCase() + " creature do so"; } public MustBeBlockedByAllAttachedEffect(final MustBeBlockedByAllAttachedEffect effect) { @@ -84,7 +84,7 @@ public class MustBeBlockedByAllAttachedEffect extends RequirementEffect { public UUID mustBlockAttacker(Ability source, Game game) { Permanent attachment = game.getPermanent(source.getSourceId()); if (attachment != null && attachment.getAttachedTo() != null) { - return attachment.getAttachedTo() ; + return attachment.getAttachedTo(); } return null; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllTargetEffect.java index 7f8dd5e81f..f242fd2cf5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAllTargetEffect.java @@ -46,7 +46,7 @@ public class MustBeBlockedByAllTargetEffect extends RequirementEffect { public MustBeBlockedByAllTargetEffect(Duration duration) { super(duration); staticText = new StringBuilder("All creatures able to block target creature ") - .append(this.getDuration().equals(Duration.EndOfTurn) ? "this turn ":"") + .append(this.getDuration() == Duration.EndOfTurn ? "this turn ":"") .append("do so").toString(); } @@ -58,7 +58,7 @@ public class MustBeBlockedByAllTargetEffect extends RequirementEffect { public boolean applies(Permanent permanent, Ability source, Game game) { Permanent attackingCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (attackingCreature != null && attackingCreature.isAttacking()) { - if (!source.getAbilityType().equals(AbilityType.STATIC)) { + if (source.getAbilityType() != AbilityType.STATIC) { BlockedAttackerWatcher blockedAttackerWatcher = (BlockedAttackerWatcher) game.getState().getWatchers().get("BlockedAttackerWatcher"); if (blockedAttackerWatcher != null && blockedAttackerWatcher.creatureHasBlockedAttacker(attackingCreature, permanent, game)) { // has already blocked this turn, so no need to do again diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardColorAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardColorAttachedEffect.java index cab6d29e66..538d422096 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardColorAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardColorAttachedEffect.java @@ -84,11 +84,7 @@ public class AddCardColorAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) - sb.append("Enchanted"); - else if (attachmentType == AttachmentType.EQUIPMENT) - sb.append("Equipped"); - + sb.append(attachmentType.verb()); sb.append(" creature is a ").append(addedColor.getDescription()).append(" in addition to its colors"); staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java index f58836f257..a32141d8c7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java @@ -62,7 +62,7 @@ public class AddCardSubTypeTargetEffect extends ContinuousEffectImpl { target.getSubtype(game).add(addedSubType); } } else { - if (Duration.Custom.equals(duration)) { + if (duration == Duration.Custom) { discard(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubtypeAttachedEffect.java index 8811d631cc..b22025852c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardSubtypeAttachedEffect.java @@ -72,11 +72,8 @@ public class AddCardSubtypeAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) - sb.append("Enchanted"); - else if (attachmentType == AttachmentType.EQUIPMENT) - sb.append("Equipped"); + sb.append(attachmentType.verb()); sb.append(" creature becomes ").append(addedSubtype).append(" in addition to its other types"); //TODO add attacked card type detection staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java index 0d42828dd0..2886bdf363 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java @@ -72,11 +72,7 @@ public class AddCardTypeAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) - sb.append("Enchanted"); - else if (attachmentType == AttachmentType.EQUIPMENT) - sb.append("Equipped"); - + sb.append(attachmentType.verb()); sb.append(" creature becomes ").append(addedCardType.toString()).append(" in addition to its other types"); //TODO add attacked card type detection staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java index fa695f368f..a76b352761 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common.continuous; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffectImpl; @@ -49,7 +50,7 @@ public class AddCardTypeSourceEffect extends ContinuousEffectImpl { public AddCardTypeSourceEffect(CardType addedCardType, Duration duration) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.addedCardType = addedCardType; - if (addedCardType.equals(CardType.ENCHANTMENT)) { + if (addedCardType == CardType.ENCHANTMENT) { dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); } } @@ -59,16 +60,27 @@ public class AddCardTypeSourceEffect extends ContinuousEffectImpl { this.addedCardType = effect.addedCardType; } + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (Duration.Custom.equals(this.duration) || this.duration.toString().startsWith("End")) { + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()), game)); + if (affectedObjectList.isEmpty()) { + this.discard(); + } + } + } + @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { + if (permanent != null + && (affectedObjectList.isEmpty() || affectedObjectList.contains(new MageObjectReference(permanent, game)))) { if (!permanent.getCardType().contains(addedCardType)) { permanent.getCardType().add(addedCardType); } return true; - } - else if (this.getDuration().equals(Duration.Custom)) { + } else if (this.getDuration().equals(Duration.Custom)) { this.discard(); } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java index 665f4b28cc..56981a038f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java @@ -50,9 +50,9 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { public AddCardTypeTargetEffect(CardType addedCardType, Duration duration) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.addedCardType = addedCardType; - if (addedCardType.equals(CardType.ENCHANTMENT)) { + if (addedCardType == CardType.ENCHANTMENT) { dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); - } else if (addedCardType.equals(CardType.ARTIFACT)) { + } else if (addedCardType == CardType.ARTIFACT) { dependencyTypes.add(DependencyType.ArtifactAddingRemoving); } } @@ -75,7 +75,7 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { } } if (!result) { - if (this.getDuration().equals(Duration.Custom)) { + if (this.getDuration() == Duration.Custom) { this.discard(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java index 1e32816cce..12d8955d1d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeAllEffect.java @@ -130,7 +130,7 @@ public class CantGainLifeAllEffect extends ContinuousEffectImpl { sb.append(" can't gain life"); if (!this.duration.toString().isEmpty()) { sb.append(' '); - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append("this turn"); } else { sb.append(duration.toString()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java index 7ac097963a..18af3f8478 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantGainLifeTargetEffect.java @@ -48,7 +48,7 @@ public class CantGainLifeTargetEffect extends ContinuousEffectImpl { super(duration, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); StringBuilder sb = new StringBuilder("If that player would gain life"); if (!this.duration.toString().isEmpty()) { - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append("this turn, "); } else { sb.append(' ').append(duration.toString()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java index ab7967dc1d..b1b2623be4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CastAsThoughItHadFlashAllEffect.java @@ -94,7 +94,7 @@ public class CastAsThoughItHadFlashAllEffect extends AsThoughEffectImpl { sb.append(" may cast "); sb.append(filter.getMessage()); if (!duration.toString().isEmpty()) { - if (duration.equals(Duration.EndOfTurn)) { + if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } else { sb.append(' '); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/DamageCantBePreventedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/DamageCantBePreventedEffect.java index 08b432f31b..56d08fdbab 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/DamageCantBePreventedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/DamageCantBePreventedEffect.java @@ -29,7 +29,7 @@ public class DamageCantBePreventedEffect extends ContinuousRuleModifyingEffectIm @Override public boolean checksEventType(GameEvent event, Game game) { - return event.getType().equals(GameEvent.EventType.PREVENT_DAMAGE); + return event.getType() == GameEvent.EventType.PREVENT_DAMAGE; } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java index 90734de9f2..543c49bab4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java @@ -124,11 +124,7 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) { - sb.append("Enchanted"); - } else if (attachmentType == AttachmentType.EQUIPMENT) { - sb.append("Equipped"); - } + sb.append(attachmentType.verb()); sb.append(" creature "); if (duration == Duration.WhileOnBattlefield) { sb.append("has "); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityAttachedEffect.java index 7315dd2005..82fd03fdaa 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityAttachedEffect.java @@ -83,11 +83,7 @@ public class LoseAbilityAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) { - sb.append("Enchanted"); - } else if (attachmentType == AttachmentType.EQUIPMENT) { - sb.append("Equipped"); - } + sb.append(attachmentType.verb()); sb.append(" creature "); if (duration == Duration.WhileOnBattlefield) { sb.append("loses "); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/MaximumHandSizeControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/MaximumHandSizeControllerEffect.java index 8ea40207d6..e81642e823 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/MaximumHandSizeControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/MaximumHandSizeControllerEffect.java @@ -46,7 +46,7 @@ import mage.util.CardUtil; */ public class MaximumHandSizeControllerEffect extends ContinuousEffectImpl { - public static enum HandSizeModification { + public enum HandSizeModification { SET, INCREASE, REDUCE } @@ -90,8 +90,8 @@ public class MaximumHandSizeControllerEffect extends ContinuousEffectImpl { protected static Outcome defineOutcome(HandSizeModification handSizeModification, TargetController targetController) { Outcome newOutcome = Outcome.Benefit; - if ((targetController.equals(TargetController.YOU) || targetController.equals(TargetController.ANY)) - && handSizeModification.equals(HandSizeModification.REDUCE)) { + if ((targetController == TargetController.YOU || targetController == TargetController.ANY) + && handSizeModification == HandSizeModification.REDUCE) { newOutcome = Outcome.Detriment; } return newOutcome; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayAdditionalLandsControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayAdditionalLandsControllerEffect.java index 8d84b19e7c..c7395e98b9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayAdditionalLandsControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayAdditionalLandsControllerEffect.java @@ -38,7 +38,6 @@ import mage.game.Game; import mage.players.Player; /** - * * @author Viserion */ public class PlayAdditionalLandsControllerEffect extends ContinuousEffectImpl { @@ -65,10 +64,9 @@ public class PlayAdditionalLandsControllerEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - if(player.getLandsPerTurn() == Integer.MAX_VALUE || this.additionalCards == Integer.MAX_VALUE){ + if (player.getLandsPerTurn() == Integer.MAX_VALUE || this.additionalCards == Integer.MAX_VALUE) { player.setLandsPerTurn(Integer.MAX_VALUE); - } - else{ + } else { player.setLandsPerTurn(player.getLandsPerTurn() + this.additionalCards); } return true; @@ -79,15 +77,13 @@ public class PlayAdditionalLandsControllerEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); sb.append("You may play "); - if(additionalCards == Integer.MAX_VALUE){ + if (additionalCards == Integer.MAX_VALUE) { sb.append("any number of"); + } else { + sb.append(Integer.toString(additionalCards)); } - else - { - sb.append(Integer.toString(additionalCards)); - } - sb.append(" additional land").append((additionalCards == 1 ? "" : "s")) - .append(duration == Duration.EndOfTurn ? " this turn" : " on each of your turns"); + sb.append(" additional land").append((additionalCards == 1 ? "" : "s")) + .append(duration == Duration.EndOfTurn ? " this turn" : " on each of your turns"); staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayWithHandRevealedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayWithHandRevealedEffect.java index 4ae3e82e0d..7a3ba37830 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayWithHandRevealedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayWithHandRevealedEffect.java @@ -71,7 +71,7 @@ public class PlayWithHandRevealedEffect extends ContinuousEffectImpl { affectedPlayers = game.getOpponents(source.getControllerId()); break; case YOU: - ArrayList tmp = new ArrayList<>(); + ArrayList tmp = new ArrayList<>(); tmp.add(source.getControllerId()); affectedPlayers = tmp; break; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardColorAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardColorAttachedEffect.java index 1de431c2d1..c11f4dcdf3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardColorAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardColorAttachedEffect.java @@ -75,11 +75,7 @@ public class SetCardColorAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) - sb.append("Enchanted"); - else if (attachmentType == AttachmentType.EQUIPMENT) - sb.append("Equipped"); - + sb.append(attachmentType.verb()); sb.append(" creature is ").append(setColor.getDescription()); staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index cb528774c9..f9c06e4bf7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -29,6 +29,7 @@ package mage.abilities.effects.common.continuous; import java.util.ArrayList; import java.util.List; + import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.repository.CardRepository; @@ -88,12 +89,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { private void setText() { StringBuilder sb = new StringBuilder(); - if (attachmentType == AttachmentType.AURA) { - sb.append("Enchanted"); - } else if (attachmentType == AttachmentType.EQUIPMENT) { - sb.append("Equipped"); - } - + sb.append(attachmentType.verb()); sb.append(" creature is a"); for (String subtype : this.setSubtypes) { sb.append(' ').append(subtype); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java index 5947dbdb31..8182274c24 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java @@ -85,7 +85,7 @@ public class SetPowerToughnessSourceEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { - if (duration.equals(Duration.Custom) || isTemporary()) { + if (duration == Duration.Custom || isTemporary()) { mageObject = game.getPermanent(source.getSourceId()); } else { mageObject = game.getObject(source.getSourceId()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java index f14ea6a4ce..a13e3178d6 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessSourceEffect.java @@ -37,7 +37,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author North */ public class SwitchPowerToughnessSourceEffect extends ContinuousEffectImpl { @@ -58,7 +57,7 @@ public class SwitchPowerToughnessSourceEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Permanent target = (Permanent) game.getPermanent(source.getSourceId()); + Permanent target = game.getPermanent(source.getSourceId()); if (target != null) { int power = target.getPower().getValue(); target.getPower().setValue(target.getToughness().getValue()); @@ -68,4 +67,4 @@ public class SwitchPowerToughnessSourceEffect extends ContinuousEffectImpl { return false; } - } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessTargetEffect.java index 759ae59865..316e5cd36a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SwitchPowerToughnessTargetEffect.java @@ -39,7 +39,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; /** - * * @author ayratn */ public class SwitchPowerToughnessTargetEffect extends ContinuousEffectImpl { @@ -59,7 +58,7 @@ public class SwitchPowerToughnessTargetEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Permanent target = (Permanent) game.getPermanent(source.getFirstTarget()); + Permanent target = game.getPermanent(source.getFirstTarget()); if (target != null) { int power = target.getPower().getValue(); target.getPower().setValue(target.getToughness().getValue()); @@ -73,7 +72,7 @@ public class SwitchPowerToughnessTargetEffect extends ContinuousEffectImpl { public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); sb.append("Switch target ").append(mode.getTargets().get(0).getTargetName()).append("'s power and toughness") - .append(' ').append(duration.toString()); + .append(' ').append(duration.toString()); return sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java index 2b74dc176a..9fb4fabaef 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapAllDuringEachOtherPlayersUntapStepEffect.java @@ -69,7 +69,7 @@ public class UntapAllDuringEachOtherPlayersUntapStepEffect extends ContinuousEff if (applied == null) { applied = Boolean.FALSE; } - if (!applied && layer.equals(Layer.RulesEffects)) { + if (!applied && layer == Layer.RulesEffects) { if (!source.getControllerId().equals(game.getActivePlayerId()) && game.getStep().getType() == PhaseStep.UNTAP) { game.getState().setValue(source.getSourceId() + "applied", true); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java index 4d7010102b..b0eaa7ed3c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/UntapSourceDuringEachOtherPlayersUntapStepEffect.java @@ -64,7 +64,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous if (applied == null) { applied = Boolean.FALSE; } - if (!applied && layer.equals(Layer.RulesEffects)) { + if (!applied && layer == Layer.RulesEffects) { if (!source.getControllerId().equals(game.getActivePlayerId()) && game.getStep() != null && game.getStep().getType() == PhaseStep.UNTAP) { @@ -80,7 +80,7 @@ public class UntapSourceDuringEachOtherPlayersUntapStepEffect extends Continuous } } } - } else if (applied && layer.equals(Layer.RulesEffects)) { + } else if (applied && layer == Layer.RulesEffects) { if (game.getStep() != null && game.getStep().getType() == PhaseStep.END_TURN) { game.getState().setValue(source.getSourceId() + "applied", false); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/ProliferateEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/ProliferateEffect.java index c18d4030f0..b50b5adbbb 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/ProliferateEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/ProliferateEffect.java @@ -71,8 +71,7 @@ public class ProliferateEffect extends OneShotEffect { options.put("UI.right.btn.text", "Done"); controller.choose(Outcome.Benefit, target, source.getSourceId(), game, options); - for (int idx = 0; idx < target.getTargets().size(); idx++) { - UUID chosen = (UUID) target.getTargets().get(idx); + for (UUID chosen : target.getTargets()) { Permanent permanent = game.getPermanent(chosen); if (permanent != null) { if (!permanent.getCounters(game).isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CastOnlyDuringPhaseStepSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CastOnlyDuringPhaseStepSourceEffect.java index c20202dfc9..ccd8fcfbe1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CastOnlyDuringPhaseStepSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ruleModifying/CastOnlyDuringPhaseStepSourceEffect.java @@ -16,7 +16,6 @@ import mage.game.Game; import mage.game.events.GameEvent; /** - * * @author LevelX2 */ public class CastOnlyDuringPhaseStepSourceEffect extends ContinuousRuleModifyingEffectImpl { @@ -49,8 +48,8 @@ public class CastOnlyDuringPhaseStepSourceEffect extends ContinuousRuleModifying public boolean applies(GameEvent event, Ability source, Game game) { // has to return true, if the spell cannot be cast in the current phase / step if (event.getSourceId().equals(source.getSourceId())) { - if ((turnPhase != null && !game.getPhase().getType().equals(turnPhase)) - || (phaseStep != null && !game.getTurn().getStepType().equals(phaseStep)) + if ((turnPhase != null && game.getPhase().getType() != turnPhase) + || (phaseStep != null && (game.getTurn().getStepType() != phaseStep)) || (condition != null && !condition.apply(game, source))) { return true; } diff --git a/Mage/src/main/java/mage/constants/AttachmentType.java b/Mage/src/main/java/mage/constants/AttachmentType.java index c6a7ece88c..238fe1ca88 100644 --- a/Mage/src/main/java/mage/constants/AttachmentType.java +++ b/Mage/src/main/java/mage/constants/AttachmentType.java @@ -5,6 +5,16 @@ package mage.constants; * @author North */ public enum AttachmentType { - EQUIPMENT, - AURA + EQUIPMENT("Equipped"), + AURA("Enchanted"); + + String verb; + + public String verb(){ + return verb; + } + + AttachmentType(String verb){ + this.verb = verb; + } } diff --git a/Mage/src/main/java/mage/constants/PhaseStep.java b/Mage/src/main/java/mage/constants/PhaseStep.java index 06bd7427df..f6bb690515 100644 --- a/Mage/src/main/java/mage/constants/PhaseStep.java +++ b/Mage/src/main/java/mage/constants/PhaseStep.java @@ -1,5 +1,7 @@ package mage.constants; +import mage.game.turn.Phase; + /** * * @author North @@ -33,6 +35,14 @@ public enum PhaseStep { this.stepText = stepText; } + public boolean isBefore(PhaseStep other){ + return this.getIndex()other.getIndex(); + } + public int getIndex() { return index; } diff --git a/Mage/src/main/java/mage/game/Table.java b/Mage/src/main/java/mage/game/Table.java index 1a019a24a7..44b04c1205 100644 --- a/Mage/src/main/java/mage/game/Table.java +++ b/Mage/src/main/java/mage/game/Table.java @@ -30,7 +30,9 @@ package mage.game; import java.io.Serializable; import java.util.Arrays; import java.util.Date; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import mage.cards.decks.DeckValidator; import mage.constants.TableState; @@ -63,6 +65,7 @@ public class Table implements Serializable { private Match match; private Tournament tournament; private TableRecorder recorder; + private Set bannedUsernames; @FunctionalInterface public interface TableRecorder { @@ -71,21 +74,21 @@ public class Table implements Serializable { protected TableEventSource tableEventSource = new TableEventSource(); - public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder, Tournament tournament) { - this(roomId, gameType, name, controllerName, validator, playerTypes, recorder); + public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder, Tournament tournament, Set bannedUsernames) { + this(roomId, gameType, name, controllerName, validator, playerTypes, recorder, bannedUsernames); this.tournament = tournament; this.isTournament = true; setState(TableState.WAITING); } - public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder, Match match) { - this(roomId, gameType, name, controllerName, validator, playerTypes, recorder); + public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder, Match match, Set bannedUsernames) { + this(roomId, gameType, name, controllerName, validator, playerTypes, recorder, bannedUsernames); this.match = match; this.isTournament = false; setState(TableState.WAITING); } - protected Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder) { + protected Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List playerTypes, TableRecorder recorder, Set bannedUsernames) { tableId = UUID.randomUUID(); this.roomId = roomId; this.numSeats = playerTypes.size(); @@ -96,6 +99,7 @@ public class Table implements Serializable { createSeats(playerTypes); this.validator = validator; this.recorder = recorder; + this.bannedUsernames = new HashSet<>(bannedUsernames); } private void createSeats(List playerTypes) { @@ -308,6 +312,10 @@ public class Table implements Serializable { } } + public boolean userIsBanned(String username) { + return bannedUsernames.contains(username); + } + public TableProto toProto() { TableProto.Builder builder = TableProto.newBuilder(); if (this.isTournament()) { diff --git a/Mage/src/main/java/mage/game/match/MatchOptions.java b/Mage/src/main/java/mage/game/match/MatchOptions.java index 3bcd909ab8..3b581aef1b 100644 --- a/Mage/src/main/java/mage/game/match/MatchOptions.java +++ b/Mage/src/main/java/mage/game/match/MatchOptions.java @@ -30,7 +30,9 @@ package mage.game.match; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import mage.constants.MatchTimeLimit; import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; @@ -61,6 +63,7 @@ public class MatchOptions implements Serializable { protected int edhPowerLevel; protected boolean rated; protected int numSeatsForMatch; + protected Set bannedUsers = new HashSet<>(); /** * Time each player has during the game to play using his\her priority. @@ -226,6 +229,14 @@ public class MatchOptions implements Serializable { this.rated = rated; } + public Set getBannedUsers() { + return bannedUsers; + } + + public void setBannedUsers(Set bannedUsers) { + this.bannedUsers = bannedUsers; + } + public ResultProtos.MatchOptionsProto toProto() { ResultProtos.MatchOptionsProto.Builder builder = ResultProtos.MatchOptionsProto.newBuilder() .setName(this.getName()) diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 2160a426cb..e7fbfc40be 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -28,7 +28,6 @@ package mage.game.permanent; import java.util.*; - import mage.MageObject; import mage.MageObjectReference; import mage.ObjectColor; @@ -751,7 +750,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (source != null && sourceAbilities != null) { if (sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) { Player player = game.getPlayer(sourceControllerId); - player.gainLife(damageAmount, game); + player.gainLife(damageDone, game); } if (sourceAbilities.containsKey(DeathtouchAbility.getInstance().getId())) { deathtouched = true; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index e162bc382d..0ec4220302 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -3067,7 +3067,7 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean canJoinTable(Table table) { - return true; + return !table.userIsBanned(name); } @Override diff --git a/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java index 556199213f..5fb2de58c2 100644 --- a/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/FirstSpellCastThisTurnWatcher.java @@ -3,7 +3,6 @@ package mage.watchers.common; import java.util.HashMap; import java.util.Map; import java.util.UUID; - import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; @@ -26,7 +25,7 @@ public class FirstSpellCastThisTurnWatcher extends Watcher { public FirstSpellCastThisTurnWatcher(final FirstSpellCastThisTurnWatcher watcher) { super(watcher); playerFirstSpellCast.putAll(watcher.playerFirstSpellCast); - playerFirstCastSpell.putAll(watcher.playerFirstSpellCast); + playerFirstCastSpell.putAll(watcher.playerFirstCastSpell); } @Override diff --git a/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldWatcher.java b/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldWatcher.java index e8036d18e8..d91b10e583 100644 --- a/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/PermanentsEnteredBattlefieldWatcher.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; +import mage.constants.CardType; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; @@ -75,7 +76,8 @@ public class PermanentsEnteredBattlefieldWatcher extends Watcher { if (enteringBattlefieldLastTurn.containsKey(sourcePermanent.getControllerId())) { for (Permanent permanent : enteringBattlefieldLastTurn.get(sourcePermanent.getControllerId())) { if (!permanent.getId().equals(sourcePermanent.getId()) - || permanent.getZoneChangeCounter(game) != sourcePermanent.getZoneChangeCounter(game)) { + //|| permanent.getZoneChangeCounter(game) == sourcePermanent.getZoneChangeCounter(game) why is this needed? + && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage/src/test/java/mage/ManaTest.java b/Mage/src/test/java/mage/ManaTest.java index b40b0a4562..2f49626955 100644 --- a/Mage/src/test/java/mage/ManaTest.java +++ b/Mage/src/test/java/mage/ManaTest.java @@ -6,6 +6,7 @@ import mage.constants.ManaType; import mage.filter.FilterMana; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotSame; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -527,7 +528,7 @@ public class ManaTest { // then assertEquals(mana, copy); // are equal - assertFalse(Objects.equals(mana, copy)); // are not the same object + assertNotSame(mana, copy); // are not the same object } @Test @@ -605,7 +606,7 @@ public class ManaTest { // then assertEquals(mana, newMana); - assertFalse(Objects.equals(mana, newMana)); + assertNotSame(mana, newMana); } @Test diff --git a/Mage/src/test/java/mage/counters/CounterTest.java b/Mage/src/test/java/mage/counters/CounterTest.java index 70c33aab49..ae66b60780 100644 --- a/Mage/src/test/java/mage/counters/CounterTest.java +++ b/Mage/src/test/java/mage/counters/CounterTest.java @@ -60,7 +60,7 @@ public class CounterTest { // then assertEquals(copy, counter); - assertFalse(Objects.equals(copy, counter)); + assertNotSame(copy, counter); } @Test