diff --git a/Mage.Client/src/main/java/mage/client/SessionHandler.java b/Mage.Client/src/main/java/mage/client/SessionHandler.java index a690513ec5d..97a183c3cad 100644 --- a/Mage.Client/src/main/java/mage/client/SessionHandler.java +++ b/Mage.Client/src/main/java/mage/client/SessionHandler.java @@ -1,13 +1,12 @@ package mage.client; -import java.util.*; - import mage.cards.decks.DeckCardLists; import mage.client.chat.LocalCommands; import mage.constants.ManaType; import mage.constants.PlayerAction; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.players.net.UserData; import mage.remote.Connection; import mage.remote.MageRemoteException; @@ -15,6 +14,8 @@ import mage.remote.Session; import mage.remote.SessionImpl; import mage.view.*; +import java.util.*; + /** * Created by IGOUDT on 15-9-2016. */ @@ -91,11 +92,11 @@ public final class SessionHandler { session.sendPlayerBoolean(gameId, b); } - public static String[] getPlayerTypes() { + public static PlayerType[] getPlayerTypes() { return session.getPlayerTypes(); } - public static boolean joinTournamentTable(UUID roomId, UUID tableId, String text, String selectedItem, Integer integer, DeckCardLists deckCardLists, String s) { + public static boolean joinTournamentTable(UUID roomId, UUID tableId, String text, PlayerType selectedItem, Integer integer, DeckCardLists deckCardLists, String s) { return session.joinTournamentTable(roomId, tableId, text, selectedItem, integer, deckCardLists, s); } @@ -233,7 +234,7 @@ public final class SessionHandler { return session.createTable(roomId, options); } - public static boolean joinTable(UUID roomId, UUID tableId, String playerName, String human, int skill, DeckCardLists deckCardLists, String text) { + public static boolean joinTable(UUID roomId, UUID tableId, String playerName, PlayerType human, int skill, DeckCardLists deckCardLists, String text) { return session.joinTable(roomId, tableId, playerName, human, skill, deckCardLists, text); } diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.java b/Mage.Client/src/main/java/mage/client/cards/CardsList.java index 45d106c187e..fafdece0c1d 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -33,26 +33,6 @@ */ package mage.client.cards; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Rectangle; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.beans.Beans; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JTable; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; import mage.cards.MageCard; import mage.client.constants.Constants.DeckEditorMode; import mage.client.constants.Constants.SortBy; @@ -61,15 +41,8 @@ import mage.client.deckeditor.table.TableModel; import mage.client.deckeditor.table.UpdateCountsCallback; import mage.client.dialog.PreferencesDialog; import mage.client.plugins.impl.Plugins; -import mage.client.util.CardViewCardTypeComparator; -import mage.client.util.CardViewColorComparator; -import mage.client.util.CardViewColorIdentityComparator; -import mage.client.util.CardViewCostComparator; -import mage.client.util.CardViewNameComparator; -import mage.client.util.CardViewRarityComparator; +import mage.client.util.*; import mage.client.util.Event; -import mage.client.util.GUISizeHelper; -import mage.client.util.Listener; import mage.client.util.gui.TableSpinnerEditor; import mage.constants.CardType; import mage.view.CardView; @@ -77,6 +50,18 @@ import mage.view.CardsView; import mage.view.SimpleCardView; import org.mage.card.arcane.CardPanel; +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.beans.Beans; +import java.util.*; +import java.util.List; + /** * * @author BetaSteward_at_googlemail.com diff --git a/Mage.Client/src/main/java/mage/client/cards/Permanent.java b/Mage.Client/src/main/java/mage/client/cards/Permanent.java index f23c01cc885..b057f80af03 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Permanent.java +++ b/Mage.Client/src/main/java/mage/client/cards/Permanent.java @@ -34,28 +34,25 @@ package mage.client.cards; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.RenderingHints; +import mage.cards.CardDimensions; +import mage.cards.MagePermanent; +import mage.cards.Sets; +import mage.client.util.Config; +import mage.client.util.TransformedImageCache; +import mage.constants.CardType; +import mage.view.CounterView; +import mage.view.PermanentView; + +import javax.swing.*; +import java.awt.*; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import javax.swing.PopupFactory; -import mage.cards.CardDimensions; -import mage.cards.MagePermanent; -import mage.cards.Sets; + import static mage.client.constants.Constants.DAMAGE_MAX_LEFT; import static mage.client.constants.Constants.POWBOX_TEXT_MAX_TOP; -import mage.client.util.Config; -import mage.constants.CardType; -import mage.view.CounterView; -import mage.view.PermanentView; -import mage.client.util.TransformedImageCache; /** * diff --git a/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java b/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java index f7e03f4e9c9..0c06598ab1e 100644 --- a/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java +++ b/Mage.Client/src/main/java/mage/client/chat/LocalCommands.java @@ -4,6 +4,7 @@ import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.util.IgnoreList; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.view.ChatMessage; import java.text.DateFormat; @@ -58,7 +59,7 @@ public final class LocalCommands { private static void displayLocalCommandResponse(UUID chatId, String response) { final String text = new StringBuilder().append("").append(response).append("").toString(); - ClientCallback chatMessage = new ClientCallback("chatMessage", chatId, + ClientCallback chatMessage = new ClientCallback(ClientCallbackMethod.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/components/MageUI.java b/Mage.Client/src/main/java/mage/client/components/MageUI.java index 48c14687f4a..86db500ea86 100644 --- a/Mage.Client/src/main/java/mage/client/components/MageUI.java +++ b/Mage.Client/src/main/java/mage/client/components/MageUI.java @@ -3,6 +3,7 @@ package mage.client.components; import java.awt.Component; import java.util.EnumMap; import java.util.Map; +import java.util.concurrent.TimeUnit; import javax.swing.JButton; public class MageUI { @@ -92,9 +93,9 @@ public class MageUI { public void doClick(MageComponents name, int waitBeforeClick) throws InterruptedException { final JButton j = getButton(name); - Thread.sleep(waitBeforeClick); + TimeUnit.MILLISECONDS.sleep(waitBeforeClick); while (!j.isEnabled()) { - Thread.sleep(10); + TimeUnit.MILLISECONDS.sleep(10); } Thread t = new Thread(() -> j.doClick()); t.start(); diff --git a/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java index c193da98e34..43810b3e3e9 100644 --- a/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java +++ b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java @@ -1,7 +1,7 @@ package mage.client.components.tray; import java.awt.*; - +import java.util.concurrent.TimeUnit; import mage.client.MageFrame; import org.apache.log4j.Logger; import org.mage.plugins.card.utils.impl.ImageManagerImpl; @@ -21,7 +21,6 @@ public enum MageTray { private int state = 0; - public void install() { if (!SystemTray.isSupported()) { log.warn("SystemTray is not supported"); @@ -97,7 +96,7 @@ public enum MageTray { int i = 0; while (state != 3) { trayIcon.setImage(i == 0 ? mainImage : flashedImage); - Thread.sleep(600); + TimeUnit.MILLISECONDS.sleep(600); i = i == 0 ? 1 : 0; } trayIcon.setImage(mainImage); diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 32afd8a7bfc..6ac79cc17b7 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -44,7 +44,6 @@ import java.util.concurrent.TimeUnit; import javax.swing.*; import javax.swing.Timer; import javax.swing.filechooser.FileFilter; - import mage.cards.Card; import mage.cards.Sets; import mage.cards.decks.Deck; @@ -58,8 +57,8 @@ import mage.client.SessionHandler; import mage.client.cards.BigCard; import mage.client.cards.ICardGrid; import mage.client.constants.Constants.DeckEditorMode; -import mage.client.deck.generator.DeckGenerator.DeckGeneratorException; import mage.client.deck.generator.DeckGenerator; +import mage.client.deck.generator.DeckGenerator.DeckGeneratorException; import mage.client.dialog.AddLandDialog; import mage.client.dialog.PreferencesDialog; import mage.client.plugins.impl.Plugins; @@ -189,7 +188,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { case LIMITED_BUILDING: this.btnAddLand.setVisible(true); this.txtTimeRemaining.setVisible(true); - // Fall through to sideboarding + // Fall through to sideboarding case SIDEBOARDING: this.btnSubmit.setVisible(true); this.btnSubmitTimer.setVisible(true); @@ -711,84 +710,84 @@ public class DeckEditorPanel extends javax.swing.JPanel { jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) /*.addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLayeredPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 256, Short.MAX_VALUE))*/ - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(lblDeckName) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) - .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnSave) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnLoad) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnNew) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnExit)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnImport) - .addContainerGap() - .addComponent(btnGenDeck) - .addContainerGap() - .addComponent(btnAddLand) - .addContainerGap() - .addComponent(btnSubmit) - .addContainerGap() - .addComponent(btnSubmitTimer)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(txtTimeRemaining)) - ) - .addContainerGap())); + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(lblDeckName) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDeckName, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(btnSave) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnLoad) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnNew) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnExit)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(btnImport) + .addContainerGap() + .addComponent(btnGenDeck) + .addContainerGap() + .addComponent(btnAddLand) + .addContainerGap() + .addComponent(btnSubmit) + .addContainerGap() + .addComponent(btnSubmitTimer)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(txtTimeRemaining)) + ) + .addContainerGap())); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblDeckName)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnSave) - .addComponent(btnLoad) - .addComponent(btnNew) - .addComponent(btnExit)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnImport) - .addComponent(btnGenDeck) - .addComponent(btnAddLand) - .addComponent(btnSubmit) - .addComponent(btnSubmitTimer)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtTimeRemaining)) - //.addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE) - .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE) - .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))); + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtDeckName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblDeckName)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnSave) + .addComponent(btnLoad) + .addComponent(btnNew) + .addComponent(btnExit)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnImport) + .addComponent(btnGenDeck) + .addComponent(btnAddLand) + .addComponent(btnSubmit) + .addComponent(btnSubmitTimer)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtTimeRemaining)) + //.addComponent(jLayeredPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, isShowCardInfo ? 30 : 159, Short.MAX_VALUE) + .addComponent(cardInfoPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 104, Short.MAX_VALUE) + .addComponent(bigCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE))); + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE))); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)); + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)); } /** @@ -838,7 +837,6 @@ public class DeckEditorPanel extends javax.swing.JPanel { }); } - private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed //fcSelectDeck.setCurrentDirectory(new File()); String lastFolder = MageFrame.getPreferences().get("lastDeckFolder", ""); @@ -850,10 +848,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { File file = fcSelectDeck.getSelectedFile(); { /** - * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ - * In the case where the user selects the exact same file as was previously - * selected without touching anything else in the dialog, getSelectedFile() - * will erroneously return null due to some combination of our settings. + * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ In + * the case where the user selects the exact same file as was + * previously selected without touching anything else in the + * dialog, getSelectedFile() will erroneously return null due to + * some combination of our settings. * * We manually sub in the last selected file in this case. */ @@ -893,10 +892,11 @@ public class DeckEditorPanel extends javax.swing.JPanel { File file = fcSelectDeck.getSelectedFile(); { /** - * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ - * In the case where the user selects the exact same file as was previously - * selected without touching anything else in the dialog, getSelectedFile() - * will erroneously return null due to some combination of our settings. + * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ In + * the case where the user selects the exact same file as was + * previously selected without touching anything else in the + * dialog, getSelectedFile() will erroneously return null due to + * some combination of our settings. * * We manually sub in the last selected file in this case. */ @@ -1123,7 +1123,7 @@ class UpdateDeckTask extends SwingWorker { protected Void doInBackground() throws Exception { while (!isCancelled()) { SessionHandler.updateDeck(tableId, deck.getDeckCardLists()); - Thread.sleep(5000); + TimeUnit.SECONDS.sleep(5); } return null; } diff --git a/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java index 50d74717f36..52c76236173 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java @@ -27,14 +27,16 @@ */ package mage.client.dialog; -import java.util.UUID; -import javax.swing.JOptionPane; import mage.cards.decks.importer.DeckImporterUtil; import mage.client.MageFrame; import mage.client.SessionHandler; +import mage.players.PlayerType; import mage.remote.Session; import org.apache.log4j.Logger; +import javax.swing.*; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -143,9 +145,9 @@ public class JoinTableDialog extends MageDialog { try { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PASSWORD_JOIN, txtPassword.getText()); if (isTournament) { - joined = session.joinTournamentTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), "Human", 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText()); + joined = session.joinTournamentTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText()); } else { - joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), "Human", 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText()); + joined = session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()), this.txtPassword.getText()); } } catch (Exception ex) { 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 c94ebc18085..c70749b2dc4 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java @@ -27,14 +27,6 @@ */ package mage.client.dialog; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import javax.swing.*; - import mage.cards.decks.importer.DeckImporterUtil; import mage.client.MageFrame; import mage.client.SessionHandler; @@ -48,10 +40,18 @@ import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; import mage.constants.SkillLevel; import mage.game.match.MatchOptions; +import mage.players.PlayerType; import mage.view.GameTypeView; import mage.view.TableView; import org.apache.log4j.Logger; +import javax.swing.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -65,7 +65,7 @@ public class NewTableDialog extends MageDialog { private UUID roomId; private String lastSessionId; private final List players = new ArrayList<>(); - private final List prefPlayerTypes = new ArrayList<>(); + private final List prefPlayerTypes = new ArrayList<>(); private static final String LIMITED = "Limited"; @@ -370,7 +370,7 @@ public class NewTableDialog extends MageDialog { private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem(); MatchOptions options = new MatchOptions(this.txtName.getText(), gameType.getName(), false, 2); - options.getPlayerTypes().add("Human"); + options.getPlayerTypes().add(PlayerType.HUMAN); for (TablePlayerPanel player : players) { options.getPlayerTypes().add(player.getPlayerType()); } @@ -404,7 +404,7 @@ public class NewTableDialog extends MageDialog { roomId, table.getTableId(), this.player1Panel.getPlayerName(), - "Human", 1, + PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()), this.txtPassword.getText())) { for (TablePlayerPanel player : players) { @@ -509,7 +509,7 @@ public class NewTableDialog extends MageDialog { if (numPlayers > players.size()) { while (players.size() != numPlayers) { TablePlayerPanel playerPanel = new TablePlayerPanel(); - String playerType = "Human"; + PlayerType playerType = PlayerType.HUMAN; if (prefPlayerTypes.size() >= players.size() && !players.isEmpty()) { playerType = prefPlayerTypes.get(players.size() - 1); } @@ -597,7 +597,9 @@ public class NewTableDialog extends MageDialog { String playerTypes = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_TYPES, "Human"); prefPlayerTypes.clear(); - prefPlayerTypes.addAll(Arrays.asList(playerTypes.split(","))); + for(String pType : playerTypes.split(",")) { + prefPlayerTypes.add(PlayerType.getByDescription(pType)); + } this.spnNumPlayers.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_PLAYERS, "2"))); String gameTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_GAME_TYPE, "Two Player Duel"); diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index dd6caba68c3..205442fde94 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -33,22 +33,6 @@ */ package mage.client.dialog; -import java.awt.Component; -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import javax.swing.ComboBoxModel; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.JTextArea; -import javax.swing.SpinnerNumberModel; -import javax.swing.filechooser.FileFilter; import mage.cards.decks.Deck; import mage.cards.decks.importer.DeckImporterUtil; import mage.cards.repository.ExpansionInfo; @@ -65,13 +49,20 @@ import mage.game.draft.DraftOptions; import mage.game.draft.DraftOptions.TimingOption; import mage.game.tournament.LimitedOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.view.GameTypeView; import mage.view.TableView; import mage.view.TournamentTypeView; import org.apache.log4j.Logger; +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import java.awt.*; +import java.io.File; +import java.util.*; +import java.util.List; + /** - * * @author BetaSteward_at_googlemail.com */ public class NewTournamentDialog extends MageDialog { @@ -93,7 +84,9 @@ public class NewTournamentDialog extends MageDialog { private String cubeFromDeckFilename = ""; private boolean automaticChange = false; - /** Creates new form NewTournamentDialog */ + /** + * Creates new form NewTournamentDialog + */ public NewTournamentDialog() { initComponents(); lastSessionId = ""; @@ -121,8 +114,8 @@ public class NewTournamentDialog extends MageDialog { cbDraftCube.setModel(new DefaultComboBoxModel(SessionHandler.getDraftCubes())); cbDraftTiming.setModel(new DefaultComboBoxModel(DraftOptions.TimingOption.values())); // update player types - int i=2; - for (TournamentPlayerPanel tournamentPlayerPanel :players) { + int i = 2; + for (TournamentPlayerPanel tournamentPlayerPanel : players) { tournamentPlayerPanel.init(i++); } cbAllowSpectators.setSelected(true); @@ -133,7 +126,8 @@ public class NewTournamentDialog extends MageDialog { this.setVisible(true); } - /** This method is called from within the constructor to + /** + * This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. @@ -213,7 +207,7 @@ public class NewTournamentDialog extends MageDialog { lblTournamentType.setText("Tournament Type:"); - cbTournamentType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + cbTournamentType.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); cbTournamentType.addActionListener(evt -> cbTournamentTypeActionPerformed(evt)); lbDeckType.setText("Deck Type:"); @@ -235,7 +229,7 @@ public class NewTournamentDialog extends MageDialog { lblDraftCube.setText("Draft Cube:"); - cbDraftCube.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + cbDraftCube.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); cbDraftCube.addActionListener(evt -> cbDraftCubeActionPerformed(evt)); lblNumRounds.setText("Number of Swiss Rounds:"); @@ -260,27 +254,27 @@ public class NewTournamentDialog extends MageDialog { jLabel6.setText("Timing:"); - cbDraftTiming.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + cbDraftTiming.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Item 1", "Item 2", "Item 3", "Item 4"})); cbDraftTiming.addActionListener(evt -> cbDraftTimingActionPerformed(evt)); javax.swing.GroupLayout pnlDraftOptionsLayout = new javax.swing.GroupLayout(pnlDraftOptions); pnlDraftOptions.setLayout(pnlDraftOptionsLayout); pnlDraftOptionsLayout.setHorizontalGroup( - pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnlDraftOptionsLayout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cbDraftTiming, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(19, Short.MAX_VALUE)) + pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlDraftOptionsLayout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbDraftTiming, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(19, Short.MAX_VALUE)) ); pnlDraftOptionsLayout.setVerticalGroup( - pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(pnlDraftOptionsLayout.createSequentialGroup() - .addGap(3, 3, 3) - .addGroup(pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(cbDraftTiming, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlDraftOptionsLayout.createSequentialGroup() + .addGap(3, 3, 3) + .addGroup(pnlDraftOptionsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbDraftTiming, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) ); cbAllowSpectators.setText("Allow spectators"); @@ -306,12 +300,12 @@ public class NewTournamentDialog extends MageDialog { javax.swing.GroupLayout pnlPlayersLayout = new javax.swing.GroupLayout(pnlPlayers); pnlPlayers.setLayout(pnlPlayersLayout); pnlPlayersLayout.setHorizontalGroup( - pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pnlPlayersLayout.setVerticalGroup( - pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + pnlPlayersLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); btnOk.setText("OK"); @@ -333,170 +327,170 @@ public class NewTournamentDialog extends MageDialog { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(pnlPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnlPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(lblNbrPlayers) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblNbrSeats) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumSeats, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(lblPacks) - .addComponent(lblPlayer1)) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(28, 28, 28) - .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lblNumRounds)) - .addGroup(layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lblConstructionTime))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkRollbackTurnsAllowed)) - .addGroup(layout.createSequentialGroup() - .addComponent(spnNumRounds, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cbAllowSpectators)))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(btnOk) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCancel)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(lblDraftCube) - .addComponent(lblTournamentType) - .addComponent(lbDeckType) - .addComponent(lblGameType)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(cbDraftCube, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createSequentialGroup() - .addGap(28, 28, 28) - .addComponent(lblNumWins) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblQuitRatio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(chkRated)) - .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(layout.createSequentialGroup() - .addComponent(lblName) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lbTimeLimit) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lbSkillLevel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPassword) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(lblFreeMulligans) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pnlRandomPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(lblNbrPlayers) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumPlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblNbrSeats) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumSeats, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(lblPacks) + .addComponent(lblPlayer1)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(28, 28, 28) + .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lblNumRounds)) + .addGroup(layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lblConstructionTime))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkRollbackTurnsAllowed)) + .addGroup(layout.createSequentialGroup() + .addComponent(spnNumRounds, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbAllowSpectators)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(btnOk) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCancel)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(lblDraftCube) + .addComponent(lblTournamentType) + .addComponent(lbDeckType) + .addComponent(lblGameType)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(cbDraftCube, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGap(28, 28, 28) + .addComponent(lblNumWins) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblQuitRatio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(chkRated)) + .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(layout.createSequentialGroup() + .addComponent(lblName) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lbTimeLimit) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lbSkillLevel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPassword) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(lblFreeMulligans) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addComponent(player1Panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlRandomPacks, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(4, 4, 4) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblName) - .addComponent(lbTimeLimit) - .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblPassword) - .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbSkillLevel) - .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lblFreeMulligans) - .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblNumWins) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblQuitRatio) - .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(chkRated)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblTournamentType)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbDraftCube, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblDraftCube)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbDeckType)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(lblGameType) - .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPacks) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(layout.createSequentialGroup() - .addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlRandomPacks, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbAllowSpectators, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(spnNumRounds, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblNumRounds)) - .addComponent(lblNbrPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(spnNumPlayers) - .addComponent(lblNbrSeats, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(spnNumSeats) - .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPlayer1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblConstructionTime) - .addComponent(chkRollbackTurnsAllowed))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(player1Panel, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(pnlPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(btnOk) - .addComponent(btnCancel)) - .addContainerGap()) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblName) + .addComponent(lbTimeLimit) + .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblPassword) + .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbSkillLevel) + .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblFreeMulligans) + .addComponent(spnFreeMulligans, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblNumWins) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblQuitRatio) + .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(chkRated)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblTournamentType)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbDraftCube, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblDraftCube)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbDeckType)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblGameType) + .addComponent(cbGameType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPacks) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addComponent(pnlPacks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlRandomPacks, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbAllowSpectators, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spnNumRounds, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblNumRounds)) + .addComponent(lblNbrPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spnNumPlayers) + .addComponent(lblNbrSeats, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(spnNumSeats) + .addComponent(pnlDraftOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPlayer1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spnConstructTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblConstructionTime) + .addComponent(chkRollbackTurnsAllowed))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(player1Panel, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(btnOk) + .addComponent(btnCancel)) + .addContainerGap()) ); bindingGroup.bind(); @@ -510,18 +504,18 @@ public class NewTournamentDialog extends MageDialog { private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); - int numSeats = (Integer)this.spnNumSeats.getValue(); + int numSeats = (Integer) this.spnNumSeats.getValue(); TournamentOptions tOptions = new TournamentOptions(this.txtName.getText(), "", numSeats); tOptions.setTournamentType(tournamentType.getName()); tOptions.setPassword(txtPassword.getText()); - tOptions.getPlayerTypes().add("Human"); + tOptions.getPlayerTypes().add(PlayerType.HUMAN); tOptions.setWatchingAllowed(cbAllowSpectators.isSelected()); - tOptions.setQuitRatio((Integer)spnQuitRatio.getValue()); - for (TournamentPlayerPanel player: players) { - tOptions.getPlayerTypes().add((String) player.getPlayerType().getSelectedItem()); + tOptions.setQuitRatio((Integer) spnQuitRatio.getValue()); + for (TournamentPlayerPanel player : players) { + tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem()); } if (!tournamentType.isElimination()) { - tOptions.setNumberRounds((Integer)spnNumRounds.getValue()); + tOptions.setNumberRounds((Integer) spnNumRounds.getValue()); } if (tournamentType.isDraft()) { DraftOptions options = new DraftOptions(); @@ -533,21 +527,21 @@ public class NewTournamentDialog extends MageDialog { tOptions.setLimitedOptions(new LimitedOptions()); } if (tournamentType.isLimited()) { - tOptions.getLimitedOptions().setConstructionTime((Integer)this.spnConstructTime.getValue() * 60); + tOptions.getLimitedOptions().setConstructionTime((Integer) this.spnConstructTime.getValue() * 60); tOptions.getLimitedOptions().setIsRandom(tournamentType.isRandom()); if (tournamentType.isCubeBooster()) { tOptions.getLimitedOptions().setDraftCubeName(this.cbDraftCube.getSelectedItem().toString()); if (!(cubeFromDeckFilename.isEmpty())) { - Deck cubeFromDeck = new Deck(); + Deck cubeFromDeck = new Deck(); try { cubeFromDeck = Deck.load(DeckImporterUtil.importDeck(cubeFromDeckFilename), true, true); } catch (GameException e1) { - JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); } if (cubeFromDeck != null) { cubeFromDeck.clearLayouts(); tOptions.getLimitedOptions().setCubeFromDeck(cubeFromDeck); - } + } } } else if (tournamentType.isRandom() || tournamentType.isRichMan()) { this.isRandom = tournamentType.isRandom(); @@ -558,18 +552,18 @@ public class NewTournamentDialog extends MageDialog { if (tournamentType.isRichMan()) { maxPacks = 36; } - if (selected.size() > maxPacks ){ + if (selected.size() > maxPacks) { StringBuilder infoString = new StringBuilder("More sets were selected than needed. "); infoString.append(maxPacks); infoString.append(" sets will be randomly chosen."); JOptionPane.showMessageDialog(MageFrame.getDesktop(), infoString, "Information", JOptionPane.INFORMATION_MESSAGE); Collections.shuffle(selected); tOptions.getLimitedOptions().getSetCodes().addAll(selected.subList(0, maxPacks)); - }else{ - tOptions.getLimitedOptions().getSetCodes().addAll(selected); + } else { + tOptions.getLimitedOptions().getSetCodes().addAll(selected); } } else { - for (JComboBox pack: packs) { + for (JComboBox pack : packs) { tOptions.getLimitedOptions().getSetCodes().add(((ExpansionInfo) pack.getSelectedItem()).getCode()); } } @@ -588,8 +582,8 @@ public class NewTournamentDialog extends MageDialog { tOptions.getMatchOptions().setMatchTimeLimit((MatchTimeLimit) this.cbTimeLimit.getSelectedItem()); tOptions.getMatchOptions().setSkillLevel((SkillLevel) this.cbSkillLevel.getSelectedItem()); - tOptions.getMatchOptions().setWinsNeeded((Integer)this.spnNumWins.getValue()); - tOptions.getMatchOptions().setFreeMulligans((Integer)this.spnFreeMulligans.getValue()); + tOptions.getMatchOptions().setWinsNeeded((Integer) this.spnNumWins.getValue()); + tOptions.getMatchOptions().setFreeMulligans((Integer) this.spnFreeMulligans.getValue()); tOptions.getMatchOptions().setAttackOption(MultiplayerAttackOption.LEFT); tOptions.getMatchOptions().setRange(RangeOfInfluence.ALL); tOptions.getMatchOptions().setRollbackTurnsAllowed(this.chkRollbackTurnsAllowed.isSelected()); @@ -605,10 +599,10 @@ public class NewTournamentDialog extends MageDialog { roomId, table.getTableId(), this.player1Panel.getPlayerName(), - "Human", 1, + PlayerType.HUMAN, 1, DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()), tOptions.getPassword())) { - for (TournamentPlayerPanel player: players) { + for (TournamentPlayerPanel player : players) { if (!player.getPlayerType().toString().equals("Human")) { if (!player.joinTournamentTable(roomId, table.getTableId(), DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()))) { // error message must be send by sever @@ -633,8 +627,8 @@ public class NewTournamentDialog extends MageDialog { }//GEN-LAST:event_btnCancelActionPerformed private void updateNumSeats() { - int numPlayers = (Integer)this.spnNumPlayers.getValue(); - int numSeats = (Integer)this.spnNumSeats.getValue(); + int numPlayers = (Integer) this.spnNumPlayers.getValue(); + int numSeats = (Integer) this.spnNumSeats.getValue(); if (numSeats > 2) { TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); @@ -652,16 +646,16 @@ public class NewTournamentDialog extends MageDialog { } private void spnNumPlayersStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumPlayersStateChanged - int numPlayers = (Integer)this.spnNumPlayers.getValue(); + int numPlayers = (Integer) this.spnNumPlayers.getValue(); createPlayers(numPlayers - 1); - int numSeats = (Integer)this.spnNumSeats.getValue(); + int numSeats = (Integer) this.spnNumSeats.getValue(); if (numSeats > 2 && numPlayers != numSeats) { updateNumSeats(); } }//GEN-LAST:event_spnNumPlayersStateChanged private void spnNumSeatsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumSeatsStateChanged - int numSeats = (Integer)this.spnNumSeats.getValue(); + int numSeats = (Integer) this.spnNumSeats.getValue(); if (numSeats > 2) { this.spnNumPlayers.setEnabled(false); } else { @@ -669,11 +663,11 @@ public class NewTournamentDialog extends MageDialog { } updateNumSeats(); }//GEN-LAST:event_spnNumSeatsStateChanged - + private void spnNumWinsnumPlayersChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spnNumWinsnumPlayersChanged - int numSeats = (Integer)this.spnNumSeats.getValue(); - int numWins = (Integer)this.spnNumSeats.getValue(); + int numSeats = (Integer) this.spnNumSeats.getValue(); + int numWins = (Integer) this.spnNumSeats.getValue(); if (numSeats > 2) { spnNumWins.setValue(1); } @@ -718,6 +712,7 @@ public class NewTournamentDialog extends MageDialog { private void cbGameTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbGameTypeActionPerformed setGameOptions(); }//GEN-LAST:event_cbGameTypeActionPerformed + private void setGameOptions() { GameTypeView gameType = (GameTypeView) cbGameType.getSelectedItem(); // int oldValue = (Integer) this.spnNumPlayers.getValue(); @@ -747,10 +742,10 @@ public class NewTournamentDialog extends MageDialog { if (tournamentType.isLimited()) { this.isRandom = tournamentType.isRandom(); - this.isRichMan = tournamentType.isRichMan(); - if (this.isRandom || this.isRichMan){ + this.isRichMan = tournamentType.isRichMan(); + if (this.isRandom || this.isRichMan) { createRandomPacks(); - }else{ + } else { createPacks(tournamentType.getNumBoosters()); } } @@ -759,8 +754,8 @@ public class NewTournamentDialog extends MageDialog { private void setNumberOfSwissRoundsMin(int numPlayers) { // set the number of minimum swiss rounds related to the number of players - int minRounds = (int) Math.ceil(Math.log(numPlayers + 1) / Math.log(2)); - int newValue = Math.max((Integer)spnNumRounds.getValue(), minRounds); + int minRounds = (int) Math.ceil(Math.log(numPlayers + 1) / Math.log(2)); + int newValue = Math.max((Integer) spnNumRounds.getValue(), minRounds); this.spnNumRounds.setModel(new SpinnerNumberModel(newValue, minRounds, 10, 1)); this.pack(); this.revalidate(); @@ -793,7 +788,7 @@ public class NewTournamentDialog extends MageDialog { this.lblPacks.setVisible(false); this.pnlPacks.setVisible(false); this.pnlRandomPacks.setVisible(false); - } else if (tournamentType.isRandom() || tournamentType.isRichMan()){ + } else if (tournamentType.isRandom() || tournamentType.isRichMan()) { this.lblDraftCube.setVisible(false); this.cbDraftCube.setVisible(false); this.lblPacks.setVisible(true); @@ -887,14 +882,13 @@ public class NewTournamentDialog extends MageDialog { private void packActionPerformed(java.awt.event.ActionEvent evt) { boolean start = false; int selectedIndex = 0; - for (JComboBox pack: packs) { + for (JComboBox pack : packs) { if (!start) { if (evt.getSource().equals(pack)) { start = true; selectedIndex = pack.getSelectedIndex(); } - } - else { + } else { pack.setSelectedIndex(selectedIndex); } } @@ -909,8 +903,7 @@ public class NewTournamentDialog extends MageDialog { players.add(playerPanel); } - } - else if (numPlayers < players.size()) { + } else if (numPlayers < players.size()) { while (players.size() != numPlayers) { players.remove(players.size() - 1); } @@ -922,10 +915,9 @@ public class NewTournamentDialog extends MageDialog { } - private void drawPlayers() { this.pnlOtherPlayers.removeAll(); - for (TournamentPlayerPanel panel: players) { + for (TournamentPlayerPanel panel : players) { this.pnlOtherPlayers.add(panel); panel.getPlayerType().addActionListener(evt -> { if (!automaticChange) { @@ -942,14 +934,13 @@ public class NewTournamentDialog extends MageDialog { boolean start = false; int selectedIndex = 0; automaticChange = true; - for (TournamentPlayerPanel player: players) { + for (TournamentPlayerPanel player : players) { if (!start) { if (evt.getSource().equals(player.getPlayerType())) { start = true; selectedIndex = player.getPlayerType().getSelectedIndex(); } - } - else { + } else { player.getPlayerType().setSelectedIndex(selectedIndex); } } @@ -959,19 +950,19 @@ public class NewTournamentDialog extends MageDialog { /** * set the tournament settings from java prefs */ - private void setTournamentSettingsFromPrefs () { + private void setTournamentSettingsFromPrefs() { int numPlayers; txtName.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NAME, "Tournament")); txtPassword.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PASSWORD, "")); int timeLimit = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TIME_LIMIT, "1500")); - for (MatchTimeLimit mtl :MatchTimeLimit.values()) { + for (MatchTimeLimit mtl : MatchTimeLimit.values()) { if (mtl.getTimeLimit() == timeLimit) { this.cbTimeLimit.setSelectedItem(mtl); break; } } String skillLevelDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_SKILL_LEVEL, "Casual"); - for (SkillLevel skillLevel :SkillLevel.values()) { + for (SkillLevel skillLevel : SkillLevel.values()) { if (skillLevel.toString().equals(skillLevelDefault)) { this.cbSkillLevel.setSelectedItem(skillLevel); break; @@ -1006,7 +997,7 @@ public class NewTournamentDialog extends MageDialog { if (tournamentType.isDraft()) { numPlayers = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PLAYERS_DRAFT, "4")); setTournamentOptions(numPlayers); - if (!(tournamentType.isRandom() || tournamentType.isRichMan())){ + if (!(tournamentType.isRandom() || tournamentType.isRichMan())) { loadBoosterPacks(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_DRAFT, "")); } @@ -1028,13 +1019,13 @@ public class NewTournamentDialog extends MageDialog { if (!packString.isEmpty()) { String[] packsArray = packString.substring(1, packString.length() - 1).split(","); int packNumber = 0; - for (String pack : packsArray ){ + for (String pack : packsArray) { packNumber++; if (this.packs.size() >= packNumber - 1) { - JComboBox comboBox = this.packs.get(packNumber-1); + JComboBox comboBox = this.packs.get(packNumber - 1); ComboBoxModel model = comboBox.getModel(); int size = model.getSize(); - for(int i=0;i { @Override protected Void doInBackground() throws Exception { while (!isCancelled()) { - SessionHandler.getTable(roomId, tableId).ifPresent(tableView -> { - - this.publish(tableView); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - }); + SessionHandler.getTable(roomId, tableId).ifPresent(this::publish); + TimeUnit.SECONDS.sleep(1); } return null; } diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index d68e842327e..1e239242160 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -31,6 +31,7 @@ import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import static java.awt.Component.LEFT_ALIGNMENT; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; @@ -59,6 +60,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.GroupLayout; @@ -80,7 +82,6 @@ import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.plaf.basic.BasicSplitPaneDivider; import javax.swing.plaf.basic.BasicSplitPaneUI; - import mage.cards.Card; import mage.cards.action.ActionCallback; import mage.choices.Choice; @@ -100,9 +101,7 @@ import mage.client.dialog.PickChoiceDialog; import mage.client.dialog.PickNumberDialog; import mage.client.dialog.PickPileDialog; import mage.client.dialog.PreferencesDialog; - import static mage.client.dialog.PreferencesDialog.*; - import mage.client.dialog.ShowCardsDialog; import mage.client.game.FeedbackPanel.FeedbackMode; import mage.client.plugins.adapters.MageActionCallback; @@ -119,13 +118,11 @@ import mage.constants.Constants; import mage.constants.EnlargeMode; import mage.constants.PhaseStep; import mage.constants.PlayerAction; - import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_FIRST; import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_ABILITY_LAST; import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_FIRST; import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_LAST; import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; - import mage.constants.Zone; import mage.game.events.PlayerQueryEvent; import mage.view.AbilityPickerView; @@ -534,8 +531,8 @@ public final class GamePanel extends javax.swing.JPanel { this.pnlReplay.setVisible(false); this.gameChatPanel.clear(); - SessionHandler.getGameChatId(gameId).ifPresent(uuid -> - this.gameChatPanel.connect(uuid)); + SessionHandler.getGameChatId(gameId).ifPresent(uuid + -> this.gameChatPanel.connect(uuid)); if (!SessionHandler.watchGame(gameId)) { removeGame(); } @@ -816,13 +813,15 @@ public final class GamePanel extends javax.swing.JPanel { cardsView.put(player.getTopCard().getId(), player.getTopCard()); handleGameInfoWindow(revealed, ShowType.REVEAL_TOP_LIBRARY, player.getName() + "'s top library card", cardsView); } - } else { + } else if (!players.isEmpty()) { logger.warn("Couldn't find player."); logger.warn(" uuid:" + player.getPlayerId()); logger.warn(" players:"); for (PlayAreaPanel p : players.values()) { logger.warn(String.valueOf(p)); } + } else { + // can happen at the game start before player list is initiated } } if (!menuNameSet) { @@ -1776,24 +1775,24 @@ public final class GamePanel extends javax.swing.JPanel { pnlReplay.setLayout(gl_pnlReplay); gl_pnlReplay.setHorizontalGroup( gl_pnlReplay.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(gl_pnlReplay.createSequentialGroup() - .addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnStopReplay, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnNextPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnSkipForward, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(gl_pnlReplay.createSequentialGroup() + .addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStopReplay, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnNextPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSkipForward, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)) ); gl_pnlReplay.setVerticalGroup( gl_pnlReplay.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(btnSkipForward, 0, 0, Short.MAX_VALUE) - .addComponent(btnNextPlay, 0, 0, Short.MAX_VALUE) - .addComponent(btnStopReplay, 0, 0, Short.MAX_VALUE) - .addComponent(btnPlay, 0, 0, Short.MAX_VALUE) - .addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 31, Short.MAX_VALUE) + .addComponent(btnSkipForward, 0, 0, Short.MAX_VALUE) + .addComponent(btnNextPlay, 0, 0, Short.MAX_VALUE) + .addComponent(btnStopReplay, 0, 0, Short.MAX_VALUE) + .addComponent(btnPlay, 0, 0, Short.MAX_VALUE) + .addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 31, Short.MAX_VALUE) ); // Game info panel (buttons on the right panel) @@ -1867,8 +1866,8 @@ public final class GamePanel extends javax.swing.JPanel { } }; String[] phases = {"Untap", "Upkeep", "Draw", "Main1", - "Combat_Start", "Combat_Attack", "Combat_Block", "Combat_Damage", "Combat_End", - "Main2", "Cleanup", "Next_Turn"}; + "Combat_Start", "Combat_Attack", "Combat_Block", "Combat_Damage", "Combat_End", + "Main2", "Cleanup", "Next_Turn"}; for (String name : phases) { createPhaseButton(name, phasesMouseAdapter); } @@ -1905,46 +1904,46 @@ public final class GamePanel extends javax.swing.JPanel { javax.swing.GroupLayout gl_helperHandButtonsStackArea = new javax.swing.GroupLayout(pnlHelperHandButtonsStackArea); gl_helperHandButtonsStackArea.setHorizontalGroup( gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - // .addGap(0) - .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addComponent(helper, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(handContainer, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ) - .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addComponent(pnlShortCuts, 410, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addComponent(stackObjects, 410, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - ) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + // .addGap(0) + .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) + .addComponent(helper, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(handContainer, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ) - .addGap(0) - //.addComponent(jPhases, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - .addComponent(pnlBattlefield, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE) - .addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - ))) + .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) + .addComponent(pnlShortCuts, 410, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addComponent(stackObjects, 410, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + ) + ) + .addGap(0) + //.addComponent(jPhases, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + .addComponent(pnlBattlefield, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE) + .addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + ))) ); gl_helperHandButtonsStackArea.setVerticalGroup( gl_helperHandButtonsStackArea.createParallelGroup(Alignment.TRAILING) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addComponent(pnlBattlefield, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE) - .addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) + .addComponent(pnlBattlefield, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE) + .addComponent(phasesContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + ) + //.addPreferredGap(ComponentPlacement.RELATED) + .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + .addGap(2) + .addComponent(pnlShortCuts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(stackObjects, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) ) - //.addPreferredGap(ComponentPlacement.RELATED) - .addGroup(gl_helperHandButtonsStackArea.createParallelGroup(Alignment.LEADING) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - .addGap(2) - .addComponent(pnlShortCuts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(stackObjects, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - ) - .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() - .addComponent(helper, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(handContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - ) + .addGroup(gl_helperHandButtonsStackArea.createSequentialGroup() + .addComponent(helper, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(handContainer, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) ) ) + ) ); pnlHelperHandButtonsStackArea.setLayout(gl_helperHandButtonsStackArea); @@ -1977,11 +1976,11 @@ public final class GamePanel extends javax.swing.JPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPane0, javax.swing.GroupLayout.DEFAULT_SIZE, 1078, Short.MAX_VALUE) + .addComponent(jSplitPane0, javax.swing.GroupLayout.DEFAULT_SIZE, 1078, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSplitPane0, javax.swing.GroupLayout.DEFAULT_SIZE, 798, Short.MAX_VALUE) + .addComponent(jSplitPane0, javax.swing.GroupLayout.DEFAULT_SIZE, 798, Short.MAX_VALUE) ); } @@ -2433,7 +2432,7 @@ class ReplayTask extends SwingWorker> { protected Void doInBackground() throws Exception { while (!isCancelled()) { SessionHandler.nextPlay(gameId); - Thread.sleep(1000); + TimeUnit.SECONDS.sleep(1); } return null; } 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 0db517ded03..63866222351 100644 --- a/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java +++ b/Mage.Client/src/main/java/mage/client/remote/CallbackClientImpl.java @@ -27,11 +27,6 @@ */ package mage.client.remote; -import java.awt.event.KeyEvent; -import java.util.List; -import java.util.UUID; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import mage.cards.decks.Deck; import mage.client.MageFrame; import mage.client.SessionHandler; @@ -49,19 +44,15 @@ import mage.client.util.object.SaveObjectUtil; import mage.interfaces.callback.CallbackClient; import mage.interfaces.callback.ClientCallback; import mage.utils.CompressUtil; -import mage.view.AbilityPickerView; -import mage.view.ChatMessage; +import mage.view.*; import mage.view.ChatMessage.MessageType; -import mage.view.DeckView; -import mage.view.DraftClientMessage; -import mage.view.DraftView; -import mage.view.GameClientMessage; -import mage.view.GameEndView; -import mage.view.GameView; -import mage.view.TableClientMessage; -import mage.view.UserRequestMessage; import org.apache.log4j.Logger; +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.util.List; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -79,38 +70,38 @@ public class CallbackClientImpl implements CallbackClient { @Override public synchronized void processCallback(final ClientCallback callback) { - SaveObjectUtil.saveObject(callback.getData(), callback.getMethod()); + SaveObjectUtil.saveObject(callback.getData(), callback.getMethod().toString()); callback.setData(CompressUtil.decompress(callback.getData())); SwingUtilities.invokeLater(() -> { try { logger.debug(callback.getMessageId() + " -- " + callback.getMethod()); switch (callback.getMethod()) { - case "startGame": { + case START_GAME: { TableClientMessage message = (TableClientMessage) callback.getData(); GameManager.instance.setCurrentPlayerUUID(message.getPlayerId()); gameStarted(message.getGameId(), message.getPlayerId()); break; } - case "startTournament": { + case START_TOURNAMENT: { TableClientMessage message = (TableClientMessage) callback.getData(); tournamentStarted(message.getGameId(), message.getPlayerId()); break; } - case "startDraft": { + case START_DRAFT: { TableClientMessage message = (TableClientMessage) callback.getData(); draftStarted(message.getGameId(), message.getPlayerId()); break; } - case "replayGame": + case REPLAY_GAME: replayGame(callback.getObjectId()); break; - case "showTournament": + case SHOW_TOURNAMENT: showTournament(callback.getObjectId()); break; - case "watchGame": + case WATCHGAME: watchGame(callback.getObjectId()); break; - case "chatMessage": { + case CHATMESSAGE: { ChatMessage message = (ChatMessage) callback.getData(); // Drop messages from ignored users @@ -154,7 +145,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "serverMessage": + case SERVER_MESSAGE: if (callback.getData() != null) { ChatMessage message = (ChatMessage) callback.getData(); if (message.getColor() == ChatMessage.MessageColor.RED) { @@ -164,50 +155,50 @@ public class CallbackClientImpl implements CallbackClient { } } break; - case "joinedTable": { + case JOINED_TABLE: { TableClientMessage message = (TableClientMessage) callback.getData(); joinedTable(message.getRoomId(), message.getTableId(), message.getFlag()); break; } - case "replayInit": { + case REPLAY_INIT: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.init((GameView) callback.getData()); } break; } - case "replayDone": { + case REPLAY_DONE: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.endMessage((String) callback.getData(), callback.getMessageId()); } break; } - case "replayUpdate": { + case REPLAY_UPDATE: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.updateGame((GameView) callback.getData()); } break; } - case "gameInit": { + case GAME_INIT: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.init((GameView) callback.getData()); } break; } - case "gameOver": { + case GAME_OVER: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.endMessage((String) callback.getData(), callback.getMessageId()); } break; } - case "gameError": + case GAME_ERROR: frame.showErrorDialog("Game Error", (String) callback.getData()); break; - case "gameAsk": { + case GAME_ASK: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -215,7 +206,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameTarget": // e.g. Pick triggered ability + case GAME_TARGET: // e.g. Pick triggered ability { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); @@ -225,7 +216,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameSelect": { + case GAME_SELECT: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -233,14 +224,14 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameChooseAbility": { + case GAME_CHOOSE_ABILITY: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.pickAbility((AbilityPickerView) callback.getData()); } break; } - case "gameChoosePile": { + case GAME_CHOOSE_PILE: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -248,7 +239,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameChooseChoice": { + case GAME_CHOOSE_CHOICE: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); @@ -257,7 +248,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gamePlayMana": { + case GAME_PLAY_MANA: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -265,7 +256,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gamePlayXMana": { + case GAME_PLAY_XMANA: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -273,7 +264,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameSelectAmount": { + case GAME_GET_AMOUNT: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -281,23 +272,23 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "gameUpdate": { + case GAME_UPDATE: { GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { panel.updateGame((GameView) callback.getData()); } break; } - case "endGameInfo": + case END_GAME_INFO: MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData()); break; - case "showUserMessage": + case SHOW_USERMESSAGE: List messageData = (List) callback.getData(); if (messageData.size() == 2) { JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE); } break; - case "gameInform": + case GAME_INFORM: if (callback.getMessageId() > gameInformMessageId) { { GameClientMessage message = (GameClientMessage) callback.getData(); @@ -313,7 +304,7 @@ public class CallbackClientImpl implements CallbackClient { } gameInformMessageId = messageId; break; - case "gameInformPersonal": { + case GAME_INFORM_PERSONAL: { GameClientMessage message = (GameClientMessage) callback.getData(); GamePanel panel = MageFrame.getGame(callback.getObjectId()); if (panel != null) { @@ -322,7 +313,7 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "sideboard": { + case SIDEBOARD: { TableClientMessage message = (TableClientMessage) callback.getData(); DeckView deckView = message.getDeck(); Deck deck = DeckUtil.construct(deckView); @@ -333,17 +324,17 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "construct": { + case CONSTRUCT: { TableClientMessage message = (TableClientMessage) callback.getData(); DeckView deckView = message.getDeck(); Deck deck = DeckUtil.construct(deckView); construct(deck, message.getTableId(), message.getTime()); break; } - case "draftOver": + case DRAFT_OVER: MageFrame.removeDraft(callback.getObjectId()); break; - case "draftPick": { + case DRAFT_PICK: { DraftClientMessage message = (DraftClientMessage) callback.getData(); DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { @@ -351,14 +342,14 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "draftUpdate": { + case DRAFT_UPDATE: { DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { panel.updateDraft((DraftView) callback.getData()); } break; } - case "draftInform": // if (callback.getMessageId() > messageId) { + case DRAFT_INFORM: // if (callback.getMessageId() > messageId) { { DraftClientMessage message = (DraftClientMessage) callback.getData(); } @@ -366,7 +357,7 @@ public class CallbackClientImpl implements CallbackClient { // logger.warn("message out of sequence - ignoring"); // } break; - case "draftInit": { + case DRAFT_INIT: { DraftClientMessage message = (DraftClientMessage) callback.getData(); DraftPanel panel = MageFrame.getDraft(callback.getObjectId()); if (panel != null) { @@ -374,9 +365,9 @@ public class CallbackClientImpl implements CallbackClient { } break; } - case "tournamentInit": + case TOURNAMENT_INIT: break; - case "userRequestDialog": + case USER_REQUEST_DIALOG: frame.showUserRequestDialog((UserRequestMessage) callback.getData()); break; } diff --git a/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java index 902aab84dd9..2deeeebb0f5 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java @@ -34,14 +34,16 @@ package mage.client.table; -import java.io.IOException; -import java.util.UUID; -import javax.swing.DefaultComboBoxModel; import mage.cards.decks.importer.DeckImporterUtil; import mage.client.SessionHandler; import mage.client.util.Config; import mage.client.util.Event; import mage.client.util.Listener; +import mage.players.PlayerType; + +import javax.swing.*; +import java.io.IOException; +import java.util.UUID; /** * @@ -58,7 +60,7 @@ public class TablePlayerPanel extends javax.swing.JPanel { this.newPlayerPanel.setVisible(false); } - public void init(int playerNum, String playerType) { + public void init(int playerNum, PlayerType playerType) { cbPlayerType.setModel(new DefaultComboBoxModel(SessionHandler.getPlayerTypes())); this.lblPlayerNum.setText("Player " + playerNum); if (Config.defaultOtherPlayerIndex != null) { @@ -77,13 +79,13 @@ public class TablePlayerPanel extends javax.swing.JPanel { public boolean joinTable(UUID roomId, UUID tableId) throws IOException, ClassNotFoundException { if (!this.cbPlayerType.getSelectedItem().equals("Human")) { - return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (String)this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()),""); + return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (PlayerType) this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()),""); } return true; } - public String getPlayerType() { - return (String) this.cbPlayerType.getSelectedItem(); + public PlayerType getPlayerType() { + return PlayerType.getByDescription(this.cbPlayerType.getSelectedItem().toString()); } public void addPlayerTypeEventListener(Listener listener) { 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 5a6be71f1a9..73ca9f0caed 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -33,69 +33,21 @@ */ package mage.client.table; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.HeadlessException; -import java.awt.Image; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.beans.PropertyVetoException; -import java.io.File; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -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; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JDesktopPane; -import javax.swing.JInternalFrame; -import javax.swing.JLayeredPane; -import javax.swing.JOptionPane; -import javax.swing.JPopupMenu; -import javax.swing.JToggleButton; -import javax.swing.RowFilter; -import javax.swing.SwingWorker; -import javax.swing.table.AbstractTableModel; import mage.cards.decks.importer.DeckImporterUtil; import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.chat.ChatPanelBasic; import mage.client.components.MageComponents; -import mage.client.dialog.JoinTableDialog; -import mage.client.dialog.NewTableDialog; -import mage.client.dialog.NewTournamentDialog; -import mage.client.dialog.PreferencesDialog; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER; -import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH; -import mage.client.dialog.TableWaitingDialog; -import static mage.client.table.TablesPanel.PASSWORDED; +import mage.client.dialog.*; 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; -import mage.constants.MatchTimeLimit; -import mage.constants.MultiplayerAttackOption; -import mage.constants.PlayerAction; -import mage.constants.RangeOfInfluence; -import mage.constants.SkillLevel; +import mage.constants.*; import mage.game.match.MatchOptions; +import mage.players.PlayerType; import mage.remote.MageRemoteException; import mage.view.MatchView; import mage.view.RoomUsersView; @@ -103,6 +55,25 @@ import mage.view.TableView; import mage.view.UserRequestMessage; import org.apache.log4j.Logger; +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.beans.PropertyVetoException; +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER; +import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH; +import static mage.client.table.TablesPanel.PASSWORDED; + /** * * @author BetaSteward_at_googlemail.com @@ -216,7 +187,7 @@ public class TablesPanel extends javax.swing.JPanel { if (PASSWORDED.equals(pwdColumn)) { joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); } else { - SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), "Human", 1, null, ""); + SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), PlayerType.HUMAN, 1, null, ""); } } else { joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited")); @@ -1188,8 +1159,8 @@ public class TablesPanel extends javax.swing.JPanel { } MatchOptions options = new MatchOptions("1", "Two Player Duel", false, 2); - options.getPlayerTypes().add("Human"); - options.getPlayerTypes().add("Computer - mad"); + options.getPlayerTypes().add(PlayerType.HUMAN); + options.getPlayerTypes().add(PlayerType.COMPUTER_MAD); options.setDeckType("Limited"); options.setAttackOption(MultiplayerAttackOption.LEFT); options.setRange(RangeOfInfluence.ALL); @@ -1203,8 +1174,8 @@ public class TablesPanel extends javax.swing.JPanel { options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); table = SessionHandler.createTable(roomId, options); - SessionHandler.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"), ""); - SessionHandler.joinTable(roomId, table.getTableId(), "Computer", "Computer - mad", 5, DeckImporterUtil.importDeck("test.dck"), ""); + SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, DeckImporterUtil.importDeck("test.dck"), ""); + SessionHandler.joinTable(roomId, table.getTableId(), "Computer", PlayerType.COMPUTER_MAD, 5, DeckImporterUtil.importDeck("test.dck"), ""); SessionHandler.startMatch(roomId, table.getTableId()); } catch (HeadlessException ex) { handleError(ex); @@ -1450,7 +1421,7 @@ class UpdateTablesTask extends SwingWorker> { if (!tables.isEmpty()) { this.publish(tables); } - Thread.sleep(3000); + TimeUnit.SECONDS.sleep(3); } return null; } @@ -1494,7 +1465,7 @@ class UpdatePlayersTask extends SwingWorker> { protected Void doInBackground() throws Exception { while (!isCancelled()) { this.publish(SessionHandler.getRoomUsers(roomId)); - Thread.sleep(3000); + TimeUnit.SECONDS.sleep(3); } return null; } @@ -1636,7 +1607,7 @@ class UpdateMatchesTask extends SwingWorker> { if (!matches.isEmpty()) { this.publish(matches); } - Thread.sleep(10000); + TimeUnit.SECONDS.sleep(10); } return null; } diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java index 91796275a6a..9a6a65d89af 100644 --- a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java @@ -36,6 +36,7 @@ package mage.client.table; import mage.cards.decks.DeckCardLists; import mage.client.SessionHandler; +import mage.players.PlayerType; import javax.swing.*; import java.util.UUID; @@ -68,8 +69,8 @@ public class TournamentPlayerPanel extends javax.swing.JPanel { roomId, tableId, this.txtPlayerName.getText(), - (String)this.cbPlayerType.getSelectedItem(), - (Integer)spnLevel.getValue(), + (PlayerType) this.cbPlayerType.getSelectedItem(), + (Integer) spnLevel.getValue(), deckCardLists, ""); } diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java index 27a93236c37..12367d4384c 100644 --- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java +++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java @@ -44,13 +44,12 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.SwingWorker; import javax.swing.table.AbstractTableModel; - -import mage.cards.o.Opt; import mage.client.MageFrame; import mage.client.SessionHandler; import mage.client.chat.ChatPanelBasic; @@ -730,7 +729,7 @@ class UpdateTournamentTask extends SwingWorker { protected Void doInBackground() throws Exception { while (!isCancelled()) { this.publish(SessionHandler.getTournament(tournamentId)); - Thread.sleep(2000); + TimeUnit.SECONDS.sleep(2); } return null; } diff --git a/Mage.Client/src/main/java/mage/client/util/audio/MusicPlayer.java b/Mage.Client/src/main/java/mage/client/util/audio/MusicPlayer.java index d77d81ef09d..3ce0b81d7ec 100644 --- a/Mage.Client/src/main/java/mage/client/util/audio/MusicPlayer.java +++ b/Mage.Client/src/main/java/mage/client/util/audio/MusicPlayer.java @@ -1,7 +1,8 @@ package mage.client.util.audio; -import java.io.File; import java.awt.List; +import java.io.File; +import java.util.concurrent.TimeUnit; import javax.sound.sampled.*; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; @@ -75,7 +76,7 @@ public class MusicPlayer { player.breaked_out = true; player.breaked = true; try { - Thread.sleep(100); + TimeUnit.MILLISECONDS.sleep(100); } catch (Exception e) { log.error("Thread error: " + e); } @@ -119,7 +120,7 @@ public class MusicPlayer { public void run() { try { - Thread.sleep(100); + TimeUnit.MILLISECONDS.sleep(100); } catch (Exception e) { } while (!stopped) { @@ -130,7 +131,7 @@ public class MusicPlayer { PlayThread.start(); while (!(breaked || breaked_out)) { try { - Thread.sleep(10); + TimeUnit.MILLISECONDS.sleep(10); } catch (Exception e) { log.error("Thread error: " + e); } diff --git a/Mage.Client/src/main/java/mage/client/util/gui/BufferedImageBuilder.java b/Mage.Client/src/main/java/mage/client/util/gui/BufferedImageBuilder.java index 97e2c45741c..83b586d04db 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/BufferedImageBuilder.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/BufferedImageBuilder.java @@ -3,6 +3,7 @@ package mage.client.util.gui; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; +import java.util.concurrent.TimeUnit; /** * Utility class for creating BufferedImage object from Image instance. @@ -65,7 +66,7 @@ public class BufferedImageBuilder { }); while (!imageLoadStatus.widthDone && !imageLoadStatus.heightDone) { try { - Thread.sleep(300); + TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { } @@ -73,8 +74,9 @@ public class BufferedImageBuilder { } static class ImageLoadStatus { + public boolean widthDone = false; public boolean heightDone = false; } -} \ No newline at end of file +} diff --git a/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java b/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java index cc6907b6145..61b28bda4ed 100644 --- a/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java +++ b/Mage.Client/src/main/java/mage/client/util/stats/UpdateMemUsageTask.java @@ -3,6 +3,7 @@ package mage.client.util.stats; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import javax.swing.*; import org.apache.log4j.Logger; @@ -29,7 +30,7 @@ public class UpdateMemUsageTask extends SwingWorker { while (!isCancelled()) { float memUsage = MemoryUsageStatUtil.getMemoryFreeStatPercentage(); this.publish(memUsage >= 0 ? memUsage : null); - Thread.sleep(MEM_USAGE_UPDATE_TIME); + TimeUnit.MILLISECONDS.sleep(MEM_USAGE_UPDATE_TIME); } return null; } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/Util.java b/Mage.Client/src/main/java/org/mage/card/arcane/Util.java index 87d91920447..2c02a2d0c44 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/Util.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/Util.java @@ -11,20 +11,21 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; - import javax.swing.SwingUtilities; -@SuppressWarnings({ "rawtypes", "unchecked" }) +@SuppressWarnings({"rawtypes", "unchecked"}) public final class Util { + public static final boolean isMac = System.getProperty("os.name").toLowerCase().contains("mac"); public static final boolean isWindows = !System.getProperty("os.name").toLowerCase().contains("windows"); public static final ThreadPoolExecutor threadPool; static private int threadCount; + static { threadPool = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() { @Override - public Thread newThread (Runnable runnable) { + public Thread newThread(Runnable runnable) { threadCount++; Thread thread = new Thread(runnable, "Util" + threadCount); thread.setDaemon(true); @@ -34,14 +35,14 @@ public final class Util { threadPool.prestartAllCoreThreads(); } - public static void broadcast (byte[] data, int port) throws IOException { + public static void broadcast(byte[] data, int port) throws IOException { DatagramSocket socket = new DatagramSocket(); broadcast(socket, data, port, NetworkInterface.getNetworkInterfaces()); socket.close(); } - private static void broadcast (DatagramSocket socket, byte[] data, int port, Enumeration ifaces) - throws IOException { + private static void broadcast(DatagramSocket socket, byte[] data, int port, Enumeration ifaces) + throws IOException { for (NetworkInterface iface : Collections.list(ifaces)) { for (InetAddress address : Collections.list(iface.getInetAddresses())) { if (!address.isSiteLocalAddress()) { @@ -57,14 +58,14 @@ public final class Util { } } - public static void sleep (int millis) { + public static void sleep(int millis) { try { - Thread.sleep(millis); + TimeUnit.MILLISECONDS.sleep(millis); } catch (InterruptedException ignored) { } } - public static boolean classExists (String className) { + public static boolean classExists(String className) { try { Class.forName(className); return true; @@ -73,7 +74,7 @@ public final class Util { } } - public static void wait (Object lock) { + public static void wait(Object lock) { synchronized (lock) { try { lock.wait(); @@ -82,7 +83,7 @@ public final class Util { } } - public static void invokeAndWait (Runnable runnable) { + public static void invokeAndWait(Runnable runnable) { try { SwingUtilities.invokeAndWait(runnable); } catch (Exception ex) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java index 44e4f2183d1..7753654af9e 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -12,6 +12,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLayeredPane; @@ -33,6 +34,7 @@ import org.apache.log4j.Logger; import org.mage.card.arcane.Animation; import org.mage.card.arcane.CardPanel; import org.mage.card.arcane.CardPanelComponentImpl; +import org.mage.card.arcane.CardPanelRenderImpl; import org.mage.card.arcane.ManaSymbols; import org.mage.plugins.card.dl.DownloadGui; import org.mage.plugins.card.dl.DownloadJob; @@ -43,7 +45,6 @@ import org.mage.plugins.card.dl.sources.GathererSets; import org.mage.plugins.card.dl.sources.GathererSymbols; import org.mage.plugins.card.images.ImageCache; import org.mage.plugins.card.info.CardInfoPaneImpl; -import org.mage.card.arcane.CardPanelRenderImpl; /** * {@link CardPlugin} implementation. @@ -108,10 +109,10 @@ public class CardPluginImpl implements CardPlugin { cardWidthMin = (int) GUISizeHelper.battlefieldCardMinDimension.getWidth(); cardWidthMax = (int) GUISizeHelper.battlefieldCardMaxDimension.getWidth(); } - + /** - * Temporary card rendering shim. Split card rendering isn't implemented yet, so - * use old component based rendering for the split cards. + * Temporary card rendering shim. Split card rendering isn't implemented + * yet, so use old component based rendering for the split cards. */ private CardPanel makePanel(CardView view, UUID gameId, boolean loadImage, ActionCallback callback, boolean isFoil, Dimension dimension) { String fallback = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_FALLBACK, "false"); @@ -584,7 +585,7 @@ public class CardPluginImpl implements CardPlugin { Animation.showCard(card, count > 0 ? count : 1); try { while ((card).getAlpha() + 0.05f < 1) { - Thread.sleep(30); + TimeUnit.MILLISECONDS.sleep(30); } } catch (Exception e) { e.printStackTrace(); @@ -598,7 +599,7 @@ public class CardPluginImpl implements CardPlugin { Animation.hideCard(card, count > 0 ? count : 1); try { while ((card).getAlpha() - 0.05f > 0) { - Thread.sleep(30); + TimeUnit.MILLISECONDS.sleep(30); } } catch (Exception e) { e.printStackTrace(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java index 2799f503aa3..e7750f0801a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GrabbagImageSource.java @@ -29,6 +29,7 @@ package org.mage.plugins.card.dl.sources; import java.io.IOException; import java.util.HashMap; +import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.mage.plugins.card.images.CardDownloadData; @@ -1697,7 +1698,7 @@ public class GrabbagImageSource implements CardImageSource { public void doPause(String httpImageUrl) { if (!httpImageUrl.startsWith("/MTG")) { try { - Thread.sleep(2000); + TimeUnit.SECONDS.sleep(2); } catch (InterruptedException ex) { } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index 047bb90f240..d75337f6bb4 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -24,8 +24,7 @@ * 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.plugins.card.dl.sources; import java.io.BufferedReader; @@ -41,6 +40,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import java.util.prefs.Preferences; import mage.client.MageFrame; import mage.client.dialog.PreferencesDialog; @@ -271,12 +271,12 @@ public class WizardCardsImageSource implements CardImageSource { public String getNextHttpImageUrl() { return null; } - + @Override public String getFileForHttpImage(String httpImageUrl) { return null; } - + private Map getSetLinks(String cardSet) { ConcurrentHashMap setLinks = new ConcurrentHashMap<>(); ExecutorService executor = Executors.newFixedThreadPool(10); @@ -289,7 +289,7 @@ public class WizardCardsImageSource implements CardImageSource { int firstMultiverseIdLastPage = 0; Pages: while (page < 999) { - String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page +"&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"; + String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page + "&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"; Document doc = getDocument(searchUrl); Elements cardsImages = doc.select("img[src^=../../Handlers/]"); if (cardsImages.isEmpty()) { @@ -320,7 +320,7 @@ public class WizardCardsImageSource implements CardImageSource { while (!executor.isTerminated()) { try { - Thread.sleep(1000); + TimeUnit.SECONDS.sleep(1); } catch (InterruptedException ie) { } } @@ -339,7 +339,7 @@ public class WizardCardsImageSource implements CardImageSource { int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0")); URL url = new URL(urlString); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort)); - HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy); + HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy); uc.connect(); @@ -359,7 +359,7 @@ public class WizardCardsImageSource implements CardImageSource { Document landDoc = getDocument(urlLandDocument); Elements variations = landDoc.select("a.variationlink"); Map links = new HashMap<>(); - if(!variations.isEmpty()) { + if (!variations.isEmpty()) { int landNumber = 1; for (Element variation : variations) { Integer landMultiverseId = Integer.parseInt(variation.attr("onclick").replaceAll("[^\\d]", "")); @@ -374,7 +374,7 @@ public class WizardCardsImageSource implements CardImageSource { } private static String generateLink(int landMultiverseId) { - return "/Handlers/Image.ashx?multiverseid=" +landMultiverseId + "&type=card"; + return "/Handlers/Image.ashx?multiverseid=" + landMultiverseId + "&type=card"; } private int getLocalizedMultiverseId(String preferedLanguage, Integer multiverseId) throws IOException { @@ -396,7 +396,7 @@ public class WizardCardsImageSource implements CardImageSource { Document cardLanguagesDoc = getDocument(cardLanguagesUrl); Elements languageTableRows = cardLanguagesDoc.select("tr.cardItem"); HashMap localizedIds = new HashMap<>(); - if(!languageTableRows.isEmpty()) { + if (!languageTableRows.isEmpty()) { for (Element languageTableRow : languageTableRows) { Elements languageTableColumns = languageTableRow.select("td"); Integer localizedId = Integer.parseInt(languageTableColumns.get(0).select("a").first().attr("href").replaceAll("[^\\d]", "")); @@ -408,14 +408,14 @@ public class WizardCardsImageSource implements CardImageSource { } private String normalizeName(String name) { - //Split card - if(name.contains("//")) { - name = name.substring(0, name.indexOf('(') - 1); - } - //Special timeshifted name - if(name.startsWith("XX")) { - name = name.substring(name.indexOf('(') + 1, name.length() - 1); - } + //Split card + if (name.contains("//")) { + name = name.substring(0, name.indexOf('(') - 1); + } + //Special timeshifted name + if (name.startsWith("XX")) { + name = name.substring(name.indexOf('(') + 1, name.length() - 1); + } return name.replace("\u2014", "-").replace("\u2019", "'") .replace("\u00C6", "AE").replace("\u00E6", "ae") .replace("\u00C3\u2020", "AE") @@ -445,7 +445,7 @@ public class WizardCardsImageSource implements CardImageSource { if (link == null) { int length = collectorId.length(); - if (Character.isLetter(collectorId.charAt(length -1))) { + if (Character.isLetter(collectorId.charAt(length - 1))) { length -= 1; } @@ -507,17 +507,17 @@ public class WizardCardsImageSource implements CardImageSource { } } - + @Override public int getTotalImages() { return -1; } - + @Override public boolean isTokenSource() { return false; } - + @Override public void doPause(String httpImageUrl) { } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 22d2d9f5ba9..e93a4f881d4 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -1,5 +1,22 @@ package org.mage.plugins.card.images; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.net.*; +import java.nio.file.AccessDeniedException; +import java.util.*; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.FileImageOutputStream; +import javax.swing.*; import mage.cards.repository.CardInfo; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; @@ -15,23 +32,6 @@ import org.mage.plugins.card.dl.sources.*; import org.mage.plugins.card.properties.SettingsManager; import org.mage.plugins.card.utils.CardImageUtils; -import javax.imageio.IIOImage; -import javax.imageio.ImageIO; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.imageio.stream.FileImageOutputStream; -import javax.swing.*; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.*; -import java.net.*; -import java.nio.file.AccessDeniedException; -import java.util.*; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicBoolean; - public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable { private static final Logger logger = Logger.getLogger(DownloadPictures.class); @@ -316,7 +316,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab List cardsToDownload = Collections.synchronizedList(new ArrayList<>()); allCardsUrls.parallelStream().forEach(card -> { TFile file = new TFile(CardImageUtils.generateImagePath(card)); - logger.debug(card.getName() + " (is_token=" + card.isToken() + "). Image is here:" + file.getAbsolutePath() + " (exists=" + file.exists() +')'); + logger.debug(card.getName() + " (is_token=" + card.isToken() + "). Image is here:" + file.getAbsolutePath() + " (exists=" + file.exists() + ')'); if (!file.exists()) { logger.debug("Missing: " + file.getAbsolutePath()); cardsToDownload.add(card); @@ -345,9 +345,8 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab return list; } - - try(InputStreamReader input = new InputStreamReader(in); - BufferedReader reader = new BufferedReader(input)) { + try (InputStreamReader input = new InputStreamReader(in); + BufferedReader reader = new BufferedReader(input)) { String line = reader.readLine(); while (line != null) { @@ -486,7 +485,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab executor.shutdown(); while (!executor.isTerminated()) { try { - Thread.sleep(1000); + TimeUnit.SECONDS.sleep(1); } catch (InterruptedException ie) { } } diff --git a/Mage.Client/src/main/resources/card-pictures-tok.txt b/Mage.Client/src/main/resources/card-pictures-tok.txt index b242976bacb..b4ddbd99d1e 100644 --- a/Mage.Client/src/main/resources/card-pictures-tok.txt +++ b/Mage.Client/src/main/resources/card-pictures-tok.txt @@ -1,3 +1,27 @@ +|Generate|TOK:AKH|Trueheart Duelist|| + +|Generate|TOK:MM3|Angel|| +|Generate|TOK:MM3|Beast|1| +|Generate|TOK:MM3|Beast|2| +|Generate|TOK:MM3|Bird|| +|Generate|TOK:MM3|Centaur|| +|Generate|TOK:MM3|Dragon|| +|Generate|TOK:MM3|Elemental|| +|Generate|TOK:MM3|Elephant|| +|Generate|TOK:MM3|Giant Warrior|| +|Generate|TOK:MM3|Goblin|| +|Generate|TOK:MM3|Goblin Warrior|| +|Generate|TOK:MM3|Golem|| +|Generate|TOK:MM3|Ooze|| +|Generate|TOK:MM3|Saproling|| +|Generate|TOK:MM3|Soldier|1| +|Generate|TOK:MM3|Soldier|2| +|Generate|TOK:MM3|Spider|| +|Generate|TOK:MM3|Spirit|| +|Generate|TOK:MM3|Wurm|| +|Generate|TOK:MM3|Zombie|| +|Generate|EMBLEM!:MM3|Emblem Domri|| + |Generate|TOK:C16|Beast|| |Generate|TOK:C16|Bird|1| |Generate|TOK:C16|Bird|2| diff --git a/Mage.Client/src/main/resources/image.url.properties b/Mage.Client/src/main/resources/image.url.properties index 2d32397f850..9f5e89bcde7 100644 --- a/Mage.Client/src/main/resources/image.url.properties +++ b/Mage.Client/src/main/resources/image.url.properties @@ -74,6 +74,6 @@ dd3evg=ddaevg dd3gvl=ddagvl dd3jvc=ddajvc # Remove setname as soon as the images can be downloaded -ignore.urls=TOK,PCA,DDS,ANB,AKH,HOU +ignore.urls=TOK,PCA,ANB,HOU # sets ordered by release time (newest goes first) token.lookup.order=ANB,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC \ No newline at end of file diff --git a/Mage.Client/src/test/java/mage/client/game/MultiConnectTest.java b/Mage.Client/src/test/java/mage/client/game/MultiConnectTest.java index 51d99cfe165..1974187c4d4 100644 --- a/Mage.Client/src/test/java/mage/client/game/MultiConnectTest.java +++ b/Mage.Client/src/test/java/mage/client/game/MultiConnectTest.java @@ -1,5 +1,8 @@ package mage.client.game; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.swing.*; import mage.client.components.MageUI; import mage.interfaces.MageClient; import mage.interfaces.callback.ClientCallback; @@ -10,9 +13,6 @@ import mage.utils.MageVersion; import org.apache.log4j.Logger; import org.junit.Ignore; -import javax.swing.*; -import java.util.concurrent.CountDownLatch; - /** * Test for emulating the connection from multi mage clients. * @@ -30,7 +30,7 @@ public class MultiConnectTest { private static final CountDownLatch latch = new CountDownLatch(USER_CONNECT_COUNT); - private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); + private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO); private static volatile int connected; @@ -116,7 +116,7 @@ public class MultiConnectTest { private void sleep(int ms) { try { - Thread.sleep(ms); + TimeUnit.MILLISECONDS.sleep(ms); } catch (Exception e) { e.printStackTrace(); } diff --git a/Mage.Client/src/test/java/mage/client/game/StartMultiGamesTest.java b/Mage.Client/src/test/java/mage/client/game/StartMultiGamesTest.java index f5dea6e8c51..e8ec74705c0 100644 --- a/Mage.Client/src/test/java/mage/client/game/StartMultiGamesTest.java +++ b/Mage.Client/src/test/java/mage/client/game/StartMultiGamesTest.java @@ -1,13 +1,13 @@ package mage.client.game; +import java.util.concurrent.TimeUnit; +import javax.swing.*; import mage.client.MageFrame; import mage.client.components.MageComponents; import mage.client.components.MageUI; import org.apache.log4j.Logger; import org.junit.Ignore; -import javax.swing.*; - /** * @author ayratn */ @@ -68,7 +68,7 @@ public class StartMultiGamesTest { private void sleep(int ms) { try { - Thread.sleep(ms); + TimeUnit.MILLISECONDS.sleep(ms); } catch (Exception e) { e.printStackTrace(); } diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index bf144fa7150..2b505a128ad 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -27,10 +27,6 @@ */ package mage.interfaces; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.cards.repository.CardInfo; @@ -40,15 +36,15 @@ import mage.constants.PlayerAction; import mage.game.GameException; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.players.net.UserData; import mage.utils.MageVersion; -import mage.view.DraftPickView; -import mage.view.GameView; -import mage.view.MatchView; -import mage.view.RoomUsersView; -import mage.view.TableView; -import mage.view.TournamentView; -import mage.view.UserView; +import mage.view.*; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; /** * @@ -94,9 +90,9 @@ public interface MageServer { TableView createTournamentTable(String sessionId, UUID roomId, TournamentOptions tournamentOptions) throws MageException; - boolean joinTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; + boolean joinTable(String sessionId, UUID roomId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; - boolean joinTournamentTable(String sessionId, UUID roomId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; + boolean joinTournamentTable(String sessionId, UUID roomId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException, GameException; boolean submitDeck(String sessionId, UUID tableId, DeckCardLists deckList) throws MageException, GameException; diff --git a/Mage.Common/src/mage/interfaces/ServerState.java b/Mage.Common/src/mage/interfaces/ServerState.java index 8208b44f037..02f2c4a8d25 100644 --- a/Mage.Common/src/mage/interfaces/ServerState.java +++ b/Mage.Common/src/mage/interfaces/ServerState.java @@ -28,15 +28,15 @@ package mage.interfaces; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - +import mage.players.PlayerType; import mage.utils.MageVersion; import mage.view.GameTypeView; import mage.view.TournamentTypeView; +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + /** * @author BetaSteward_at_googlemail.com */ @@ -44,7 +44,7 @@ public class ServerState implements Serializable { private final List gameTypes; private final List tournamentTypes; - private final String[] playerTypes; + private final PlayerType[] playerTypes; private final String[] deckTypes; private final String[] draftCubes; private final boolean testMode; @@ -53,7 +53,7 @@ public class ServerState implements Serializable { private final long expansionsContentVersion; public ServerState(List gameTypes, List tournamentTypes, - String[] playerTypes, String[] deckTypes, String[] draftCubes, boolean testMode, + PlayerType[] playerTypes, String[] deckTypes, String[] draftCubes, boolean testMode, MageVersion version, long cardsContentVersion, long expansionsContentVersion) { this.gameTypes = gameTypes; this.tournamentTypes = tournamentTypes; @@ -81,7 +81,7 @@ public class ServerState implements Serializable { return tournamentTypes; } - public String[] getPlayerTypes() { + public PlayerType[] getPlayerTypes() { return playerTypes; } diff --git a/Mage.Common/src/mage/interfaces/callback/ClientCallback.java b/Mage.Common/src/mage/interfaces/callback/ClientCallback.java index 366045102f9..868d70e065d 100644 --- a/Mage.Common/src/mage/interfaces/callback/ClientCallback.java +++ b/Mage.Common/src/mage/interfaces/callback/ClientCallback.java @@ -39,18 +39,18 @@ public class ClientCallback implements Serializable { private UUID objectId; private Object data; - private String method; + private ClientCallbackMethod method; private int messageId; public ClientCallback() {} - public ClientCallback(String method, UUID objectId, Object data) { + public ClientCallback(ClientCallbackMethod method, UUID objectId, Object data) { this.method = method; this.objectId = objectId; this.data = data; } - public ClientCallback(String method, UUID objectId) { + public ClientCallback(ClientCallbackMethod method, UUID objectId) { this(method, objectId, null); } @@ -75,11 +75,11 @@ public class ClientCallback implements Serializable { this.data = data; } - public String getMethod() { + public ClientCallbackMethod getMethod() { return method; } - public void setMethod(String method) { + public void setMethod(ClientCallbackMethod method) { this.method = method; } diff --git a/Mage.Common/src/mage/interfaces/callback/ClientCallbackMethod.java b/Mage.Common/src/mage/interfaces/callback/ClientCallbackMethod.java new file mode 100644 index 00000000000..9e3180f3a8b --- /dev/null +++ b/Mage.Common/src/mage/interfaces/callback/ClientCallbackMethod.java @@ -0,0 +1,46 @@ +package mage.interfaces.callback; + +/** + * Created by IGOUDT on 4-4-2017. + */ +public enum ClientCallbackMethod { + + CHATMESSAGE("chatMessage"), + TOURNAMENT_INIT("tournamentInit"), + TOURNAMENT_UPDATE("tournamentUpdate"), + TOURNAMENT_OVER("tournamentOver"), + JOINED_TABLE("joinedTable"), + START_DRAFT("startDraft"), + START_TOURNAMENT("startTournament"), + SIDEBOARD("sideboard"), + CONSTRUCT("construct"), + SHOW_USERMESSAGE("showUserMessage"), + WATCHGAME("watchGame"), + REPLAY_GAME("replayGame"), + START_GAME("startGame"), + SHOW_TOURNAMENT("showTournament"), + SHOW_GAME_END_DIALOG("showGameEndDialog"), + SERVER_MESSAGE("serverMessage"), + GAME_INIT("gameInit"), + GAME_OVER("gameOver"), + GAME_INFORM("gameInform"), + GAME_INFORM_PERSONAL("gameInformPersonal"), + GAME_ERROR("gameError"), + GAME_UPDATE("gameUpdate"), + DRAFT_OVER("draftOver"), + REPLAY_DONE("replayDone"), + USER_REQUEST_DIALOG("userRequestDialog"), + REPLAY_UPDATE("replayUpdate"), + REPLAY_INIT("replayInit"), + END_GAME_INFO("endGameInfo"), + GAME_TARGET("gameTarget"), + GAME_CHOOSE_ABILITY("gameChooseAbility"), + GAME_CHOOSE_PILE("gameChoosePile"), + GAME_CHOOSE_CHOICE("gameChooseChoice"), GAME_ASK("gameAsk"), GAME_SELECT("gameSelect"), GAME_PLAY_MANA("gamePlayMana"), GAME_PLAY_XMANA("gamePlayXMana"), GAME_GET_AMOUNT("gameSelectAmount"), DRAFT_INIT("draftInit"), DRAFT_INFORM("draftInform"), DRAFT_PICK("draftPick"), DRAFT_UPDATE("draftUpdate"); + + String value; + + ClientCallbackMethod(String value){ + this.value = value; + } +} diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java index 46d6cc8aa40..b2c46a93963 100644 --- a/Mage.Common/src/mage/remote/SessionImpl.java +++ b/Mage.Common/src/mage/remote/SessionImpl.java @@ -27,13 +27,6 @@ */ package mage.remote; -import java.io.IOException; -import java.lang.reflect.UndeclaredThrowableException; -import java.net.*; -import java.util.*; -import java.util.concurrent.TimeUnit; -import javax.swing.JOptionPane; - import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.cards.decks.InvalidDeckException; @@ -50,6 +43,7 @@ import mage.interfaces.MageClient; import mage.interfaces.MageServer; import mage.interfaces.ServerState; import mage.interfaces.callback.ClientCallback; +import mage.players.PlayerType; import mage.players.net.UserData; import mage.utils.CompressUtil; import mage.view.*; @@ -62,6 +56,13 @@ import org.jboss.remoting.transport.bisocket.Bisocket; import org.jboss.remoting.transport.socket.SocketWrapper; import org.jboss.remoting.transporter.TransporterClient; +import javax.swing.*; +import java.io.IOException; +import java.lang.reflect.UndeclaredThrowableException; +import java.net.*; +import java.util.*; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -550,7 +551,7 @@ public class SessionImpl implements Session { } @Override - public String[] getPlayerTypes() { + public PlayerType[] getPlayerTypes() { return serverState.getPlayerTypes(); } @@ -680,7 +681,7 @@ public class SessionImpl implements Session { } @Override - public boolean joinTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill, DeckCardLists deckList, String password) { + public boolean joinTable(UUID roomId, UUID tableId, String playerName, PlayerType playerType, int skill, DeckCardLists deckList, String password) { try { if (isConnected()) { // Workaround to fix Can't join table problem @@ -703,7 +704,7 @@ public class SessionImpl implements Session { } @Override - public boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill, DeckCardLists deckList, String password) { + public boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, PlayerType playerType, int skill, DeckCardLists deckList, String password) { try { if (isConnected()) { // Workaround to fix Can't join table problem diff --git a/Mage.Common/src/mage/remote/interfaces/GameTypes.java b/Mage.Common/src/mage/remote/interfaces/GameTypes.java index d1845d7b386..dc3c90f3502 100644 --- a/Mage.Common/src/mage/remote/interfaces/GameTypes.java +++ b/Mage.Common/src/mage/remote/interfaces/GameTypes.java @@ -28,6 +28,8 @@ package mage.remote.interfaces; import java.util.List; + +import mage.players.PlayerType; import mage.view.GameTypeView; import mage.view.TournamentTypeView; @@ -36,7 +38,7 @@ import mage.view.TournamentTypeView; */ public interface GameTypes { - String[] getPlayerTypes(); + PlayerType[] getPlayerTypes(); List getGameTypes(); List getTournamentGameTypes(); diff --git a/Mage.Common/src/mage/remote/interfaces/PlayerActions.java b/Mage.Common/src/mage/remote/interfaces/PlayerActions.java index dd80ae37b6b..72818ca2f3f 100644 --- a/Mage.Common/src/mage/remote/interfaces/PlayerActions.java +++ b/Mage.Common/src/mage/remote/interfaces/PlayerActions.java @@ -30,6 +30,7 @@ package mage.remote.interfaces; import mage.cards.decks.DeckCardLists; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.remote.MageRemoteException; import mage.view.TableView; import mage.view.TournamentView; @@ -64,13 +65,13 @@ public interface PlayerActions { // boolean startChallenge(UUID roomId, UUID tableId, UUID challengeId); - boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill, DeckCardLists deckList, String password); + boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, PlayerType playerType, int skill, DeckCardLists deckList, String password); boolean watchTable(UUID roomId, UUID tableId); boolean watchTournamentTable(UUID tableId); - boolean joinTable(UUID roomId, UUID tableId, String playerName, String playerType, int skill, DeckCardLists deckList, String password); + boolean joinTable(UUID roomId, UUID tableId, String playerName, PlayerType playerType, int skill, DeckCardLists deckList, String password); Optional getTable(UUID roomId, UUID tableId); diff --git a/Mage.Common/src/mage/utils/DeckBuilder.java b/Mage.Common/src/mage/utils/DeckBuilder.java index 55760f7d28d..19922120b3c 100644 --- a/Mage.Common/src/mage/utils/DeckBuilder.java +++ b/Mage.Common/src/mage/utils/DeckBuilder.java @@ -1,21 +1,14 @@ package mage.utils; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - import mage.Mana; import mage.cards.Card; import mage.cards.decks.Deck; -import mage.constants.CardType; import mage.constants.ColoredManaSymbol; import mage.interfaces.rate.RateCallback; import mage.util.RandomUtil; +import java.util.*; + /** * Builds deck from provided card pool. * @@ -246,13 +239,13 @@ public final class DeckBuilder { this.card = card; int type; - if (card.getCardType().contains(CardType.CREATURE)) { + if (card.isCreature()) { type = 10; } else if (card.getSubtype(null).contains("Equipment")) { type = 8; } else if (card.getSubtype(null).contains("Aura")) { type = 5; - } else if (card.getCardType().contains(CardType.INSTANT)) { + } else if (card.isInstant()) { type = 7; } else { type = 6; diff --git a/Mage.Common/src/mage/view/SeatView.java b/Mage.Common/src/mage/view/SeatView.java index dff17d5e08c..a5e83fd580a 100644 --- a/Mage.Common/src/mage/view/SeatView.java +++ b/Mage.Common/src/mage/view/SeatView.java @@ -27,10 +27,12 @@ */ package mage.view; +import mage.game.Seat; +import mage.players.PlayerType; +import mage.players.net.UserData; + import java.io.Serializable; import java.util.UUID; -import mage.game.Seat; -import mage.players.net.UserData; /** * @@ -43,7 +45,7 @@ public class SeatView implements Serializable { private final String flagName; private UUID playerId; private final String playerName; - private final String playerType; + private final PlayerType playerType; private final String history; private final int generalRating; private final int constructedRating; @@ -86,7 +88,7 @@ public class SeatView implements Serializable { return playerName; } - public String getPlayerType() { + public PlayerType getPlayerType() { return playerType; } diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index 0a36060891c..23e6ee2ec1d 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -27,11 +27,6 @@ */ package mage.deck; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; @@ -42,11 +37,12 @@ import mage.cards.ExpansionSet; import mage.cards.Sets; import mage.cards.decks.Constructed; import mage.cards.decks.Deck; -import mage.constants.CardType; import mage.constants.SetType; import mage.filter.FilterMana; import mage.util.CardUtil; +import java.util.*; + /** * * @author Plopman @@ -501,7 +497,7 @@ public class Commander extends Constructed { thisMaxPower = Math.max(thisMaxPower, 1); } - if (card.getCardType().contains(CardType.PLANESWALKER)) { + if (card.isPlaneswalker()) { if (card.getName().toLowerCase().equals("jace, the mind sculptor")) { thisMaxPower = Math.max(thisMaxPower, 6); } @@ -511,7 +507,7 @@ public class Commander extends Constructed { thisMaxPower = Math.max(thisMaxPower, 4); } - if (card.getCardType().contains(CardType.LAND)) { + if (card.isLand()) { thisMaxPower = 0; } diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java index 04ed14327fd..d5ad689c8f3 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java @@ -1,6 +1,5 @@ package mage.player.ai.ma; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.keyword.HasteAbility; @@ -11,6 +10,8 @@ import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; +import java.util.UUID; + /** * @author ubeefx, nantuko */ @@ -27,7 +28,7 @@ public final class ArtificialScoringSystem { public static int getCardDefinitionScore(final Game game, final Card card) { int value = 3; //TODO: add new rating system card value - if (card.getCardType().contains(CardType.LAND)) { + if (card.isLand()) { int score = (int) ((value / 2.0f) * 50); //TODO: check this for "any color" lands //TODO: check this for dual and filter lands diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java index bdd761b68d0..bfb41b55fe4 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/utils/RateCard.java @@ -4,7 +4,6 @@ import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.Card; -import mage.constants.CardType; import mage.constants.ColoredManaSymbol; import mage.constants.Outcome; import mage.target.Target; @@ -57,15 +56,15 @@ public final class RateCard { return rate; } int type; - if (card.getCardType().contains(CardType.PLANESWALKER)) { + if (card.isPlaneswalker()) { type = 15; - } else if (card.getCardType().contains(CardType.CREATURE)) { + } else if (card.isCreature()) { type = 10; } else if (card.getSubtype(null).contains("Equipment")) { type = 8; } else if (card.getSubtype(null).contains("Aura")) { type = 5; - } else if (card.getCardType().contains(CardType.INSTANT)) { + } else if (card.isInstant()) { type = 7; } else { type = 6; @@ -78,8 +77,7 @@ public final class RateCard { } private static int isRemoval(Card card) { - if (card.getSubtype(null).contains("Aura") || card.getCardType().contains(CardType.INSTANT) - || card.getCardType().contains(CardType.SORCERY)) { + if (card.getSubtype(null).contains("Aura") || card.isInstant() || card.isSorcery()) { for (Ability ability : card.getAbilities()) { for (Effect effect : ability.getEffects()) { diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index afc14c45f35..0f8ae477a9d 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -27,30 +27,13 @@ */ package mage.player.human; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.ActivatedAbility; -import mage.abilities.Mode; -import mage.abilities.Modes; -import mage.abilities.PlayLandAbility; -import mage.abilities.SpecialAction; -import mage.abilities.SpellAbility; -import mage.abilities.TriggeredAbility; +import mage.abilities.*; import mage.abilities.costs.VariableCost; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.costs.mana.PhyrexianManaCost; import mage.abilities.effects.RequirementEffect; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.Card; @@ -58,22 +41,7 @@ import mage.cards.Cards; import mage.cards.decks.Deck; import mage.choices.Choice; import mage.choices.ChoiceImpl; -import mage.constants.AbilityType; -import mage.constants.CardType; -import mage.constants.Constants; -import mage.constants.ManaType; -import mage.constants.Outcome; -import mage.constants.PhaseStep; -import mage.constants.PlayerAction; -import static mage.constants.PlayerAction.HOLD_PRIORITY; -import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_ID_NO; -import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_LAST; -import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; -import mage.constants.RangeOfInfluence; -import static mage.constants.SpellAbilityType.SPLIT; -import static mage.constants.SpellAbilityType.SPLIT_FUSED; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterBlockingCreature; import mage.filter.common.FilterCreatureForCombat; @@ -102,6 +70,12 @@ import mage.util.ManaUtil; import mage.util.MessageToClient; import org.apache.log4j.Logger; +import java.io.Serializable; +import java.util.*; + +import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL; +import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL; + /** * * @author BetaSteward_at_googlemail.com @@ -1275,7 +1249,7 @@ public class HumanPlayer extends PlayerImpl { return; } } - if (userData.isUseFirstManaAbility() && object instanceof Permanent && object.getCardType().contains(CardType.LAND)) { + if (userData.isUseFirstManaAbility() && object instanceof Permanent && object.isLand()) { ActivatedAbility ability = abilities.values().iterator().next(); if (ability instanceof ActivatedManaAbilityImpl) { activateAbility(ability, game); diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java index e77b9b12dd1..1a826f53d7f 100644 --- a/Mage.Server/src/main/java/mage/server/ChatManager.java +++ b/Mage.Server/src/main/java/mage/server/ChatManager.java @@ -50,7 +50,6 @@ public enum ChatManager { private static final Logger logger = Logger.getLogger(ChatManager.class); private static final HashMap userMessages = new HashMap<>(); - private final ConcurrentHashMap chatSessions = new ConcurrentHashMap<>(); public UUID createChatSession(String info) { @@ -159,7 +158,6 @@ public enum ChatManager { userMessages.put(userName, message); - if (messageType == MessageType.TALK) { if (user.getChatLockedUntil() != null) { if (user.getChatLockedUntil().compareTo(Calendar.getInstance().getTime()) > 0) { @@ -173,8 +171,8 @@ public enum ChatManager { } } - chatSession.broadcast(userName, message, color, withTime, messageType, soundToPlay); } + chatSession.broadcast(userName, message, color, withTime, messageType, soundToPlay); } } @@ -255,11 +253,11 @@ public enum ChatManager { } public void sendReconnectMessage(UUID userId) { - UserManager.instance.getUser(userId).ifPresent(user -> - chatSessions.values() - .stream() - .filter(chat -> chat.hasUser(userId)) - .forEach(chatSession -> chatSession.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS, null))); + UserManager.instance.getUser(userId).ifPresent(user + -> chatSessions.values() + .stream() + .filter(chat -> chat.hasUser(userId)) + .forEach(chatSession -> chatSession.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS, null))); } @@ -275,6 +273,4 @@ public enum ChatManager { return new ArrayList<>(chatSessions.values()); } - } - diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 8abfdce3344..f7a9c969fbb 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -28,6 +28,7 @@ package mage.server; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.view.ChatMessage; import mage.view.ChatMessage.MessageColor; import mage.view.ChatMessage.MessageType; @@ -61,14 +62,14 @@ public class ChatSession { } public void join(UUID userId) { - UserManager.instance.getUser(userId).ifPresent(user-> { - if (!clients.containsKey(userId)) { - String userName = user.getName(); - clients.put(userId, userName); - broadcast(null, userName + " has joined (" + user.getClientVersion() + ')', MessageColor.BLUE, true, MessageType.STATUS, null); - logger.trace(userName + " joined chat " + chatId); - } - }); + UserManager.instance.getUser(userId).ifPresent(user -> { + if (!clients.containsKey(userId)) { + String userName = user.getName(); + clients.put(userId, userName); + broadcast(null, userName + " has joined (" + user.getClientVersion() + ')', MessageColor.BLUE, true, MessageType.STATUS, null); + logger.trace(userName + " joined chat " + chatId); + } + }); } public void kill(UUID userId, DisconnectReason reason) { @@ -84,30 +85,9 @@ public class ChatSession { clients.remove(userId); logger.debug(userName + '(' + reason.toString() + ')' + " removed from chatId " + chatId); } - String message; - switch (reason) { - case Disconnected: - message = " has left XMage"; - break; - case LostConnection: - message = " has lost connection"; - break; - case SessionExpired: - message = " session expired"; - break; - case AdminDisconnect: - message = " was disconnected by the Admin"; - break; - case ConnectingOtherInstance: - message = " reconnected and replaced still active old session"; - break; - case CleaningUp: - message = null; - break; - default: - message = " left (" + reason.toString() + ')'; - } - if (message != null) { + String message = reason.getMessage(); + + if (!message.isEmpty()) { broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS, null); } } @@ -118,7 +98,7 @@ public class ChatSession { public boolean broadcastInfoToUser(User toUser, String message) { if (clients.containsKey(toUser.getId())) { - toUser.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(null, message, timeFormatter.format(new Date()), MessageColor.BLUE, MessageType.USER_INFO, null))); + toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, new ChatMessage(null, message, timeFormatter.format(new Date()), MessageColor.BLUE, MessageType.USER_INFO, null))); return true; } return false; @@ -126,10 +106,10 @@ public class ChatSession { public boolean broadcastWhisperToUser(User fromUser, User toUser, String message) { if (clients.containsKey(toUser.getId())) { - toUser.fireCallback(new ClientCallback("chatMessage", chatId, + toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, 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, + fromUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, new ChatMessage(toUser.getName(), message, timeFormatter.format(new Date()), MessageColor.YELLOW, MessageType.WHISPER_TO, null))); return true; } @@ -139,24 +119,20 @@ public class ChatSession { public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) { if (!message.isEmpty()) { - HashSet clientsToRemove = null; - ClientCallback clientCallback = new ClientCallback("chatMessage", chatId, new ChatMessage(userName, message, (withTime ? timeFormatter.format(new Date()) : ""), color, messageType, soundToPlay)); + HashSet clientsToRemove = new HashSet<>(); + ClientCallback clientCallback = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, new ChatMessage(userName, message, (withTime ? timeFormatter.format(new Date()) : ""), color, messageType, soundToPlay)); for (UUID userId : clients.keySet()) { Optional user = UserManager.instance.getUser(userId); if (user.isPresent()) { user.get().fireCallback(clientCallback); } else { - if (clientsToRemove == null) { - clientsToRemove = new HashSet<>(); - } clientsToRemove.add(userId); } } - if (clientsToRemove != null) { - for (UUID userIdToRemove : clientsToRemove) { - clients.remove(userIdToRemove); - } + for (UUID userIdToRemove : clientsToRemove) { + clients.remove(userIdToRemove); } + } } diff --git a/Mage.Server/src/main/java/mage/server/DisconnectReason.java b/Mage.Server/src/main/java/mage/server/DisconnectReason.java index c751814f7bb..576c64f2c7e 100644 --- a/Mage.Server/src/main/java/mage/server/DisconnectReason.java +++ b/Mage.Server/src/main/java/mage/server/DisconnectReason.java @@ -6,5 +6,20 @@ package mage.server; */ public enum DisconnectReason { - LostConnection, Disconnected, CleaningUp, ConnectingOtherInstance, AdminDisconnect, SessionExpired, Undefined + LostConnection(" has lost connection"), + Disconnected(" has left XMage"), + CleaningUp(" [cleaning up]"), + ConnectingOtherInstance(" reconnected and replaced still active old session"), + AdminDisconnect(" was disconnected by the Admin"), + SessionExpired(" session expired"), + Undefined(""); + + String message; + DisconnectReason(String message){ + this.message = message; + } + + public String getMessage(){ + return message; + } } diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index 0c28c809177..ef727c93a4b 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -45,6 +45,8 @@ import mage.interfaces.ActionWithResult; import mage.interfaces.MageServer; import mage.interfaces.ServerState; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; +import mage.players.PlayerType; import mage.players.net.UserData; import mage.remote.MageVersionException; import mage.server.draft.CubeFactory; @@ -74,7 +76,7 @@ import java.util.concurrent.ExecutorService; public class MageServerImpl implements MageServer { private static final Logger logger = Logger.getLogger(MageServerImpl.class); - private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); + private static final ExecutorService callExecutor = ThreadExecutor.instance.getCallExecutor(); private static final SecureRandom RANDOM = new SecureRandom(); private final String adminPassword; @@ -233,8 +235,8 @@ public class MageServerImpl implements MageServer { String maxAiOpponents = ConfigSettings.instance.getMaxAiOpponents(); if (maxAiOpponents != null) { int aiPlayers = 0; - for (String playerType : options.getPlayerTypes()) { - if (!playerType.equals("Human")) { + for (PlayerType playerType : options.getPlayerTypes()) { + if (playerType != PlayerType.HUMAN) { aiPlayers++; } } @@ -282,7 +284,7 @@ public class MageServerImpl implements MageServer { } @Override - public boolean joinTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final String playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException { + public boolean joinTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException { return executeWithResult("joinTable", sessionId, new ActionWithBooleanResult() { @Override public Boolean execute() throws MageException { @@ -309,7 +311,7 @@ public class MageServerImpl implements MageServer { } @Override - public boolean joinTournamentTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final String playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException { + public boolean joinTournamentTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException { return executeWithResult("joinTournamentTable", sessionId, new ActionWithBooleanResult() { @Override public Boolean execute() throws MageException { @@ -989,11 +991,11 @@ public class MageServerImpl implements MageServer { public ServerState getServerState() throws MageException { try { return new ServerState( - GameFactory.getInstance().getGameTypes(), - TournamentFactory.getInstance().getTournamentTypes(), - PlayerFactory.getInstance().getPlayerTypes().toArray(new String[PlayerFactory.getInstance().getPlayerTypes().size()]), - DeckValidatorFactory.getInstance().getDeckTypes().toArray(new String[DeckValidatorFactory.getInstance().getDeckTypes().size()]), - CubeFactory.getInstance().getDraftCubes().toArray(new String[CubeFactory.getInstance().getDraftCubes().size()]), + GameFactory.instance.getGameTypes(), + TournamentFactory.instance.getTournamentTypes(), + PlayerFactory.instance.getPlayerTypes().toArray(new PlayerType[PlayerFactory.instance.getPlayerTypes().size()]), + DeckValidatorFactory.instance.getDeckTypes().toArray(new String[DeckValidatorFactory.instance.getDeckTypes().size()]), + CubeFactory.instance.getDraftCubes().toArray(new String[CubeFactory.instance.getDraftCubes().size()]), testMode, Main.getVersion(), CardRepository.instance.getContentVersionConstant(), @@ -1161,7 +1163,7 @@ public class MageServerImpl implements MageServer { session -> FeedbackServiceImpl.instance.feedback(username, title, type, message, email, session.getHost()) - )); + )); } } @@ -1171,9 +1173,9 @@ public class MageServerImpl implements MageServer { execute("sendBroadcastMessage", sessionId, () -> { for (User user : UserManager.instance.getUsers()) { if (message.toLowerCase(Locale.ENGLISH).startsWith("warn")) { - user.fireCallback(new ClientCallback("serverMessage", null, new ChatMessage("SERVER", message, null, MessageColor.RED))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, MessageColor.RED))); } else { - user.fireCallback(new ClientCallback("serverMessage", null, new ChatMessage("SERVER", message, null, MessageColor.BLUE))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, MessageColor.BLUE))); } } }, true); diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java index 233649b2f3f..52fe274ae1e 100644 --- a/Mage.Server/src/main/java/mage/server/Main.java +++ b/Mage.Server/src/main/java/mage/server/Main.java @@ -62,7 +62,6 @@ import org.w3c.dom.Element; import javax.management.MBeanServer; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.net.InetAddress; import java.net.MalformedURLException; import java.util.*; @@ -164,31 +163,31 @@ public final class Main { deleteSavedGames(); ConfigSettings config = ConfigSettings.instance; for (GamePlugin plugin : config.getGameTypes()) { - GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); + GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); } for (GamePlugin plugin : config.getTournamentTypes()) { - TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin)); + TournamentFactory.instance.addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin)); } for (Plugin plugin : config.getPlayerTypes()) { - PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin)); + PlayerFactory.instance.addPlayerType(plugin.getName(), loadPlugin(plugin)); } for (Plugin plugin : config.getDraftCubes()) { - CubeFactory.getInstance().addDraftCube(plugin.getName(), loadPlugin(plugin)); + CubeFactory.instance.addDraftCube(plugin.getName(), loadPlugin(plugin)); } for (Plugin plugin : config.getDeckTypes()) { - DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin)); + DeckValidatorFactory.instance.addDeckType(plugin.getName(), loadPlugin(plugin)); } for (ExtensionPackage pkg : extensions) { Map draftCubes = pkg.getDraftCubes(); for (String name : draftCubes.keySet()) { logger.info("Loading extension: [" + name + "] " + draftCubes.get(name).toString()); - CubeFactory.getInstance().addDraftCube(name, draftCubes.get(name)); + CubeFactory.instance.addDraftCube(name, draftCubes.get(name)); } Map deckTypes = pkg.getDeckTypes(); for (String name : deckTypes.keySet()) { logger.info("Loading extension: [" + name + "] " + deckTypes.get(name)); - DeckValidatorFactory.getInstance().addDeckType(name, deckTypes.get(name)); + DeckValidatorFactory.instance.addDeckType(name, deckTypes.get(name)); } } diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index a96129aa3b0..fe01b269c01 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -30,6 +30,7 @@ package mage.server; import mage.MageException; import mage.constants.Constants; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.players.net.UserData; import mage.players.net.UserGroup; import mage.server.game.GamesRoom; @@ -423,14 +424,14 @@ public class Session { List messageData = new LinkedList<>(); messageData.add("Error while connecting to server"); messageData.add(message); - fireCallback(new ClientCallback("showUserMessage", null, messageData)); + fireCallback(new ClientCallback(ClientCallbackMethod.SHOW_USERMESSAGE, null, messageData)); } public void sendInfoMessageToClient(String message) { List messageData = new LinkedList<>(); messageData.add("Information about connecting to the server"); messageData.add(message); - fireCallback(new ClientCallback("showUserMessage", null, messageData)); + fireCallback(new ClientCallback(ClientCallbackMethod.SHOW_USERMESSAGE, null, messageData)); } public static Throwable getBasicCause(Throwable cause) { diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index e45b0ed816e..cda5d61d04b 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -45,6 +45,7 @@ import mage.game.tournament.Tournament; import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentPlayer; import mage.players.Player; +import mage.players.PlayerType; import mage.server.draft.DraftManager; import mage.server.game.DeckValidatorFactory; import mage.server.game.GameFactory; @@ -87,12 +88,12 @@ public class TableController { private Tournament tournament; private ScheduledFuture futureTimeout; - protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor(); + protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.instance.getTimeoutExecutor(); public TableController(UUID roomId, UUID userId, MatchOptions options) { this.userId = userId; this.options = options; - match = GameFactory.getInstance().createMatch(options.getGameType(), options); + match = GameFactory.instance.createMatch(options.getGameType(), options); if (userId != null) { Optional user = UserManager.instance.getUser(userId); // TODO: Handle if user == null @@ -100,14 +101,14 @@ 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, options.getBannedUsers()); + table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()), options.getPlayerTypes(), TableRecorderImpl.instance, match, options.getBannedUsers()); chatId = ChatManager.instance.createChatSession("Match Table " + table.getId()); init(); } public TableController(UUID roomId, UUID userId, TournamentOptions options) { this.userId = userId; - tournament = TournamentFactory.getInstance().createTournament(options.getTournamentType(), options); + tournament = TournamentFactory.instance.createTournament(options.getTournamentType(), options); if (userId != null) { Optional user = UserManager.instance.getUser(userId); if (!user.isPresent()) { @@ -119,7 +120,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, options.getMatchOptions().getBannedUsers()); + table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes(), TableRecorderImpl.instance, tournament, options.getMatchOptions().getBannedUsers()); chatId = ChatManager.instance.createChatSession("Tourn. table " + table.getId()); } @@ -139,7 +140,7 @@ public class TableController { ); } - public synchronized boolean joinTournament(UUID userId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws GameException { + public synchronized boolean joinTournament(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException { if (table.getState() != TableState.WAITING) { return false; } @@ -155,13 +156,13 @@ public class TableController { } User user = _user.get(); // check password - if (!table.getTournament().getOptions().getPassword().isEmpty() && playerType.equals("Human")) { + if (!table.getTournament().getOptions().getPassword().isEmpty() && playerType == PlayerType.HUMAN) { if (!table.getTournament().getOptions().getPassword().equals(password)) { user.showUserMessage("Join Table", "Wrong password."); return false; } } - if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) { + if (userPlayerMap.containsKey(userId) && playerType == PlayerType.HUMAN) { user.showUserMessage("Join Table", "You can join a table only one time."); return false; } @@ -228,7 +229,7 @@ public class TableController { return userPlayerMap.containsKey(userId); } - public synchronized boolean replaceDraftPlayer(Player oldPlayer, String name, String playerType, int skill) { + public synchronized boolean replaceDraftPlayer(Player oldPlayer, String name, PlayerType playerType, int skill) { Optional newPlayerOpt = createPlayer(name, playerType, skill); if (!newPlayerOpt.isPresent() || table.getState() != TableState.DRAFTING) { return false; @@ -246,13 +247,13 @@ public class TableController { return true; } - public synchronized boolean joinTable(UUID userId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException { + public synchronized boolean joinTable(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException { Optional _user = UserManager.instance.getUser(userId); if (!_user.isPresent()) { return false; } User user = _user.get(); - if (userPlayerMap.containsKey(userId) && playerType.equals("Human")) { + if (userPlayerMap.containsKey(userId) && playerType == PlayerType.HUMAN) { user.showUserMessage("Join Table", new StringBuilder("You can join a table only one time.").toString()); return false; } @@ -261,7 +262,7 @@ public class TableController { return false; } // check password - if (!table.getMatch().getOptions().getPassword().isEmpty() && playerType.equals("Human")) { + if (!table.getMatch().getOptions().getPassword().isEmpty() && playerType == PlayerType.HUMAN) { if (!table.getMatch().getOptions().getPassword().equals(password)) { user.showUserMessage("Join Table", "Wrong password."); return false; @@ -370,7 +371,7 @@ public class TableController { return true; } - public void addPlayer(UUID userId, Player player, String playerType, Deck deck) throws GameException { + public void addPlayer(UUID userId, Player player, PlayerType playerType, Deck deck) throws GameException { if (table.getState() != TableState.WAITING) { return; } @@ -480,12 +481,12 @@ public class TableController { // ReplayManager.instance.replayGame(table.getId(), userId); // return true; // } - private Optional createPlayer(String name, String playerType, int skill) { + private Optional createPlayer(String name, PlayerType playerType, int skill) { Optional playerOpt; if (options == null) { - playerOpt = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, skill); + playerOpt = PlayerFactory.instance.createPlayer(playerType, name, RangeOfInfluence.ALL, skill); } else { - playerOpt = PlayerFactory.getInstance().createPlayer(playerType, name, options.getRange(), skill); + playerOpt = PlayerFactory.instance.createPlayer(playerType, name, options.getRange(), skill); } if (playerOpt.isPresent()) { Player player = playerOpt.get(); @@ -876,7 +877,7 @@ public class TableController { if (table.getState() == TableState.READY_TO_START) { if (seatNum1 >= 0 && seatNum2 >= 0 && seatNum1 < table.getSeats().length && seatNum2 < table.getSeats().length) { Player swapPlayer = table.getSeats()[seatNum1].getPlayer(); - String swapType = table.getSeats()[seatNum1].getPlayerType(); + PlayerType swapType = table.getSeats()[seatNum1].getPlayerType(); table.getSeats()[seatNum1].setPlayer(table.getSeats()[seatNum2].getPlayer()); table.getSeats()[seatNum1].setPlayerType(table.getSeats()[seatNum2].getPlayerType()); table.getSeats()[seatNum2].setPlayer(swapPlayer); diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java index a8f0bd5f377..047639386ff 100644 --- a/Mage.Server/src/main/java/mage/server/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -28,17 +28,7 @@ package mage.server; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - import mage.MageException; -import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; import mage.constants.TableState; import mage.game.Game; @@ -50,13 +40,22 @@ import mage.game.match.MatchOptions; import mage.game.tournament.Tournament; import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentPlayer; -import mage.players.Player; +import mage.players.PlayerType; import mage.server.game.GameController; import mage.server.game.GameManager; import mage.server.game.GamesRoomManager; import mage.server.util.ThreadExecutor; import org.apache.log4j.Logger; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -133,14 +132,14 @@ public enum TableManager { return Optional.empty(); } - public boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException { + public boolean joinTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException { if (controllers.containsKey(tableId)) { return controllers.get(tableId).joinTable(userId, name, playerType, skill, deckList, password); } return false; } - public boolean joinTournament(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws GameException { + public boolean joinTournament(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException { if (controllers.containsKey(tableId)) { return controllers.get(tableId).joinTournament(userId, name, playerType, skill, deckList, password); } @@ -376,7 +375,7 @@ public enum TableManager { logger.debug(chatSession.getChatId() + " " + formatter.format(chatSession.getCreateTime()) + ' ' + chatSession.getInfo() + ' ' + chatSession.getClients().values().toString()); } logger.debug("------- Games: " + GameManager.instance.getNumberActiveGames() + " --------------------------------------------"); - logger.debug(" Active Game Worker: " + ThreadExecutor.getInstance().getActiveThreads(ThreadExecutor.getInstance().getGameExecutor())); + logger.debug(" Active Game Worker: " + ThreadExecutor.instance.getActiveThreads(ThreadExecutor.instance.getGameExecutor())); for (Entry entry : GameManager.instance.getGameController().entrySet()) { logger.debug(entry.getKey() + entry.getValue().getPlayerNameList()); } diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 78fe8309932..ee7e96fd715 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -27,10 +27,6 @@ */ package mage.server; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import mage.cards.decks.Deck; import mage.constants.ManaType; import mage.constants.TableState; @@ -38,6 +34,7 @@ import mage.game.Table; import mage.game.result.ResultProtos; import mage.game.tournament.TournamentPlayer; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.players.net.UserData; import mage.server.draft.DraftSession; import mage.server.game.GameManager; @@ -54,6 +51,11 @@ import mage.server.util.SystemUtil; import mage.view.TableClientMessage; import org.apache.log4j.Logger; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -247,52 +249,52 @@ public class User { } public void ccJoinedTable(final UUID roomId, final UUID tableId, boolean isTournament) { - fireCallback(new ClientCallback("joinedTable", tableId, new TableClientMessage(roomId, tableId, isTournament))); + fireCallback(new ClientCallback(ClientCallbackMethod.JOINED_TABLE, tableId, new TableClientMessage(roomId, tableId, isTournament))); } public void ccGameStarted(final UUID gameId, final UUID playerId) { - fireCallback(new ClientCallback("startGame", gameId, new TableClientMessage(gameId, playerId))); + fireCallback(new ClientCallback(ClientCallbackMethod.START_GAME, gameId, new TableClientMessage(gameId, playerId))); } public void ccDraftStarted(final UUID draftId, final UUID playerId) { - fireCallback(new ClientCallback("startDraft", draftId, new TableClientMessage(draftId, playerId))); + fireCallback(new ClientCallback(ClientCallbackMethod.START_DRAFT, draftId, new TableClientMessage(draftId, playerId))); } public void ccTournamentStarted(final UUID tournamentId, final UUID playerId) { - fireCallback(new ClientCallback("startTournament", tournamentId, new TableClientMessage(tournamentId, playerId))); + fireCallback(new ClientCallback(ClientCallbackMethod.START_TOURNAMENT, tournamentId, new TableClientMessage(tournamentId, playerId))); } public void ccSideboard(final Deck deck, final UUID tableId, final int time, boolean limited) { - fireCallback(new ClientCallback("sideboard", tableId, new TableClientMessage(deck, tableId, time, limited))); + fireCallback(new ClientCallback(ClientCallbackMethod.SIDEBOARD, tableId, new TableClientMessage(deck, tableId, time, limited))); sideboarding.put(tableId, deck); } public void ccConstruct(final Deck deck, final UUID tableId, final int time) { - fireCallback(new ClientCallback("construct", tableId, new TableClientMessage(deck, tableId, time))); + fireCallback(new ClientCallback(ClientCallbackMethod.CONSTRUCT, tableId, new TableClientMessage(deck, tableId, time))); } public void ccShowTournament(final UUID tournamentId) { - fireCallback(new ClientCallback("showTournament", tournamentId)); + fireCallback(new ClientCallback(ClientCallbackMethod.SHOW_TOURNAMENT, tournamentId)); } public void ccShowGameEndDialog(final UUID gameId) { - fireCallback(new ClientCallback("showGameEndDialog", gameId)); + fireCallback(new ClientCallback(ClientCallbackMethod.SHOW_GAME_END_DIALOG, gameId)); } public void showUserMessage(final String titel, String message) { List messageData = new LinkedList<>(); messageData.add(titel); messageData.add(message); - fireCallback(new ClientCallback("showUserMessage", null, messageData)); + fireCallback(new ClientCallback(ClientCallbackMethod.SHOW_USERMESSAGE, null, messageData)); } public boolean ccWatchGame(final UUID gameId) { - fireCallback(new ClientCallback("watchGame", gameId)); + fireCallback(new ClientCallback(ClientCallbackMethod.WATCHGAME, gameId)); return true; } public void ccReplayGame(final UUID gameId) { - fireCallback(new ClientCallback("replayGame", gameId)); + fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_GAME, gameId)); } public void sendPlayerUUID(final UUID gameId, final UUID data) { diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 18d45fb7fac..0aaab44e743 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -51,7 +51,7 @@ public enum UserManager { private final ConcurrentHashMap users = new ConcurrentHashMap<>(); - private static final ExecutorService USER_EXECUTOR = ThreadExecutor.getInstance().getCallExecutor(); + private static final ExecutorService USER_EXECUTOR = ThreadExecutor.instance.getCallExecutor(); UserManager() { expireExecutor.scheduleAtFixedRate(this::checkExpired, 60, 60, TimeUnit.SECONDS); diff --git a/Mage.Server/src/main/java/mage/server/challenge/ChallengeManager.java b/Mage.Server/src/main/java/mage/server/challenge/ChallengeManager.java index e239dbbb817..1c9b4f57777 100644 --- a/Mage.Server/src/main/java/mage/server/challenge/ChallengeManager.java +++ b/Mage.Server/src/main/java/mage/server/challenge/ChallengeManager.java @@ -1,10 +1,11 @@ package mage.server.challenge; +import mage.constants.Zone; +import mage.game.match.Match; + import java.util.HashMap; import java.util.Map; import java.util.UUID; -import mage.constants.Zone; -import mage.game.match.Match; /** * C U R R E N T L Y U N U S E D @@ -12,13 +13,9 @@ import mage.game.match.Match; * Loads challenges from scenarios. * Configure games by initializing starting game board. */ -public class ChallengeManager { +public enum ChallengeManager { - public static final ChallengeManager instance = new ChallengeManager(); - - public static ChallengeManager getInstance() { - return instance; - } + instance; public void prepareChallenge(UUID playerId, Match match) { Map commands = new HashMap<>(); diff --git a/Mage.Server/src/main/java/mage/server/draft/CubeFactory.java b/Mage.Server/src/main/java/mage/server/draft/CubeFactory.java index 939b36598e7..0897905532f 100644 --- a/Mage.Server/src/main/java/mage/server/draft/CubeFactory.java +++ b/Mage.Server/src/main/java/mage/server/draft/CubeFactory.java @@ -27,30 +27,27 @@ */ package mage.server.draft; +import mage.cards.decks.Deck; +import mage.game.draft.DraftCube; +import org.apache.log4j.Logger; + import java.lang.reflect.Constructor; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import mage.cards.decks.Deck; -import mage.game.draft.DraftCube; -import org.apache.log4j.Logger; /** * * @author LevelX2 */ -public class CubeFactory { +public enum CubeFactory { - private static final CubeFactory INSTANCE = new CubeFactory(); + instance; private static final Logger logger = Logger.getLogger(CubeFactory.class); private final Map draftCubes = new LinkedHashMap<>(); - public static CubeFactory getInstance() { - return INSTANCE; - } - private CubeFactory() {} public DraftCube createDraftCube(String draftCubeName) { diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftController.java b/Mage.Server/src/main/java/mage/server/draft/DraftController.java index b89624fc812..68071b08968 100644 --- a/Mage.Server/src/main/java/mage/server/draft/DraftController.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftController.java @@ -28,12 +28,6 @@ package mage.server.draft; -import java.io.File; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import mage.MageException; import mage.game.draft.Draft; import mage.game.draft.DraftPlayer; @@ -48,6 +42,13 @@ import mage.server.util.ThreadExecutor; import mage.view.DraftPickView; import org.apache.log4j.Logger; +import java.io.File; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + /** * * @author BetaSteward_at_googlemail.com @@ -152,7 +153,7 @@ public class DraftController { private synchronized void checkStart() { if (!draft.isStarted() && allJoined()) { draft.setStarted(); - ThreadExecutor.getInstance().getCallExecutor().execute(this::startDraft); + ThreadExecutor.instance.getCallExecutor().execute(this::startDraft); } } diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java index 9b25134c4b6..3992af7ca25 100644 --- a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java +++ b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java @@ -28,16 +28,9 @@ package mage.server.draft; -import java.rmi.RemoteException; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - import mage.game.draft.Draft; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.server.User; import mage.server.UserManager; import mage.server.util.ThreadExecutor; @@ -46,6 +39,14 @@ import mage.view.DraftPickView; import mage.view.DraftView; import org.apache.log4j.Logger; +import java.rmi.RemoteException; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -60,7 +61,7 @@ public class DraftSession { protected UUID markedCard; private ScheduledFuture futureTimeout; - protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor(); + protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.instance.getTimeoutExecutor(); public DraftSession(Draft draft, UUID userId, UUID playerId) { this.userId = userId; @@ -75,7 +76,7 @@ public class DraftSession { if (user.isPresent()) { if (futureTimeout != null && !futureTimeout.isDone()) { int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS); - user.get().fireCallback(new ClientCallback("draftInit", draft.getId(), new DraftClientMessage(getDraftPickView(remaining)))); + user.get().fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_INIT, draft.getId(), new DraftClientMessage(getDraftPickView(remaining)))); } return true; } @@ -88,7 +89,7 @@ public class DraftSession { UserManager.instance .getUser(userId). ifPresent(user -> user.fireCallback( - new ClientCallback("draftUpdate", draft.getId(), getDraftView()))); + new ClientCallback(ClientCallbackMethod.DRAFT_UPDATE, draft.getId(), getDraftView()))); } } @@ -98,7 +99,7 @@ public class DraftSession { if (!killed) { UserManager.instance .getUser(userId) - .ifPresent(user -> user.fireCallback(new ClientCallback("draftInform", draft.getId(), new DraftClientMessage(getDraftView(), message)))); + .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_INFORM, draft.getId(), new DraftClientMessage(getDraftView(), message)))); } } @@ -107,7 +108,7 @@ public class DraftSession { if (!killed) { UserManager.instance .getUser(userId) - .ifPresent(user -> user.fireCallback(new ClientCallback("draftOver", draft.getId()))); + .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_OVER, draft.getId()))); } } @@ -117,7 +118,7 @@ public class DraftSession { setupTimeout(timeout); UserManager.instance .getUser(userId) - .ifPresent(user -> user.fireCallback(new ClientCallback("draftPick", draft.getId(), new DraftClientMessage(getDraftPickView(timeout))))); + .ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_PICK, draft.getId(), new DraftClientMessage(getDraftPickView(timeout))))); } } diff --git a/Mage.Server/src/main/java/mage/server/game/DeckValidatorFactory.java b/Mage.Server/src/main/java/mage/server/game/DeckValidatorFactory.java index 168c025fb9d..ad3fbc5e307 100644 --- a/Mage.Server/src/main/java/mage/server/game/DeckValidatorFactory.java +++ b/Mage.Server/src/main/java/mage/server/game/DeckValidatorFactory.java @@ -28,27 +28,26 @@ package mage.server.game; +import mage.cards.decks.DeckValidator; +import org.apache.log4j.Logger; + import java.lang.reflect.Constructor; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import mage.cards.decks.DeckValidator; -import org.apache.log4j.Logger; /** * * @author BetaSteward_at_googlemail.com */ -public class DeckValidatorFactory { +public enum DeckValidatorFactory { - private static final DeckValidatorFactory INSTANCE = new DeckValidatorFactory(); + instance; private static final Logger logger = Logger.getLogger(DeckValidatorFactory.class); private final Map deckTypes = new LinkedHashMap<>(); - public static DeckValidatorFactory getInstance() { - return INSTANCE; - } + private DeckValidatorFactory() {} diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 4ed4720c7fc..5c1e38ba58b 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -27,23 +27,6 @@ */ package mage.server.game; -import java.io.BufferedOutputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.zip.GZIPOutputStream; import mage.MageException; import mage.abilities.Ability; import mage.cards.Card; @@ -66,37 +49,35 @@ import mage.game.events.TableEvent; import mage.game.permanent.Permanent; import mage.interfaces.Action; import mage.players.Player; -import mage.server.ChatManager; -import mage.server.Main; -import mage.server.TableManager; -import mage.server.User; -import mage.server.UserManager; +import mage.server.*; import mage.server.util.ConfigSettings; import mage.server.util.Splitter; import mage.server.util.SystemUtil; import mage.server.util.ThreadExecutor; import mage.utils.timer.PriorityTimer; -import mage.view.AbilityPickerView; -import mage.view.CardsView; -import mage.view.ChatMessage; +import mage.view.*; import mage.view.ChatMessage.MessageColor; import mage.view.ChatMessage.MessageType; -import mage.view.GameView; -import mage.view.PermanentView; import org.apache.log4j.Logger; +import java.io.*; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.*; +import java.util.zip.GZIPOutputStream; + /** * @author BetaSteward_at_googlemail.com */ public class GameController implements GameCallback { - private static final ExecutorService gameExecutor = ThreadExecutor.getInstance().getGameExecutor(); + private static final ExecutorService gameExecutor = ThreadExecutor.instance.getGameExecutor(); private static final Logger logger = Logger.getLogger(GameController.class); protected final ScheduledExecutorService joinWaitingExecutor = Executors.newSingleThreadScheduledExecutor(); private ScheduledFuture futureTimeout; - protected static final ScheduledExecutorService timeoutIdleExecutor = ThreadExecutor.getInstance().getTimeoutIdleExecutor(); + protected static final ScheduledExecutorService timeoutIdleExecutor = ThreadExecutor.instance.getTimeoutIdleExecutor(); private final ConcurrentHashMap gameSessions = new ConcurrentHashMap<>(); private final ConcurrentHashMap watchers = new ConcurrentHashMap<>(); @@ -388,7 +369,7 @@ public class GameController implements GameCallback { private void checkStart() { if (allJoined()) { joinWaitingExecutor.shutdownNow(); - ThreadExecutor.getInstance().getCallExecutor().execute(this::startGame); + ThreadExecutor.instance.getCallExecutor().execute(this::startGame); } } diff --git a/Mage.Server/src/main/java/mage/server/game/GameFactory.java b/Mage.Server/src/main/java/mage/server/game/GameFactory.java index f31f3ee7cdd..f19f67217aa 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameFactory.java +++ b/Mage.Server/src/main/java/mage/server/game/GameFactory.java @@ -28,24 +28,25 @@ package mage.server.game; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import mage.game.match.Match; import mage.game.match.MatchOptions; import mage.game.match.MatchType; import mage.view.GameTypeView; import org.apache.log4j.Logger; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * * @author BetaSteward_at_googlemail.com */ -public class GameFactory { +public enum GameFactory { - private static final GameFactory INSTANCE = new GameFactory(); + instance; private static final Logger logger = Logger.getLogger(GameFactory.class); private final Map> games = new HashMap<>(); @@ -53,9 +54,6 @@ public class GameFactory { private final List gameTypeViews = new ArrayList<>(); - public static GameFactory getInstance() { - return INSTANCE; - } private GameFactory() {} diff --git a/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java b/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java index f3f1146967c..22740037396 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java +++ b/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java @@ -27,10 +27,6 @@ */ package mage.server.game; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ExecutorService; import mage.cards.Cards; import mage.choices.Choice; import mage.constants.ManaType; @@ -38,6 +34,7 @@ import mage.constants.PlayerAction; import mage.game.Game; import mage.game.Table; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.players.Player; import mage.server.User; import mage.server.UserManager; @@ -45,6 +42,11 @@ import mage.server.util.ThreadExecutor; import mage.view.*; import org.apache.log4j.Logger; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; + /** * @author BetaSteward_at_googlemail.com */ @@ -54,7 +56,7 @@ public class GameSessionPlayer extends GameSessionWatcher { private final UUID playerId; - private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); + private static final ExecutorService callExecutor = ThreadExecutor.instance.getCallExecutor(); public GameSessionPlayer(Game game, UUID userId, UUID playerId) { super(userId, game, true); @@ -68,7 +70,7 @@ public class GameSessionPlayer extends GameSessionWatcher { public void ask(final String question, final Map options) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameAsk", game.getId(), new GameClientMessage(getGameView(), question, options))) + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_TARGET, game.getId(), new GameClientMessage(getGameView(), question, options))) ); } } @@ -76,7 +78,7 @@ public class GameSessionPlayer extends GameSessionWatcher { public void target(final String question, final CardsView cardView, final Set targets, final boolean required, final Map options) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user -> { - user.fireCallback(new ClientCallback("gameTarget", game.getId(), new GameClientMessage(getGameView(), question, cardView, targets, required, options))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_TARGET, game.getId(), new GameClientMessage(getGameView(), question, cardView, targets, required, options))); }); } @@ -84,14 +86,14 @@ public class GameSessionPlayer extends GameSessionWatcher { public void select(final String message, final Map options) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameSelect", game.getId(), new GameClientMessage(getGameView(), message, options)))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_SELECT, game.getId(), new GameClientMessage(getGameView(), message, options)))); } } public void chooseAbility(final AbilityPickerView abilities) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user - -> user.fireCallback(new ClientCallback("gameChooseAbility", game.getId(), abilities))); + -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_ABILITY, game.getId(), abilities))); } } @@ -99,7 +101,7 @@ public class GameSessionPlayer extends GameSessionWatcher { public void choosePile(final String message, final CardsView pile1, final CardsView pile2) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user - -> user.fireCallback(new ClientCallback("gameChoosePile", game.getId(), new GameClientMessage(message, pile1, pile2)))); + -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_PILE, game.getId(), new GameClientMessage(message, pile1, pile2)))); } } @@ -107,7 +109,7 @@ public class GameSessionPlayer extends GameSessionWatcher { public void chooseChoice(final Choice choice) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user - -> user.fireCallback(new ClientCallback("gameChooseChoice", game.getId(), new GameClientMessage(choice)))); + -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_CHOICE, game.getId(), new GameClientMessage(choice)))); } } @@ -115,14 +117,14 @@ public class GameSessionPlayer extends GameSessionWatcher { public void playMana(final String message, final Map options) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user - -> user.fireCallback(new ClientCallback("gamePlayMana", game.getId(), new GameClientMessage(getGameView(), message, options)))); + -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_PLAY_MANA, game.getId(), new GameClientMessage(getGameView(), message, options)))); } } public void playXMana(final String message) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user - -> user.fireCallback(new ClientCallback("gamePlayXMana", game.getId(), new GameClientMessage(getGameView(), message)))); + -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_PLAY_XMANA, game.getId(), new GameClientMessage(getGameView(), message)))); } } @@ -130,14 +132,14 @@ public class GameSessionPlayer extends GameSessionWatcher { public void getAmount(final String message, final int min, final int max) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user -> { - user.fireCallback(new ClientCallback("gameSelectAmount", game.getId(), new GameClientMessage(message, min, max))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_GET_AMOUNT, game.getId(), new GameClientMessage(message, min, max))); }); } } public void endGameInfo(Table table) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("endGameInfo", game.getId(), getGameEndView(playerId, table)))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.END_GAME_INFO, game.getId(), getGameEndView(playerId, table)))); } } @@ -164,7 +166,7 @@ public class GameSessionPlayer extends GameSessionWatcher { userRequestMessage.setGameId(game.getId()); userRequestMessage.setButton1("Accept", PlayerAction.ADD_PERMISSION_TO_ROLLBACK_TURN); userRequestMessage.setButton2("Deny", PlayerAction.DENY_PERMISSON_TO_ROLLBACK_TURN); - requestedUser.get().fireCallback(new ClientCallback("userRequestDialog", game.getId(), userRequestMessage)); + requestedUser.get().fireCallback(new ClientCallback(ClientCallbackMethod.USER_REQUEST_DIALOG, game.getId(), userRequestMessage)); } } } @@ -182,7 +184,7 @@ public class GameSessionPlayer extends GameSessionWatcher { userRequestMessage.setGameId(game.getId()); userRequestMessage.setButton1("Accept", PlayerAction.ADD_PERMISSION_TO_SEE_HAND_CARDS); userRequestMessage.setButton2("Reject", null); - user.get().fireCallback(new ClientCallback("userRequestDialog", game.getId(), userRequestMessage)); + user.get().fireCallback(new ClientCallback(ClientCallbackMethod.USER_REQUEST_DIALOG, game.getId(), userRequestMessage)); } } } diff --git a/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java b/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java index 59c77189297..f9eabe88575 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java +++ b/Mage.Server/src/main/java/mage/server/game/GameSessionWatcher.java @@ -28,14 +28,10 @@ package mage.server.game; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - import mage.game.Game; import mage.game.Table; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.players.Player; import mage.server.User; import mage.server.UserManager; @@ -45,6 +41,11 @@ import mage.view.GameView; import mage.view.SimpleCardsView; import org.apache.log4j.Logger; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + /** * @author BetaSteward_at_googlemail.com */ @@ -67,7 +68,7 @@ public class GameSessionWatcher { if (!killed) { Optional user = UserManager.instance.getUser(userId); if (user.isPresent()) { - user.get().fireCallback(new ClientCallback("gameInit", game.getId(), getGameView())); + user.get().fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INIT, game.getId(), getGameView())); return true; } } @@ -76,21 +77,21 @@ public class GameSessionWatcher { public void update() { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameUpdate", game.getId(), getGameView()))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_UPDATE, game.getId(), getGameView()))); } } public void inform(final String message) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameInform", game.getId(), new GameClientMessage(getGameView(), message)))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM, game.getId(), new GameClientMessage(getGameView(), message)))); } } public void informPersonal(final String message) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameInformPersonal", game.getId(), new GameClientMessage(getGameView(), message)))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM_PERSONAL, game.getId(), new GameClientMessage(getGameView(), message)))); } } @@ -99,7 +100,7 @@ public class GameSessionWatcher { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user -> { user.removeGameWatchInfo(game.getId()); - user.fireCallback(new ClientCallback("gameOver", game.getId(), message)); + user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_OVER, game.getId(), message)); }); } } @@ -113,7 +114,7 @@ public class GameSessionWatcher { public void gameError(final String message) { if (!killed) { - UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback("gameError", game.getId(), message))); + UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_ERROR, game.getId(), message))); } } diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java index 8e62b5dcc9f..e01d8fec850 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoom.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoom.java @@ -28,19 +28,21 @@ package mage.server.game; -import java.util.List; -import java.util.Optional; -import java.util.UUID; import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.server.Room; import mage.view.MatchView; import mage.view.RoomUsersView; import mage.view.TableView; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -50,8 +52,8 @@ public interface GamesRoom extends Room { List getTables(); List getFinished(); List getRoomUsersInfo(); - boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException; - boolean joinTournamentTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws GameException; + boolean joinTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException; + boolean joinTournamentTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException; TableView createTable(UUID userId, MatchOptions options); TableView createTournamentTable(UUID userId, TournamentOptions options); void removeTable(UUID userId, UUID tableId); diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java index e9b6bc74d2d..762f33374de 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java @@ -27,13 +27,6 @@ */ package mage.server.game; -import java.io.Serializable; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - import mage.MageException; import mage.cards.decks.DeckCardLists; import mage.constants.TableState; @@ -41,6 +34,7 @@ import mage.game.GameException; import mage.game.Table; import mage.game.match.MatchOptions; import mage.game.tournament.TournamentOptions; +import mage.players.PlayerType; import mage.server.RoomImpl; import mage.server.TableManager; import mage.server.User; @@ -54,6 +48,13 @@ import mage.view.TableView; import mage.view.UsersView; import org.apache.log4j.Logger; +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + /** * @author BetaSteward_at_googlemail.com */ @@ -133,7 +134,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { List roomUserInfo = new ArrayList<>(); roomUserInfo.add(new RoomUsersView(users, GameManager.instance.getNumberActiveGames(), - ThreadExecutor.getInstance().getActiveThreads(ThreadExecutor.getInstance().getGameExecutor()), + ThreadExecutor.instance.getActiveThreads(ThreadExecutor.instance.getGameExecutor()), ConfigSettings.instance.getMaxGameThreads() )); roomUsersView = roomUserInfo; @@ -145,7 +146,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } @Override - public boolean joinTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws MageException { + public boolean joinTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException { if (tables.containsKey(tableId)) { return TableManager.instance.joinTable(userId, tableId, name, playerType, skill, deckList, password); } else { @@ -161,7 +162,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } @Override - public boolean joinTournamentTable(UUID userId, UUID tableId, String name, String playerType, int skill, DeckCardLists deckList, String password) throws GameException { + public boolean joinTournamentTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException { if (tables.containsKey(tableId)) { return TableManager.instance.joinTournament(userId, tableId, name, playerType, skill, deckList, password); } else { 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 7b43c65ce52..51a2edd0da9 100644 --- a/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java +++ b/Mage.Server/src/main/java/mage/server/game/PlayerFactory.java @@ -30,32 +30,26 @@ package mage.server.game; import mage.constants.RangeOfInfluence; import mage.players.Player; +import mage.players.PlayerType; import org.apache.log4j.Logger; import java.lang.reflect.Constructor; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.EnumMap; import java.util.Optional; import java.util.Set; /** - * * @author BetaSteward_at_googlemail.com */ -public class PlayerFactory { +public enum PlayerFactory { - private static final PlayerFactory INSTANCE = new PlayerFactory(); + instance; private static final Logger logger = Logger.getLogger(PlayerFactory.class); - private final Map playerTypes = new LinkedHashMap<>(); + private final EnumMap playerTypes = new EnumMap<>(PlayerType.class); - public static PlayerFactory getInstance() { - return INSTANCE; - } - private PlayerFactory() {} - - public Optional createPlayer(String playerType, String name, RangeOfInfluence range, int skill) { + public Optional createPlayer(PlayerType playerType, String name, RangeOfInfluence range, int skill) { try { Class playerTypeClass = playerTypes.get(playerType); if (playerTypeClass != null) { @@ -63,8 +57,7 @@ public class PlayerFactory { Player player = (Player) con.newInstance(name, range, skill); logger.trace("Player created: " + name + " - " + player.getId()); return Optional.of(player); - } - else { + } else { logger.fatal("Unknown player type: " + playerType); } } catch (Exception ex) { @@ -73,13 +66,16 @@ public class PlayerFactory { return Optional.empty(); } - public Set getPlayerTypes() { + public Set getPlayerTypes() { return playerTypes.keySet(); } public void addPlayerType(String name, Class playerType) { - if (playerType != null) { - this.playerTypes.put(name, playerType); + PlayerType type = PlayerType.getByDescription(name); + if (type != null) { + if (playerType != null) { + this.playerTypes.put(type, playerType); + } } } diff --git a/Mage.Server/src/main/java/mage/server/game/ReplaySession.java b/Mage.Server/src/main/java/mage/server/game/ReplaySession.java index c19d9a1788c..a61bca68943 100644 --- a/Mage.Server/src/main/java/mage/server/game/ReplaySession.java +++ b/Mage.Server/src/main/java/mage/server/game/ReplaySession.java @@ -33,6 +33,7 @@ import java.util.UUID; import mage.game.Game; import mage.game.GameState; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.server.UserManager; import mage.view.GameView; @@ -52,7 +53,7 @@ public class ReplaySession implements GameCallback { public void replay() { replay.start(); UserManager.instance.getUser(userId).ifPresent(user -> - user.fireCallback(new ClientCallback("replayInit", replay.getGame().getId(), new GameView(replay.next(), replay.getGame(), null, null)))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_INIT, replay.getGame().getId(), new GameView(replay.next(), replay.getGame(), null, null)))); } @@ -78,7 +79,7 @@ public class ReplaySession implements GameCallback { @Override public void gameResult(final String result) { UserManager.instance.getUser(userId).ifPresent(user -> - user.fireCallback(new ClientCallback("replayDone", replay.getGame().getId(), result))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_DONE, replay.getGame().getId(), result))); ReplayManager.instance.endReplay(replay.getGame().getId(), userId); } @@ -88,7 +89,7 @@ public class ReplaySession implements GameCallback { gameResult("game ended"); } else { UserManager.instance.getUser(userId).ifPresent(user -> - user.fireCallback(new ClientCallback("replayUpdate", replay.getGame().getId(), new GameView(state, game, null, null)))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_UPDATE, replay.getGame().getId(), new GameView(state, game, null, null)))); } } diff --git a/Mage.Server/src/main/java/mage/server/record/TableRecorderImpl.java b/Mage.Server/src/main/java/mage/server/record/TableRecorderImpl.java index 119ea846a8f..cfcc360ed34 100644 --- a/Mage.Server/src/main/java/mage/server/record/TableRecorderImpl.java +++ b/Mage.Server/src/main/java/mage/server/record/TableRecorderImpl.java @@ -5,13 +5,9 @@ import mage.game.Table.TableRecorder; import mage.game.result.ResultProtos.TableProto; import mage.server.UserManager; -public class TableRecorderImpl implements TableRecorder { +public enum TableRecorderImpl implements TableRecorder { - private final static TableRecorderImpl INSTANCE = new TableRecorderImpl(); - - public static TableRecorderImpl getInstance() { - return INSTANCE; - } + instance; @Override public void record(Table table) { diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java index d8ec2b52baf..2668e71ea03 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentController.java @@ -37,17 +37,19 @@ import mage.game.draft.Draft; import mage.game.events.Listener; import mage.game.events.PlayerQueryEvent; import mage.game.events.TableEvent; -import mage.game.match.Match; import mage.game.match.MatchOptions; import mage.game.result.ResultProtos.TourneyQuitStatus; import mage.game.tournament.MultiplayerRound; import mage.game.tournament.Tournament; import mage.game.tournament.TournamentPairing; import mage.game.tournament.TournamentPlayer; -import mage.server.*; +import mage.players.PlayerType; +import mage.server.ChatManager; +import mage.server.TableManager; +import mage.server.User; +import mage.server.UserManager; import mage.server.draft.DraftController; import mage.server.draft.DraftManager; -import mage.server.draft.DraftSession; import mage.server.game.GamesRoomManager; import mage.server.util.ThreadExecutor; import mage.view.ChatMessage.MessageColor; @@ -198,7 +200,7 @@ public class TournamentController { private void checkStart() { if (!started && allJoined()) { - ThreadExecutor.getInstance().getCallExecutor().execute(this::startTournament); + ThreadExecutor.instance.getCallExecutor().execute(this::startTournament); } } @@ -434,7 +436,7 @@ public class TournamentController { if (user.isPresent()) { replacePlayerName = "Draftbot (" + user.get().getName() + ')'; } - tableController.replaceDraftPlayer(leavingPlayer.getPlayer(), replacePlayerName, "Computer - draftbot", 5); + tableController.replaceDraftPlayer(leavingPlayer.getPlayer(), replacePlayerName, PlayerType.COMPUTER_DRAFT_BOT, 5); if (user.isPresent()) { user.get().removeDraft(leavingPlayer.getPlayer().getId()); user.get().removeTable(leavingPlayer.getPlayer().getId()); diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java index d6c0d1b554c..33683f454f5 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentFactory.java @@ -28,12 +28,6 @@ package mage.server.tournament; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; import mage.cards.Sets; import mage.game.draft.DraftCube; import mage.game.tournament.Tournament; @@ -43,23 +37,22 @@ import mage.server.draft.CubeFactory; import mage.view.TournamentTypeView; import org.apache.log4j.Logger; +import java.lang.reflect.Constructor; +import java.util.*; + /** * * @author BetaSteward_at_googlemail.com */ -public class TournamentFactory { - private static final TournamentFactory INSTANCE = new TournamentFactory(); +public enum TournamentFactory { + instance; private static final Logger logger = Logger.getLogger(TournamentFactory.class); private final Map> tournaments = new HashMap<>(); private final Map tournamentTypes = new HashMap<>(); private final List tournamentTypeViews = new ArrayList<>(); - public static TournamentFactory getInstance() { - return INSTANCE; - } - private TournamentFactory() {} public Tournament createTournament(String tournamentType, TournamentOptions options) { @@ -81,9 +74,9 @@ public class TournamentFactory { DraftCube draftCube; if (tournament.getOptions().getLimitedOptions().getCubeFromDeck() != null) { - draftCube = CubeFactory.getInstance().createDeckDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName(), tournament.getOptions().getLimitedOptions().getCubeFromDeck()); + draftCube = CubeFactory.instance.createDeckDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName(), tournament.getOptions().getLimitedOptions().getCubeFromDeck()); } else { - draftCube = CubeFactory.getInstance().createDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName()); + draftCube = CubeFactory.instance.createDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName()); } tournament.getOptions().getLimitedOptions().setDraftCube(draftCube); tournament.setBoosterInfo(tournament.getOptions().getLimitedOptions().getDraftCubeName()); diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index 89eda7df685..446b3fe6883 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -31,6 +31,7 @@ package mage.server.tournament; import mage.cards.decks.Deck; import mage.game.tournament.Tournament; import mage.interfaces.callback.ClientCallback; +import mage.interfaces.callback.ClientCallbackMethod; import mage.server.User; import mage.server.UserManager; import mage.server.util.ThreadExecutor; @@ -56,7 +57,7 @@ public class TournamentSession { protected boolean killed = false; private ScheduledFuture futureTimeout; - protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor(); + protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.instance.getTimeoutExecutor(); public TournamentSession(Tournament tournament, UUID userId, UUID tableId, UUID playerId) { this.userId = userId; @@ -69,7 +70,7 @@ public class TournamentSession { if (!killed) { Optional user = UserManager.instance.getUser(userId); if (user.isPresent()) { - user.get().fireCallback(new ClientCallback("tournamentInit", tournament.getId(), getTournamentView())); + user.get().fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_INIT, tournament.getId(), getTournamentView())); return true; } } @@ -79,7 +80,7 @@ public class TournamentSession { public void update() { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user -> - user.fireCallback(new ClientCallback("tournamentUpdate", tournament.getId(), getTournamentView()))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_UPDATE, tournament.getId(), getTournamentView()))); } } @@ -87,7 +88,7 @@ public class TournamentSession { public void gameOver(final String message) { if (!killed) { UserManager.instance.getUser(userId).ifPresent(user -> - user.fireCallback(new ClientCallback("tournamentOver", tournament.getId(), message))); + user.fireCallback(new ClientCallback(ClientCallbackMethod.TOURNAMENT_OVER, tournament.getId(), message))); } } diff --git a/Mage.Server/src/main/java/mage/server/util/ThreadExecutor.java b/Mage.Server/src/main/java/mage/server/util/ThreadExecutor.java index 3517add4550..586e759faac 100644 --- a/Mage.Server/src/main/java/mage/server/util/ThreadExecutor.java +++ b/Mage.Server/src/main/java/mage/server/util/ThreadExecutor.java @@ -38,8 +38,8 @@ import java.util.concurrent.TimeUnit; * * @author BetaSteward_at_googlemail.com */ -public class ThreadExecutor { - +public enum ThreadExecutor { +instance; private static final ExecutorService callExecutor = Executors.newCachedThreadPool(); private static final ExecutorService userExecutor = Executors.newCachedThreadPool(); private static final ExecutorService gameExecutor = Executors.newFixedThreadPool(ConfigSettings.instance.getMaxGameThreads()); @@ -74,14 +74,6 @@ public class ThreadExecutor { ((ThreadPoolExecutor) timeoutIdleExecutor).setThreadFactory(new XMageThreadFactory("TIMEOUT_IDLE")); } - private static final ThreadExecutor INSTANCE = new ThreadExecutor(); - - public static ThreadExecutor getInstance() { - return INSTANCE; - } - - private ThreadExecutor() { - } public int getActiveThreads(ExecutorService executerService) { if (executerService instanceof ThreadPoolExecutor) { diff --git a/Mage.Sets/src/mage/cards/a/Abeyance.java b/Mage.Sets/src/mage/cards/a/Abeyance.java index 2ca6d881a13..a2a4402eb19 100644 --- a/Mage.Sets/src/mage/cards/a/Abeyance.java +++ b/Mage.Sets/src/mage/cards/a/Abeyance.java @@ -41,6 +41,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.target.TargetPlayer; +import java.util.Optional; import java.util.UUID; /** @@ -110,8 +111,8 @@ class AbeyanceEffect extends ContinuousRuleModifyingEffectImpl { } } if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null && !(ability instanceof ActivatedManaAbilityImpl)) { + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/a/AlphaStatus.java b/Mage.Sets/src/mage/cards/a/AlphaStatus.java index 695df00850f..673ca8768cb 100644 --- a/Mage.Sets/src/mage/cards/a/AlphaStatus.java +++ b/Mage.Sets/src/mage/cards/a/AlphaStatus.java @@ -45,7 +45,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; import java.util.UUID; @@ -92,7 +91,7 @@ class AlphaStatusDynamicValue implements DynamicValue { if (enchanted != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), game)) { if (!permanent.getId().equals(enchanted.getId())) { - if (CardUtil.shareSubtypes(enchanted, permanent, game)) { + if (enchanted.shareSubtypes(permanent, game)) { xValue += 2; } } diff --git a/Mage.Sets/src/mage/cards/a/AnglerDrake.java b/Mage.Sets/src/mage/cards/a/AnglerDrake.java new file mode 100644 index 00000000000..98b9ca49eee --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnglerDrake.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class AnglerDrake extends CardImpl { + + public AnglerDrake(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); + + this.subtype.add("Drake"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Angler Drake enters the battlefield, you may return target creature to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public AnglerDrake(final AnglerDrake card) { + super(card); + } + + @Override + public AnglerDrake copy() { + return new AnglerDrake(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AnointerPriest.java b/Mage.Sets/src/mage/cards/a/AnointerPriest.java new file mode 100644 index 00000000000..dbcbe3a8664 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AnointerPriest.java @@ -0,0 +1,78 @@ +/* + * 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.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.EmbalmAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; + +/** + * + * @author LevelX2 + */ +public class AnointerPriest extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("a creature token"); + + static { + filter.add(new TokenPredicate()); + } + + public AnointerPriest(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever a creature token enters the battlefield under your control, you gain 1 life. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter)); + + // Embalm {3}{W} + this.addAbility(new EmbalmAbility(new ManaCostsImpl("{3}{W}"), this)); + } + + public AnointerPriest(final AnointerPriest card) { + super(card); + } + + @Override + public AnointerPriest copy() { + return new AnointerPriest(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/ArchfiendOfIfnir.java b/Mage.Sets/src/mage/cards/a/ArchfiendOfIfnir.java new file mode 100644 index 00000000000..9aa1e16bee3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArchfiendOfIfnir.java @@ -0,0 +1,114 @@ +/* + * 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.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; + +/** + * + * @author fireshoes + */ +public class ArchfiendOfIfnir extends CardImpl { + + public ArchfiendOfIfnir(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add("Demon"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever you cycle or discard another card, put a -1/-1 counter on each creature your opponents control. + this.addAbility(new ArchfiendOfIfnirTriggeredAbility(new AddCountersAllEffect(CounterType.M1M1.createInstance(1), + new FilterOpponentsCreaturePermanent("creature your opponents control")))); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + } + + public ArchfiendOfIfnir(final ArchfiendOfIfnir card) { + super(card); + } + + @Override + public ArchfiendOfIfnir copy() { + return new ArchfiendOfIfnir(this); + } +} + +class ArchfiendOfIfnirTriggeredAbility extends TriggeredAbilityImpl { + + ArchfiendOfIfnirTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + ArchfiendOfIfnirTriggeredAbility(final ArchfiendOfIfnirTriggeredAbility ability) { + super(ability); + } + + @Override + public ArchfiendOfIfnirTriggeredAbility copy() { + return new ArchfiendOfIfnirTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DISCARDED_CARD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (getControllerId().equals(event.getPlayerId())) { + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cycle or discard another card, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/a/ArsenalThresher.java b/Mage.Sets/src/mage/cards/a/ArsenalThresher.java index e89e0134840..6d29d90343e 100644 --- a/Mage.Sets/src/mage/cards/a/ArsenalThresher.java +++ b/Mage.Sets/src/mage/cards/a/ArsenalThresher.java @@ -27,6 +27,8 @@ */ package mage.cards.a; +import java.util.ArrayList; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -45,8 +47,6 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInHand; -import java.util.UUID; - /** * * @author jeffwadsworth @@ -54,7 +54,7 @@ import java.util.UUID; public class ArsenalThresher extends CardImpl { public ArsenalThresher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{W/B}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{W/B}{U}"); this.subtype.add("Construct"); this.power = new MageInt(2); @@ -109,7 +109,8 @@ class ArsenalThresherEffect extends OneShotEffect { } if (arsenalThresher != null) { controller.revealCards(arsenalThresher.getIdName(), cards, game); - arsenalThresher.addCounters(CounterType.P1P1.createInstance(cards.size()), source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + arsenalThresher.addCounters(CounterType.P1P1.createInstance(cards.size()), source, game, appliedEffects); } } } diff --git a/Mage.Sets/src/mage/cards/b/BontusMonument.java b/Mage.Sets/src/mage/cards/b/BontusMonument.java new file mode 100644 index 00000000000..668e474597d --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BontusMonument.java @@ -0,0 +1,90 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author fireshoes + */ +public class BontusMonument extends CardImpl { + + private static final FilterCard filter = new FilterCard("Black creature spells"); + private static final FilterSpell filter2 = new FilterSpell("a creature spell"); + + static { + filter.add(Predicates.and(new ColorPredicate(ObjectColor.BLACK), new CardTypePredicate(CardType.CREATURE))); + } + static { + filter2.add(new CardTypePredicate(CardType.CREATURE)); + } + + public BontusMonument(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + addSuperType(SuperType.LEGENDARY); + + // Black creature spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast a creature spell, each opponent loses 1 life and you gain 1 life. + Ability ability = new SpellCastControllerTriggeredAbility(new LoseLifeOpponentsEffect(1), filter2, false); + Effect effect = new GainLifeEffect(1); + effect.setText("and you gain 1 life"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public BontusMonument(final BontusMonument card) { + super(card); + } + + @Override + public BontusMonument copy() { + return new BontusMonument(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java b/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java index bd2b9c499ba..4c7f7aad763 100644 --- a/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java +++ b/Mage.Sets/src/mage/cards/b/BoseijuWhoSheltersAll.java @@ -103,7 +103,7 @@ class BoseijuWhoSheltersAllWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.MANA_PAYED) { + if (event.getType() == GameEvent.EventType.MANA_PAID) { MageObject object = game.getObject(event.getSourceId()); // TODO: Replace identification by name by better method that also works if ability is copied from other land with other name if (object != null && object.getName().equals("Boseiju, Who Shelters All") && event.getFlag()) { diff --git a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java index cf63da767f8..363ace046df 100644 --- a/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java +++ b/Mage.Sets/src/mage/cards/b/BramblewoodParagon.java @@ -27,6 +27,7 @@ */ package mage.cards.b; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -47,8 +48,6 @@ import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import java.util.UUID; - /** * * @author emerald000 @@ -62,7 +61,7 @@ public class BramblewoodParagon extends CardImpl { } public BramblewoodParagon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add("Elf"); this.subtype.add("Warrior"); this.power = new MageInt(2); @@ -120,7 +119,7 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/cards/b/BronzeBombshell.java b/Mage.Sets/src/mage/cards/b/BronzeBombshell.java new file mode 100644 index 00000000000..f061e90ad3f --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BronzeBombshell.java @@ -0,0 +1,141 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +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.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public class BronzeBombshell extends CardImpl { + + public BronzeBombshell(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + + this.subtype.add("Construct"); + this.power = new MageInt(4); + this.toughness = new MageInt(1); + + // When a player other than Bronze Bombshell's owner controls it, that player sacrifices it. If the player does, Bronze Bombshell deals 7 damage to him or her. + this.addAbility(new LoseControlTriggeredAbility(new BronzeBombshellEffect(), false)); + + } + + public BronzeBombshell(final BronzeBombshell card) { + super(card); + } + + @Override + public BronzeBombshell copy() { + return new BronzeBombshell(this); + } +} + +class LoseControlTriggeredAbility extends TriggeredAbilityImpl { + + public LoseControlTriggeredAbility(Effect effect, boolean optional) { + super(Zone.BATTLEFIELD, effect, optional); + } + + public LoseControlTriggeredAbility(final LoseControlTriggeredAbility ability) { + super(ability); + } + + @Override + public LoseControlTriggeredAbility copy() { + return new LoseControlTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return (event.getType() == GameEvent.EventType.LOST_CONTROL); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getSourceId().equals(getSourceId())) { + Permanent sourcePermanent = game.getPermanent(event.getSourceId()); + if (sourcePermanent != null) { + return !(sourcePermanent.getControllerId()).equals(sourcePermanent.getOwnerId()); + } + } + return false; + } + + @Override + public String getRule() { + return "When a player other than {this}'s owner controls it, " + super.getRule(); + } +} + +class BronzeBombshellEffect extends OneShotEffect { + + public BronzeBombshellEffect() { + super(Outcome.Damage); + this.staticText = "that player sacrifices it. If the player does, {this} deals 7 damage to him or her."; + } + + public BronzeBombshellEffect(final BronzeBombshellEffect effect) { + super(effect); + } + + @Override + public BronzeBombshellEffect copy() { + return new BronzeBombshellEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent bronzeBombshell = game.getPermanent(source.getSourceId()); + if (bronzeBombshell != null) { + Player newController = game.getPlayer(bronzeBombshell.getControllerId()); + if (newController != null) { + if (bronzeBombshell.sacrifice(source.getId(), game)) {//sacrificed by the new controlling player + newController.damage(7, source.getSourceId(), game, false, true);//bronze bombshell does 7 damage to the controller + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CanyonSlough.java b/Mage.Sets/src/mage/cards/c/CanyonSlough.java new file mode 100644 index 00000000000..51fb70a2bc6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CanyonSlough.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class CanyonSlough extends CardImpl { + + public CanyonSlough(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Swamp"); + this.subtype.add("Mountain"); + + // ({T}: Add {B} or {R} to your mana pool.) + this.addAbility(new BlackManaAbility()); + this.addAbility(new RedManaAbility()); + + // Canyon Slough enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public CanyonSlough(final CanyonSlough card) { + super(card); + } + + @Override + public CanyonSlough copy() { + return new CanyonSlough(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CartoucheOfSolidarity.java b/Mage.Sets/src/mage/cards/c/CartoucheOfSolidarity.java new file mode 100644 index 00000000000..a6076e767d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CartoucheOfSolidarity.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.permanent.token.WarriorVigilantToken; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class CartoucheOfSolidarity extends CardImpl { + + public CartoucheOfSolidarity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + + this.subtype.add("Aura"); + this.subtype.add("Cartouche"); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Cartouche of Solidarity enters the battlefield, create a 1/1 white Warrior creature token with vigilance. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WarriorVigilantToken()))); + + // Enchanted creature gets +1/+1 and has first strike. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA))); + } + + public CartoucheOfSolidarity(final CartoucheOfSolidarity card) { + super(card); + } + + @Override + public CartoucheOfSolidarity copy() { + return new CartoucheOfSolidarity(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CastOut.java b/Mage.Sets/src/mage/cards/c/CastOut.java new file mode 100644 index 00000000000..8518bc08e4b --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CastOut.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author fireshoes + */ +public class CastOut extends CardImpl { + + private final static FilterNonlandPermanent filter = new FilterNonlandPermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public CastOut(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Cast Out enters the battlefield, exile target nonland permanent an opponent controls until Cast Out leaves the battlefield. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(filter.getMessage())); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + + // Cycling {W} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{W}"))); + + } + + public CastOut(final CastOut card) { + super(card); + } + + @Override + public CastOut copy() { + return new CastOut(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java index d68f9afce64..9e4487669d4 100644 --- a/Mage.Sets/src/mage/cards/c/CavernOfSouls.java +++ b/Mage.Sets/src/mage/cards/c/CavernOfSouls.java @@ -169,7 +169,7 @@ class CavernOfSoulsWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.MANA_PAYED) { + if (event.getType() == GameEvent.EventType.MANA_PAID) { if (event.getData() != null && event.getData().equals(originalId)) { spells.add(event.getTargetId()); } diff --git a/Mage.Sets/src/mage/cards/c/CelestialDawn.java b/Mage.Sets/src/mage/cards/c/CelestialDawn.java index 3ea52e72b1c..0f3367eae8d 100644 --- a/Mage.Sets/src/mage/cards/c/CelestialDawn.java +++ b/Mage.Sets/src/mage/cards/c/CelestialDawn.java @@ -27,6 +27,7 @@ */ package mage.cards.c; +import java.util.UUID; import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; @@ -49,8 +50,6 @@ import mage.players.ManaPoolItem; import mage.players.Player; import mage.sets.Commander; -import java.util.UUID; - /** * * @author LevelX2 @@ -267,8 +266,8 @@ class CelestialDawnSpendColorlessManaEffect extends AsThoughEffectImpl implement @Override public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { - if (mana.getWhite() == 0 && ManaType.COLORLESS != manaType) { - return null; + if (mana.getWhite() == 0) { + return ManaType.COLORLESS; } return manaType; } diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index 99ea80b7a30..a463d8bab70 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -28,6 +28,7 @@ package mage.cards.c; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; @@ -54,6 +55,10 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * @author jeffwadsworth */ @@ -203,11 +208,7 @@ 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); - if (!card.getManaCost().isEmpty()) { - ContinuousEffect effect = new ChandraPyromasterCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - } + game.addEffect(new ChandraPyromasterPlayEffect(new MageObjectReference(card, game)), source); } return true; } @@ -215,15 +216,19 @@ class ChandraPyromasterEffect2 extends OneShotEffect { } } -class ChandraPyromasterCastFromExileEffect extends AsThoughEffectImpl { +class ChandraPyromasterPlayEffect extends AsThoughEffectImpl { - public ChandraPyromasterCastFromExileEffect() { + private final MageObjectReference objectReference; + + public ChandraPyromasterPlayEffect(MageObjectReference objectReference) { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may play the card from exile this turn"; + this.objectReference = objectReference; + staticText = "you may play that card until end of turn"; } - public ChandraPyromasterCastFromExileEffect(final ChandraPyromasterCastFromExileEffect effect) { + public ChandraPyromasterPlayEffect(final ChandraPyromasterPlayEffect effect) { super(effect); + this.objectReference = effect.objectReference; } @Override @@ -232,14 +237,19 @@ class ChandraPyromasterCastFromExileEffect extends AsThoughEffectImpl { } @Override - public ChandraPyromasterCastFromExileEffect copy() { - return new ChandraPyromasterCastFromExileEffect(this); + public ChandraPyromasterPlayEffect copy() { + return new ChandraPyromasterPlayEffect(this); } @Override - public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - if (targetPointer.getTargets(game, source).contains(sourceId)) { - return game.getState().getZone(sourceId) == Zone.EXILED; + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectReference.refersTo(objectId, game) && affectedControllerId.equals(source.getControllerId())) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + return true; + } else { + discard(); + } } return false; } diff --git a/Mage.Sets/src/mage/cards/c/ChannelerInitiate.java b/Mage.Sets/src/mage/cards/c/ChannelerInitiate.java new file mode 100644 index 00000000000..69586e8ada3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChannelerInitiate.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class ChannelerInitiate extends CardImpl { + + public ChannelerInitiate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Human"); + this.subtype.add("Druid"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When Channeler Initiate enters the battlefield, put three -1/-1 counters on target creature you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(3))); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // {T}, Remove a -1/-1 counter from Channeler Initiate: Add one mana of any color to your mana pool. + ability = new AnyColorManaAbility(); + ability.addCost(new RemoveCountersSourceCost(CounterType.M1M1.createInstance(1))); + this.addAbility(ability); + } + + public ChannelerInitiate(final ChannelerInitiate card) { + super(card); + } + + @Override + public ChannelerInitiate copy() { + return new ChannelerInitiate(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/Charisma.java b/Mage.Sets/src/mage/cards/c/Charisma.java new file mode 100644 index 00000000000..0181379436b --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/Charisma.java @@ -0,0 +1,82 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToACreatureAttachedTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.SourceOnBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author jeffwadsworth + */ +public class Charisma extends CardImpl { + + private static final String rule = "gain control of the other creature for as long as {this} remains on the battlefield"; + + public Charisma(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}{U}"); + + 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); + + // Whenever enchanted creature deals damage to a creature, gain control of the other creature for as long as Charisma remains on the battlefield. + Condition condition = new SourceOnBattlefieldCondition(); + ConditionalContinuousEffect conditionalEffect = new ConditionalContinuousEffect(new GainControlTargetEffect(Duration.Custom), condition, rule); + this.addAbility(new DealsDamageToACreatureAttachedTriggeredAbility(conditionalEffect, false, "enchanted creature", false, true)); + + } + + public Charisma(final Charisma card) { + super(card); + } + + @Override + public Charisma copy() { + return new Charisma(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChorusOfTheConclave.java b/Mage.Sets/src/mage/cards/c/ChorusOfTheConclave.java index 736bee7b7ee..421996644dd 100644 --- a/Mage.Sets/src/mage/cards/c/ChorusOfTheConclave.java +++ b/Mage.Sets/src/mage/cards/c/ChorusOfTheConclave.java @@ -27,6 +27,9 @@ */ package mage.cards.c; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -45,10 +48,6 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - /** * * @author jeffwadsworth @@ -57,7 +56,7 @@ import java.util.UUID; public class ChorusOfTheConclave extends CardImpl { public ChorusOfTheConclave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add("Dryad"); @@ -198,7 +197,7 @@ class ChorusOfTheConclaveReplacementEffect2 extends ReplacementEffectImpl { String key = event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 1); int xValue = spellX.get(key); if (xValue > 0) { - creature.addCounters(CounterType.P1P1.createInstance(xValue), source, game); + creature.addCounters(CounterType.P1P1.createInstance(xValue), source, game, event.getAppliedEffects()); game.informPlayers(sourceObject.getLogName() + ": " + creature.getLogName() + " enters the battlefield with " + xValue + " +1/+1 counter" + (xValue > 1 ? "s" : "") + " on it"); } spellX.remove(key); diff --git a/Mage.Sets/src/mage/cards/c/Conflagrate.java b/Mage.Sets/src/mage/cards/c/Conflagrate.java index 732dd120e20..b9c825eedf1 100644 --- a/Mage.Sets/src/mage/cards/c/Conflagrate.java +++ b/Mage.Sets/src/mage/cards/c/Conflagrate.java @@ -53,7 +53,7 @@ import java.util.UUID; public class Conflagrate extends CardImpl { public Conflagrate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}"); // Conflagrate deals X damage divided as you choose among any number of target creatures and/or players. DynamicValue xValue = new ConflagrateVariableValue(); @@ -81,12 +81,13 @@ class ConflagrateVariableValue implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { + int xValue = sourceAbility.getManaCostsToPay().getX(); for (Cost cost : sourceAbility.getCosts()) { if (cost instanceof DiscardTargetCost) { - return ((DiscardTargetCost) cost).getCards().size(); + xValue = ((DiscardTargetCost) cost).getCards().size(); } } - return sourceAbility.getManaCostsToPay().getX(); + return xValue; } @Override diff --git a/Mage.Sets/src/mage/cards/c/ConsumingFervor.java b/Mage.Sets/src/mage/cards/c/ConsumingFervor.java new file mode 100644 index 00000000000..4f4dd6dcd64 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConsumingFervor.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author fireshoes + */ +public class ConsumingFervor extends CardImpl { + + public ConsumingFervor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + + 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); + + // Enchanted creature gets +3/+3 and has "At the beginning of your upkeep, put a -1/-1 counter on this creature." + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)); + Ability grantedAbility = new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(1)), TargetController.YOU, false); + Effect effect = new GainAbilityAttachedEffect(grantedAbility, AttachmentType.AURA); + effect.setText("and has \"At the beginning of each upkeep, put a -1/-1 counter on this creature.\""); + ability.addEffect(effect); + this.addAbility(ability); + } + + public ConsumingFervor(final ConsumingFervor card) { + super(card); + } + + @Override + public ConsumingFervor copy() { + return new ConsumingFervor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CrocodileOfTheCrossing.java b/Mage.Sets/src/mage/cards/c/CrocodileOfTheCrossing.java new file mode 100644 index 00000000000..e98f62ac66b --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrocodileOfTheCrossing.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class CrocodileOfTheCrossing extends CardImpl { + + public CrocodileOfTheCrossing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add("Crocodile"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // When Crocodile of the Crossing enters the battlefield, put a -1/-1 counter on target creature you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(1))); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + } + + public CrocodileOfTheCrossing(final CrocodileOfTheCrossing card) { + super(card); + } + + @Override + public CrocodileOfTheCrossing copy() { + return new CrocodileOfTheCrossing(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CursedMinotaur.java b/Mage.Sets/src/mage/cards/c/CursedMinotaur.java new file mode 100644 index 00000000000..1c8ef94494b --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CursedMinotaur.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.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class CursedMinotaur extends CardImpl { + + public CursedMinotaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add("Zombie"); + this.subtype.add("Minotaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Menace + this.addAbility(new MenaceAbility()); + + } + + public CursedMinotaur(final CursedMinotaur card) { + super(card); + } + + @Override + public CursedMinotaur copy() { + return new CursedMinotaur(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DampingMatrix.java b/Mage.Sets/src/mage/cards/d/DampingMatrix.java index a148069ac6b..393114e6338 100644 --- a/Mage.Sets/src/mage/cards/d/DampingMatrix.java +++ b/Mage.Sets/src/mage/cards/d/DampingMatrix.java @@ -46,6 +46,7 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; +import java.util.Optional; import java.util.UUID; /** @@ -108,8 +109,8 @@ class DampingMatrixEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); if (object instanceof Permanent && filter.match((Permanent)object, game)) { - Ability ability = object.getAbilities().get(event.getTargetId()); - if (ability != null && !(ability instanceof ActivatedManaAbilityImpl)) { + Optional ability = object.getAbilities().get(event.getTargetId()); + if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DaringThief.java b/Mage.Sets/src/mage/cards/d/DaringThief.java index 338a024f364..368cae9591b 100644 --- a/Mage.Sets/src/mage/cards/d/DaringThief.java +++ b/Mage.Sets/src/mage/cards/d/DaringThief.java @@ -46,8 +46,8 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; -import mage.util.CardUtil; +import java.util.EnumSet; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -134,9 +134,9 @@ class TargetControlledPermanentSharingOpponentPermanentCardType extends TargetCo return new TargetControlledPermanentSharingOpponentPermanentCardType(this); } - private Set getOpponentPermanentCardTypes(UUID sourceId, UUID sourceControllerId, Game game) { + private EnumSet getOpponentPermanentCardTypes(UUID sourceId, UUID sourceControllerId, Game game) { Player controller = game.getPlayer(sourceControllerId); - Set cardTypes = new HashSet<>(); + EnumSet cardTypes =EnumSet.noneOf(CardType.class); if (controller != null) { for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) { if (controller.hasOpponent(permanent.getControllerId(), game)) { @@ -171,7 +171,7 @@ class DaringThiefSecondTarget extends TargetPermanent { Permanent target1 = game.getPermanent(source.getFirstTarget()); Permanent opponentPermanent = game.getPermanent(id); if (target1 != null && opponentPermanent != null) { - return CardUtil.shareTypes(target1, opponentPermanent); + return target1.shareTypes(opponentPermanent); } } return false; @@ -184,7 +184,7 @@ class DaringThiefSecondTarget extends TargetPermanent { MageObject targetSource = game.getObject(sourceId); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) { if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) { - if (CardUtil.shareTypes(permanent, firstTarget)) { + if (permanent.shareTypes(firstTarget)) { possibleTargets.add(permanent.getId()); } } diff --git a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java index 4e90e35ec38..061dad9b266 100644 --- a/Mage.Sets/src/mage/cards/d/DearlyDeparted.java +++ b/Mage.Sets/src/mage/cards/d/DearlyDeparted.java @@ -27,6 +27,7 @@ */ package mage.cards.d; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -45,15 +46,13 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; -import java.util.UUID; - /** * @author nantuko */ public class DearlyDeparted extends CardImpl { public DearlyDeparted(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); this.subtype.add("Spirit"); this.power = new MageInt(5); @@ -104,7 +103,7 @@ class DearlyDepartedEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { - target.addCounters(CounterType.P1P1.createInstance(), source, game); + target.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/cards/d/DecisionParalysis.java b/Mage.Sets/src/mage/cards/d/DecisionParalysis.java new file mode 100644 index 00000000000..95d4dacecaf --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DecisionParalysis.java @@ -0,0 +1,61 @@ +/* + * 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 java.util.UUID; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class DecisionParalysis extends CardImpl { + + public DecisionParalysis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); + + // Tap up to two target creatures. Those creatures don't untap during their controller's next untap step. + this.getSpellAbility().addEffect(new TapTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures")); + } + + public DecisionParalysis(final DecisionParalysis card) { + super(card); + } + + @Override + public DecisionParalysis copy() { + return new DecisionParalysis(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DescendantsPath.java b/Mage.Sets/src/mage/cards/d/DescendantsPath.java index 7cb0a463b91..3a876bb7cc2 100644 --- a/Mage.Sets/src/mage/cards/d/DescendantsPath.java +++ b/Mage.Sets/src/mage/cards/d/DescendantsPath.java @@ -42,7 +42,6 @@ import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.util.CardUtil; import java.util.UUID; @@ -102,7 +101,7 @@ class DescendantsPathEffect extends OneShotEffect { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); boolean found = false; for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { - if (CardUtil.shareSubtypes(card, permanent, game)) { + if (card.shareSubtypes(permanent, game)) { found = true; break; } diff --git a/Mage.Sets/src/mage/cards/d/Desertion.java b/Mage.Sets/src/mage/cards/d/Desertion.java index e94fca2d5ff..2ad97057f85 100644 --- a/Mage.Sets/src/mage/cards/d/Desertion.java +++ b/Mage.Sets/src/mage/cards/d/Desertion.java @@ -40,8 +40,6 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.TargetSpell; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -90,15 +88,13 @@ class DesertionEffect extends OneShotEffect { if (controller != null) { Spell targetSpell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (targetSpell != null) { - Set cardTypes = new HashSet<>(targetSpell.getCardType()); - if (!cardTypes.isEmpty()) { //targetPointer.getFirst(game, source) - if (cardTypes.contains(CardType.ARTIFACT) || cardTypes.contains(CardType.CREATURE)) { + if (targetSpell.isArtifact() || targetSpell.isCreature()) { return game.getStack().counter(targetSpell.getId(), source.getSourceId(), game, Zone.BATTLEFIELD, false, ZoneDetail.NONE); } else { return game.getStack().counter(targetSpell.getId(), source.getSourceId(), game); } - } + } } return false; diff --git a/Mage.Sets/src/mage/cards/d/Dismantle.java b/Mage.Sets/src/mage/cards/d/Dismantle.java new file mode 100644 index 00000000000..a890154451d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Dismantle.java @@ -0,0 +1,121 @@ +/* + * 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 java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetArtifactPermanent; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author Styxo + */ +public class Dismantle extends CardImpl { + + public Dismantle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); + + // Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control. + this.getSpellAbility().addEffect(new DismantleEffect()); + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); + + } + + public Dismantle(final Dismantle card) { + super(card); + } + + @Override + public Dismantle copy() { + return new Dismantle(this); + } + +} + +class DismantleEffect extends OneShotEffect { + + public DismantleEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target artifact. If that artifact had counters on it, put that many +1/+1 counters or charge counters on an artifact you control"; + + } + + public DismantleEffect(final DismantleEffect effect) { + super(effect); + } + + @Override + public DismantleEffect copy() { + return new DismantleEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (controller != null) { + if (permanent != null) { + int counterCount = 0; + counterCount = permanent.getCounters(game).values().stream().map((counter) -> counter.getCount()).reduce(counterCount, Integer::sum); + permanent.destroy(source.getSourceId(), game, false); + if (counterCount > 0) { + Target target = new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent("an artifact you control"), true); + if (target.canChoose(controller.getId(), game)) { + controller.chooseTarget(Outcome.Benefit, target, source, game); + Permanent artifact = game.getPermanent(target.getFirstTarget()); + Counter counter; + if (controller.chooseUse(Outcome.BoostCreature, "What kind of counters do you want to add?", null, "+1/+1 counters", "Charge counters", source, game)) { + counter = CounterType.P1P1.createInstance(counterCount); + } else { + counter = CounterType.CHARGE.createInstance(counterCount); + } + if (artifact != null) { + artifact.addCounters(counter, source, game); + } + } + } + } + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/cards/d/DjerusResolve.java b/Mage.Sets/src/mage/cards/d/DjerusResolve.java new file mode 100644 index 00000000000..5f2b2a5a5ec --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DjerusResolve.java @@ -0,0 +1,75 @@ +/* + * 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 java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class DjerusResolve extends CardImpl { + + public DjerusResolve(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); + + // Untap target creature. + Effect effect = new UntapTargetEffect(); + effect.setText("Untap target creature"); + this.getSpellAbility().addEffect(effect); + + // Prevent all damage that would be dealt to it this turn. + effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE); + effect.setText("Prevent all damage that would be dealt to it this turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public DjerusResolve(final DjerusResolve card) { + super(card); + } + + @Override + public DjerusResolve copy() { + return new DjerusResolve(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DrakeHaven.java b/Mage.Sets/src/mage/cards/d/DrakeHaven.java new file mode 100644 index 00000000000..7f11f8f272b --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DrakeHaven.java @@ -0,0 +1,100 @@ +/* + * 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 java.util.UUID; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.token.DrakeToken; + +/** + * + * @author fireshoes + */ +public class DrakeHaven extends CardImpl { + + public DrakeHaven(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + // When you cycle or discard a card, you may pay {1}. If you do, create a 2/2 blue Drake creature token with flying. + this.addAbility(new DrakeHavenTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new DrakeToken()), new GenericManaCost(1)))); + } + + public DrakeHaven(final DrakeHaven card) { + super(card); + } + + @Override + public DrakeHaven copy() { + return new DrakeHaven(this); + } +} + +class DrakeHavenTriggeredAbility extends TriggeredAbilityImpl { + + DrakeHavenTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + DrakeHavenTriggeredAbility(final DrakeHavenTriggeredAbility ability) { + super(ability); + } + + @Override + public DrakeHavenTriggeredAbility copy() { + return new DrakeHavenTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DISCARDED_CARD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (getControllerId().equals(event.getPlayerId())) { + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cycle or discard a card, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuneBeetle.java b/Mage.Sets/src/mage/cards/d/DuneBeetle.java new file mode 100644 index 00000000000..dadf12d0dde --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DuneBeetle.java @@ -0,0 +1,58 @@ +/* + * 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 java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class DuneBeetle extends CardImpl { + + public DuneBeetle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Insect"); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + } + + public DuneBeetle(final DuneBeetle card) { + super(card); + } + + @Override + public DuneBeetle copy() { + return new DuneBeetle(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuskFeaster.java b/Mage.Sets/src/mage/cards/d/DuskFeaster.java index 3b876799d13..fbc5bf50a77 100644 --- a/Mage.Sets/src/mage/cards/d/DuskFeaster.java +++ b/Mage.Sets/src/mage/cards/d/DuskFeaster.java @@ -41,7 +41,7 @@ import mage.constants.*; import mage.game.Game; import mage.players.Player; -import java.util.HashSet; +import java.util.EnumSet; import java.util.UUID; /** @@ -106,7 +106,7 @@ class DuskFeasterCostReductionEffect extends CostModificationEffectImpl { boolean hasDelirium = false; Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - HashSet foundCardTypes = new HashSet<>(); + EnumSet foundCardTypes = EnumSet.noneOf(CardType.class); for (Card card : controller.getGraveyard().getCards(game)) { foundCardTypes.addAll(card.getCardType()); } diff --git a/Mage.Sets/src/mage/cards/e/ExemplarOfStrength.java b/Mage.Sets/src/mage/cards/e/ExemplarOfStrength.java new file mode 100644 index 00000000000..2b151896775 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ExemplarOfStrength.java @@ -0,0 +1,76 @@ +/* + * 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.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class ExemplarOfStrength extends CardImpl { + + public ExemplarOfStrength(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Human"); + this.subtype.add("Warrior"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Exemplar of Strength enters the battlefield, put three -1/-1 counters on target creature you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(3))); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // Whenever Exemplar of Strength attacks, remove a -1/-1 counter from it. If you do, you gain 1 life. + this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(new GainLifeEffect(1), new RemoveCountersSourceCost(CounterType.M1M1.createInstance())), false)); + } + + public ExemplarOfStrength(final ExemplarOfStrength card) { + super(card); + } + + @Override + public ExemplarOfStrength copy() { + return new ExemplarOfStrength(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FaithsFetters.java b/Mage.Sets/src/mage/cards/f/FaithsFetters.java index 6e0713642d4..0dda3904ce7 100644 --- a/Mage.Sets/src/mage/cards/f/FaithsFetters.java +++ b/Mage.Sets/src/mage/cards/f/FaithsFetters.java @@ -44,16 +44,16 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; +import java.util.Optional; import java.util.UUID; /** - * * @author LevelX2 */ public class FaithsFetters extends CardImpl { public FaithsFetters(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); this.subtype.add("Aura"); // Enchant permanent @@ -114,12 +114,11 @@ class FaithsFettersEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo().equals(event.getSourceId())) { - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null) { - if (ability.getAbilityType() != AbilityType.MANA) { - return true; - } + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && ability.get().getAbilityType() != AbilityType.MANA) { + return true; } + } return false; } diff --git a/Mage.Sets/src/mage/cards/f/FetidPools.java b/Mage.Sets/src/mage/cards/f/FetidPools.java new file mode 100644 index 00000000000..6e8a7a2a552 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FetidPools.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class FetidPools extends CardImpl { + + public FetidPools(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Island"); + this.subtype.add("Swamp"); + + // ({T}: Add {U} or {B} to your mana pool.) + this.addAbility(new BlueManaAbility()); + this.addAbility(new BlackManaAbility()); + + // Fetid Pools enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public FetidPools(final FetidPools card) { + super(card); + } + + @Override + public FetidPools copy() { + return new FetidPools(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java b/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java new file mode 100644 index 00000000000..4c78d08345b --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlamebladeAdept.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; + +/** + * + * @author fireshoes + */ +public class FlamebladeAdept extends CardImpl { + + public FlamebladeAdept(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.subtype.add("Jackal"); + this.subtype.add("Warrior"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Menace + this.addAbility(new MenaceAbility()); + + // Whenever you cycle or discard a card, Flameblade Adept gets +1/+0 until end of turn. + this.addAbility(new FlamebladeAdeptTriggeredAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn))); + } + + public FlamebladeAdept(final FlamebladeAdept card) { + super(card); + } + + @Override + public FlamebladeAdept copy() { + return new FlamebladeAdept(this); + } +} + +class FlamebladeAdeptTriggeredAbility extends TriggeredAbilityImpl { + + FlamebladeAdeptTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + FlamebladeAdeptTriggeredAbility(final FlamebladeAdeptTriggeredAbility ability) { + super(ability); + } + + @Override + public FlamebladeAdeptTriggeredAbility copy() { + return new FlamebladeAdeptTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DISCARDED_CARD; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (getControllerId().equals(event.getPlayerId())) { + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cycle or discard another card, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GeneratorServant.java b/Mage.Sets/src/mage/cards/g/GeneratorServant.java index 7eec49e3d60..7b602ff5363 100644 --- a/Mage.Sets/src/mage/cards/g/GeneratorServant.java +++ b/Mage.Sets/src/mage/cards/g/GeneratorServant.java @@ -105,7 +105,7 @@ class GeneratorServantWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.MANA_PAYED) { + if (event.getType() == GameEvent.EventType.MANA_PAID) { MageObject target = game.getObject(event.getTargetId()); if (event.getSourceId() != null && event.getSourceId().equals(this.getSourceId()) && target != null && target.isCreature() && event.getFlag()) { diff --git a/Mage.Sets/src/mage/cards/g/GideonMartialParagon.java b/Mage.Sets/src/mage/cards/g/GideonMartialParagon.java new file mode 100644 index 00000000000..57e2989f20f --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GideonMartialParagon.java @@ -0,0 +1,107 @@ +/* + * 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.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventAllDamageToSourceEffect; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.UntapAllEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class GideonMartialParagon extends CardImpl { + + public GideonMartialParagon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{W}"); + + this.subtype.add("Gideon"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); + + // +2: Untap all creatures you control. Those creatures get +1/+1 until end of turn. + LoyaltyAbility ability = new LoyaltyAbility(new UntapAllEffect(new FilterControlledCreaturePermanent()), 2); + Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn); + effect.setText("Those creatures get +1/+1 until end of turn"); + ability.addEffect(effect); + this.addAbility(ability); + + // 0: Until end of turn, Gideon, Martial Paragon, becomes a 5/5 Human Soldier creature with indestructible that's still a planeswalker. + // Prevent all damage that would be dealt to him this turn. + ability = new LoyaltyAbility(new BecomesCreatureSourceEffect(new GideonMartialParagonToken(), "planeswalker", Duration.EndOfTurn), 0); + effect = new PreventAllDamageToSourceEffect(Duration.EndOfTurn); + effect.setText("Prevent all damage that would be dealt to him this turn"); + ability.addEffect(effect); + this.addAbility(ability); + + // -10: Creatures you control get +2/+2 until end of turn. Tap all creatures your opponents control. + ability = new LoyaltyAbility(new BoostControlledEffect(2, 2, Duration.EndOfTurn), -10); + effect = new TapAllEffect(new FilterOpponentsCreaturePermanent()); + effect.setText("Tap all creatures your opponents control"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public GideonMartialParagon(final GideonMartialParagon card) { + super(card); + } + + @Override + public GideonMartialParagon copy() { + return new GideonMartialParagon(this); + } +} + +class GideonMartialParagonToken extends Token { + + public GideonMartialParagonToken() { + super("", "5/5 Human Soldier creature with indestructible"); + cardType.add(CardType.CREATURE); + subtype.add("Human"); + subtype.add("Soldier"); + power = new MageInt(5); + toughness = new MageInt(5); + + addAbility(IndestructibleAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GracefulCat.java b/Mage.Sets/src/mage/cards/g/GracefulCat.java new file mode 100644 index 00000000000..7980497b0da --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GracefulCat.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author fireshoes + */ +public class GracefulCat extends CardImpl { + + public GracefulCat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add("Cat"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Graceful Cat attacks, it gets +1/+1 until end of turn. + Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn"); + this.addAbility(new AttacksTriggeredAbility(effect, false)); + } + + public GracefulCat(final GracefulCat card) { + super(card); + } + + @Override + public GracefulCat copy() { + return new GracefulCat(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HallOfTheBanditLord.java b/Mage.Sets/src/mage/cards/h/HallOfTheBanditLord.java index dfba3d59016..e0baeb9d0b6 100644 --- a/Mage.Sets/src/mage/cards/h/HallOfTheBanditLord.java +++ b/Mage.Sets/src/mage/cards/h/HallOfTheBanditLord.java @@ -110,7 +110,7 @@ class HallOfTheBanditLordWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.MANA_PAYED) { + if (event.getType() == EventType.MANA_PAID) { MageObject target = game.getObject(event.getTargetId()); if (event.getSourceId() != null && event.getSourceId().equals(this.getSourceId()) diff --git a/Mage.Sets/src/mage/cards/h/HandToHand.java b/Mage.Sets/src/mage/cards/h/HandToHand.java index 25470bd8db8..cd1ca19333c 100644 --- a/Mage.Sets/src/mage/cards/h/HandToHand.java +++ b/Mage.Sets/src/mage/cards/h/HandToHand.java @@ -27,7 +27,6 @@ */ package mage.cards.h; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -35,14 +34,13 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TurnPhase; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; +import java.util.Optional; +import java.util.UUID; + /** * * @author fireshoes @@ -106,8 +104,8 @@ class HandToHandEffect extends ContinuousRuleModifyingEffectImpl { } } if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null && !(ability instanceof ActivatedManaAbilityImpl)) { + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/h/HazoretTheFervent.java b/Mage.Sets/src/mage/cards/h/HazoretTheFervent.java new file mode 100644 index 00000000000..9da9b9f9890 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HazoretTheFervent.java @@ -0,0 +1,122 @@ +/* + * 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.h; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author fireshoes + */ +public class HazoretTheFervent extends CardImpl { + + public HazoretTheFervent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("God"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Indestructible + this.addAbility(IndestructibleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Hazoret the Fervent can't attack or block unless you have one or fewer cards in hand. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HazoretTheFerventEffect())); + + // {2}{R}, Discard a card: Hazoret deals 2 damage to each opponent. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamagePlayersEffect(2, TargetController.OPPONENT), new ManaCostsImpl("{2}{R}")); + ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + } + + public HazoretTheFervent(final HazoretTheFervent card) { + super(card); + } + + @Override + public HazoretTheFervent copy() { + return new HazoretTheFervent(this); + } +} + +class HazoretTheFerventEffect extends RestrictionEffect { + + public HazoretTheFerventEffect() { + super(Duration.WhileOnBattlefield); + staticText = "{this} can't attack or block unless you have one or fewer cards in hand"; + } + + public HazoretTheFerventEffect(final HazoretTheFerventEffect effect) { + super(effect); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + return permanent.getId().equals(source.getSourceId()) && controller.getHand().size() > 1; + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public HazoretTheFerventEffect copy() { + return new HazoretTheFerventEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HazoretsMonument.java b/Mage.Sets/src/mage/cards/h/HazoretsMonument.java new file mode 100644 index 00000000000..5ecd04e9569 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HazoretsMonument.java @@ -0,0 +1,85 @@ +/* + * 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.h; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author fireshoes + */ +public class HazoretsMonument extends CardImpl { + + private static final FilterCard filter = new FilterCard("Red creature spells"); + private static final FilterSpell filter2 = new FilterSpell("a creature spell"); + + static { + filter.add(Predicates.and(new ColorPredicate(ObjectColor.RED), new CardTypePredicate(CardType.CREATURE))); + } + static { + filter2.add(new CardTypePredicate(CardType.CREATURE)); + } + + public HazoretsMonument(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + addSuperType(SuperType.LEGENDARY); + + // Red creature spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast a creature spell, you may discard a card. If you do, draw a card. + this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()), filter2, false)); + } + + public HazoretsMonument(final HazoretsMonument card) { + super(card); + } + + @Override + public HazoretsMonument copy() { + return new HazoretsMonument(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HyenaPack.java b/Mage.Sets/src/mage/cards/h/HyenaPack.java new file mode 100644 index 00000000000..91111a56d3c --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HyenaPack.java @@ -0,0 +1,58 @@ +/* + * 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.h; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class HyenaPack extends CardImpl { + + public HyenaPack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add("Hyena"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + } + + public HyenaPack(final HyenaPack card) { + super(card); + } + + @Override + public HyenaPack copy() { + return new HyenaPack(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InOketrasName.java b/Mage.Sets/src/mage/cards/i/InOketrasName.java new file mode 100644 index 00000000000..dc237e7b8c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InOketrasName.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author fireshoes + */ +public class InOketrasName extends CardImpl { + + private static final FilterCreaturePermanent filterZombies = new FilterCreaturePermanent("Zombies"); + private static final FilterCreaturePermanent filterNotZombies = new FilterCreaturePermanent("Other creatures"); + + static { + filterZombies.add(new SubtypePredicate("Zombie")); + filterNotZombies.add(Predicates.not(new SubtypePredicate("Zombie"))); + } + + public InOketrasName(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Zombies you control get +2/+1 until end of turn. Other creatures you control get +1/+1 until end of turn. + getSpellAbility().addEffect(new BoostControlledEffect(2, 1, Duration.EndOfTurn, filterZombies)); + getSpellAbility().addEffect(new BoostControlledEffect(1, 1, Duration.EndOfTurn, filterNotZombies)); + } + + public InOketrasName(final InOketrasName card) { + super(card); + } + + @Override + public InOketrasName copy() { + return new InOketrasName(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InameDeathAspect.java b/Mage.Sets/src/mage/cards/i/InameDeathAspect.java index 02aaecb3baa..3b63f1687fe 100644 --- a/Mage.Sets/src/mage/cards/i/InameDeathAspect.java +++ b/Mage.Sets/src/mage/cards/i/InameDeathAspect.java @@ -39,7 +39,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.common.FilterCreatureCard; +import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.players.Player; @@ -73,7 +73,7 @@ public class InameDeathAspect extends CardImpl { class InameDeathAspectEffect extends SearchEffect { - private static final FilterCreatureCard filter = new FilterCreatureCard(); + private static final FilterCard filter = new FilterCard(); static { filter.add(new SubtypePredicate("Spirit")); diff --git a/Mage.Sets/src/mage/cards/i/IrrigatedFarmland.java b/Mage.Sets/src/mage/cards/i/IrrigatedFarmland.java new file mode 100644 index 00000000000..83afd63f0ab --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IrrigatedFarmland.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.i; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class IrrigatedFarmland extends CardImpl { + + public IrrigatedFarmland(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Plains"); + this.subtype.add("Island"); + + // ({T}: Add {W} or {U} to your mana pool.) + this.addAbility(new WhiteManaAbility()); + this.addAbility(new BlueManaAbility()); + + // Irrigated Farmland enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public IrrigatedFarmland(final IrrigatedFarmland card) { + super(card); + } + + @Override + public IrrigatedFarmland copy() { + return new IrrigatedFarmland(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KefnetsMonument.java b/Mage.Sets/src/mage/cards/k/KefnetsMonument.java new file mode 100644 index 00000000000..2f59203ca9a --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KefnetsMonument.java @@ -0,0 +1,95 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.k; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class KefnetsMonument extends CardImpl { + + private static final FilterCard filter = new FilterCard("Blue creature spells"); + private static final FilterSpell filter2 = new FilterSpell("a creature spell"); + private static final FilterCreaturePermanent filter3 = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(Predicates.and(new ColorPredicate(ObjectColor.BLUE), new CardTypePredicate(CardType.CREATURE))); + } + static { + filter2.add(new CardTypePredicate(CardType.CREATURE)); + } + static { + filter3.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + + public KefnetsMonument(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + addSuperType(SuperType.LEGENDARY); + + // Blue creature spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast a creature spell, target creature an opponent controls doesn't untap during its controller's next untap step. + Ability ability = new SpellCastControllerTriggeredAbility(new DontUntapInControllersNextUntapStepTargetEffect(), filter2, false); + ability.addTarget(new TargetCreaturePermanent(filter3)); + this.addAbility(ability); + } + + public KefnetsMonument(final KefnetsMonument card) { + super(card); + } + + @Override + public KefnetsMonument copy() { + return new KefnetsMonument(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KiraGreatGlassSpinner.java b/Mage.Sets/src/mage/cards/k/KiraGreatGlassSpinner.java index fccfb47523f..1ac7af667b3 100644 --- a/Mage.Sets/src/mage/cards/k/KiraGreatGlassSpinner.java +++ b/Mage.Sets/src/mage/cards/k/KiraGreatGlassSpinner.java @@ -27,6 +27,9 @@ */ package mage.cards.k; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; import mage.abilities.TriggeredAbilityImpl; @@ -46,10 +49,6 @@ import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; import mage.watchers.Watcher; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - /** * * @author LevelX2 @@ -70,8 +69,10 @@ public class KiraGreatGlassSpinner extends CardImpl { // Creatures you control have "Whenever this creature becomes the target of a spell or ability for the first time in a turn, counter that spell or ability." Effect effect = new CounterTargetEffect(); effect.setText("counter that spell or ability"); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new KiraGreatGlassSpinnerAbility(effect), Duration.WhileOnBattlefield, new FilterCreaturePermanent("creatures"))), - new CreatureWasTargetedThisTurnWatcher()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityControlledEffect(new KiraGreatGlassSpinnerAbility(effect), Duration.WhileOnBattlefield, + new FilterCreaturePermanent("creatures"))), + new KiraGreatGlassSpinnerWatcher()); } @@ -110,7 +111,7 @@ class KiraGreatGlassSpinnerAbility extends TriggeredAbilityImpl { if (event.getTargetId().equals(this.getSourceId())) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && permanent.isCreature()) { - CreatureWasTargetedThisTurnWatcher watcher = (CreatureWasTargetedThisTurnWatcher) game.getState().getWatchers().get("CreatureWasTargetedThisTurn"); + KiraGreatGlassSpinnerWatcher watcher = (KiraGreatGlassSpinnerWatcher) game.getState().getWatchers().get(KiraGreatGlassSpinnerWatcher.class.getName()); if (watcher != null && watcher.notMoreThanOnceTargetedThisTurn(permanent, game)) { for (Effect effect : getEffects()) { effect.setTargetPointer(new FixedTarget(event.getSourceId())); @@ -129,15 +130,15 @@ class KiraGreatGlassSpinnerAbility extends TriggeredAbilityImpl { } -class CreatureWasTargetedThisTurnWatcher extends Watcher { +class KiraGreatGlassSpinnerWatcher extends Watcher { private final Map creaturesTargeted = new HashMap<>(); - public CreatureWasTargetedThisTurnWatcher() { - super("CreatureWasTargetedThisTurn", WatcherScope.GAME); + public KiraGreatGlassSpinnerWatcher() { + super(KiraGreatGlassSpinnerWatcher.class.getName(), WatcherScope.GAME); } - public CreatureWasTargetedThisTurnWatcher(final CreatureWasTargetedThisTurnWatcher watcher) { + public KiraGreatGlassSpinnerWatcher(final KiraGreatGlassSpinnerWatcher watcher) { super(watcher); this.creaturesTargeted.putAll(creaturesTargeted); } @@ -146,7 +147,7 @@ class CreatureWasTargetedThisTurnWatcher extends Watcher { public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.TARGETED) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.isCreature()) { + if (permanent != null) { MageObjectReference mor = new MageObjectReference(permanent, game); int amount = 0; if (creaturesTargeted.containsKey(mor)) { @@ -171,7 +172,7 @@ class CreatureWasTargetedThisTurnWatcher extends Watcher { } @Override - public CreatureWasTargetedThisTurnWatcher copy() { - return new CreatureWasTargetedThisTurnWatcher(this); + public KiraGreatGlassSpinnerWatcher copy() { + return new KiraGreatGlassSpinnerWatcher(this); } } diff --git a/Mage.Sets/src/mage/cards/k/KondasBanner.java b/Mage.Sets/src/mage/cards/k/KondasBanner.java index f74e32d7cea..a385a89b22d 100644 --- a/Mage.Sets/src/mage/cards/k/KondasBanner.java +++ b/Mage.Sets/src/mage/cards/k/KondasBanner.java @@ -29,7 +29,6 @@ */ package mage.cards.k; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.AttachableToRestrictedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -46,7 +45,8 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; -import mage.util.CardUtil; + +import java.util.UUID; /** * @@ -111,7 +111,7 @@ class KondasBannerTypeBoostEffect extends BoostAllEffect { Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo()); if (equipedCreature != null) { for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (CardUtil.shareSubtypes(perm, equipedCreature, game)) { + if (perm.shareSubtypes(equipedCreature, game)) { perm.addPower(power.calculate(game, source, this)); perm.addToughness(toughness.calculate(game, source, this)); diff --git a/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java b/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java new file mode 100644 index 00000000000..4a2e53d2967 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LayBareTheHeart.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.target.TargetPlayer; + +/** + * + * @author fireshoes + */ +public class LayBareTheHeart extends CardImpl { + + private static final FilterCard filter = new FilterCard("nonlegendary, nonland card"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + filter.add(Predicates.not(new SupertypePredicate("Legendary"))); + } + + public LayBareTheHeart(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); + + // Target opponent reveals his or her hand. You choose a nonlegendary, nonland card from it. That player discards that card. + this.getSpellAbility().addTarget(new TargetPlayer()); + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); + } + + public LayBareTheHeart(final LayBareTheHeart card) { + super(card); + } + + @Override + public LayBareTheHeart copy() { + return new LayBareTheHeart(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java b/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java new file mode 100644 index 00000000000..a1005ab192d --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LilianaDeathWielder.java @@ -0,0 +1,120 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class LilianaDeathWielder extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with a -1/-1 counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.M1M1)); + } + + public LilianaDeathWielder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{5}{B}{B}"); + + this.subtype.add("Liliana"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); + + // +2: Put a -1/-1 counter on up to one target creature. + LoyaltyAbility ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance(1)), 2); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + + // -3: Destroy target creature with a -1/-1 counter on it. + ability = new LoyaltyAbility(new DestroyTargetEffect(), -3); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + // -10: Return all creature cards from your graveyard to the battlefield. + this.addAbility(new LoyaltyAbility(new LilianaDeathWielderEffect(), -10)); + } + + public LilianaDeathWielder(final LilianaDeathWielder card) { + super(card); + } + + @Override + public LilianaDeathWielder copy() { + return new LilianaDeathWielder(this); + } +} + +class LilianaDeathWielderEffect extends OneShotEffect { + + public LilianaDeathWielderEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Return all creature cards from your graveyard to the battlefield"; + } + + public LilianaDeathWielderEffect(final LilianaDeathWielderEffect effect) { + super(effect); + } + + @Override + public LilianaDeathWielderEffect copy() { + return new LilianaDeathWielderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null){ + for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) { + card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId()); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/l/LimitsOfSolidarity.java b/Mage.Sets/src/mage/cards/l/LimitsOfSolidarity.java new file mode 100644 index 00000000000..f5a4aa8f27a --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LimitsOfSolidarity.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class LimitsOfSolidarity extends CardImpl { + + public LimitsOfSolidarity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); + + // Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); + Effect effect = new UntapTargetEffect(); + effect.setText("Untap it"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); + effect.setText("It gains haste until end of turn"); + this.getSpellAbility().addEffect(effect); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public LimitsOfSolidarity(final LimitsOfSolidarity card) { + super(card); + } + + @Override + public LimitsOfSolidarity copy() { + return new LimitsOfSolidarity(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LongRoadHome.java b/Mage.Sets/src/mage/cards/l/LongRoadHome.java index 1dbb18589f0..43a94cfd71e 100644 --- a/Mage.Sets/src/mage/cards/l/LongRoadHome.java +++ b/Mage.Sets/src/mage/cards/l/LongRoadHome.java @@ -58,7 +58,7 @@ import mage.target.common.TargetCreaturePermanent; public class LongRoadHome extends CardImpl { public LongRoadHome(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it. this.getSpellAbility().addEffect(new LongRoadHomeEffect()); @@ -163,7 +163,7 @@ class LongRoadHomeEntersBattlefieldEffect extends ReplacementEffectImpl { public LongRoadHomeEntersBattlefieldEffect(MageObjectReference objectToReturn) { super(Duration.Custom, Outcome.BoostCreature); this.objectToReturn = objectToReturn; - staticText = "that card returns to the battlefield with a +1/+1 counter on it"; + staticText = "that card to the battlefield under its owner's control with a +1/+1 counter on it"; } public LongRoadHomeEntersBattlefieldEffect(LongRoadHomeEntersBattlefieldEffect effect) { @@ -188,7 +188,7 @@ class LongRoadHomeEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + permanent.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); discard(); // use only once } return false; diff --git a/Mage.Sets/src/mage/cards/l/LordOfLineage.java b/Mage.Sets/src/mage/cards/l/LordOfLineage.java index 2f557c675cd..c7c25e6a969 100644 --- a/Mage.Sets/src/mage/cards/l/LordOfLineage.java +++ b/Mage.Sets/src/mage/cards/l/LordOfLineage.java @@ -28,10 +28,6 @@ package mage.cards.l; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -41,6 +37,9 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.permanent.token.Token; @@ -64,7 +63,7 @@ public class LordOfLineage extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(5); - // this card is the second face of double-faced card + // this card is the second face of double-faced card Bloodline Keeper this.nightCard = true; this.transformable = true; diff --git a/Mage.Sets/src/mage/cards/m/ManaEchoes.java b/Mage.Sets/src/mage/cards/m/ManaEchoes.java index bd90a651c77..a8c9c698f2c 100644 --- a/Mage.Sets/src/mage/cards/m/ManaEchoes.java +++ b/Mage.Sets/src/mage/cards/m/ManaEchoes.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; @@ -42,7 +41,8 @@ import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.util.CardUtil; + +import java.util.UUID; /** * @@ -91,7 +91,7 @@ class ManaEchoesEffect extends OneShotEffect { if (controller != null && permanent != null) { int foundCreatures = 0; for (Permanent perm : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { - if (CardUtil.shareSubtypes(permanent, perm, game)) { + if (permanent.shareSubtypes(perm, game)) { foundCreatures++; } } diff --git a/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java b/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java index f54ca0d7f14..27932f60a83 100644 --- a/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java +++ b/Mage.Sets/src/mage/cards/m/MarkOfSakiko.java @@ -123,6 +123,7 @@ class MarkOfSakikoTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever this creature deals combat damage to a player, add that much {G} to your mana pool. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end."; + return "Whenever this creature deals combat damage to a player, add that much {G} to your mana pool. " + + "Until end of turn, this mana doesn't empty from your mana pool as steps and phases end."; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MetallicMimic.java b/Mage.Sets/src/mage/cards/m/MetallicMimic.java index bb9c932b8d0..ea93082b975 100644 --- a/Mage.Sets/src/mage/cards/m/MetallicMimic.java +++ b/Mage.Sets/src/mage/cards/m/MetallicMimic.java @@ -123,7 +123,7 @@ class MetallicMimicReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/cards/m/MiasmaMummy.java b/Mage.Sets/src/mage/cards/m/MiasmaMummy.java new file mode 100644 index 00000000000..40bf8f465b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MiasmaMummy.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 java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class MiasmaMummy extends CardImpl { + + public MiasmaMummy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Zombie"); + this.subtype.add("Jackal"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Miasma Mummy enters the battlefield, each player discards a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect())); + } + + public MiasmaMummy(final MiasmaMummy card) { + super(card); + } + + @Override + public MiasmaMummy copy() { + return new MiasmaMummy(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MoltenDisaster.java b/Mage.Sets/src/mage/cards/m/MoltenDisaster.java index b8da4da2a71..c923173de3a 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenDisaster.java +++ b/Mage.Sets/src/mage/cards/m/MoltenDisaster.java @@ -27,7 +27,6 @@ */ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.KickedCondition; @@ -50,6 +49,9 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.Optional; +import java.util.UUID; + /** * * @author LevelX2 @@ -109,8 +111,8 @@ class MoltenDisasterSplitSecondEffect extends ContinuousRuleModifyingEffectImpl } } if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null && !(ability instanceof ActivatedManaAbilityImpl)) { + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) { if (KickedCondition.instance.apply(game, source)) { return true; } diff --git a/Mage.Sets/src/mage/cards/m/MycosynthLattice.java b/Mage.Sets/src/mage/cards/m/MycosynthLattice.java index aa6cf3f4a72..72f82fc9f33 100644 --- a/Mage.Sets/src/mage/cards/m/MycosynthLattice.java +++ b/Mage.Sets/src/mage/cards/m/MycosynthLattice.java @@ -27,9 +27,6 @@ */ package mage.cards.m; -import java.util.List; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.ObjectColor; import mage.abilities.Ability; @@ -40,14 +37,7 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AsThoughEffectType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.ManaType; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.command.CommandObject; import mage.game.permanent.Permanent; @@ -55,6 +45,8 @@ import mage.game.stack.Spell; import mage.players.ManaPoolItem; import mage.players.Player; +import java.util.UUID; + /** * @author duncant */ @@ -91,10 +83,7 @@ class PermanentsAreArtifactsEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { - Set cardType = perm.getCardType(); - if (!cardType.contains(CardType.ARTIFACT)) { - cardType.add(CardType.ARTIFACT); - } + perm.getCardType().add(CardType.ARTIFACT); } return true; } diff --git a/Mage.Sets/src/mage/cards/m/MyrIncubator.java b/Mage.Sets/src/mage/cards/m/MyrIncubator.java new file mode 100644 index 00000000000..8c78679d157 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MyrIncubator.java @@ -0,0 +1,118 @@ +/* + * 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.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.SearchEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.token.MyrToken; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author jeffwadsworth + */ +public class MyrIncubator extends CardImpl { + + public MyrIncubator(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}"); + + // {6}, {tap}, Sacrifice Myr Incubator: Search your library for any number of artifact cards, exile them, then put that many 1/1 colorless Myr artifact creature tokens onto the battlefield. Then shuffle your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MyrIncubatorEffect(), new ManaCostsImpl("{6}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + this.addAbility(ability); + + } + + public MyrIncubator(final MyrIncubator card) { + super(card); + } + + @Override + public MyrIncubator copy() { + return new MyrIncubator(this); + } +} + +class MyrIncubatorEffect extends SearchEffect { + + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + int tokensToCreate = 0; + + MyrIncubatorEffect() { + super(new TargetCardInLibrary(0, Integer.MAX_VALUE, filter), Outcome.Neutral); + staticText = "Search your library for any number of artifact cards, exile them, then put that many 1/1 colorless Myr artifact creature tokens onto the battlefield. Then shuffle your library"; + } + + MyrIncubatorEffect(final MyrIncubatorEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null + && controller.searchLibrary(target, game)) { + if (!target.getTargets().isEmpty()) { + tokensToCreate = target.getTargets().size(); + controller.moveCards(new CardsImpl(target.getTargets()), Zone.EXILED, source, game); + } + CreateTokenEffect effect = new CreateTokenEffect(new MyrToken(), tokensToCreate); + effect.apply(game, source); + controller.shuffleLibrary(source, game); + return true; + } + return false; + } + + @Override + public MyrIncubatorEffect copy() { + return new MyrIncubatorEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NecromanticSummons.java b/Mage.Sets/src/mage/cards/n/NecromanticSummons.java index 025dd705596..a2c07949d2c 100644 --- a/Mage.Sets/src/mage/cards/n/NecromanticSummons.java +++ b/Mage.Sets/src/mage/cards/n/NecromanticSummons.java @@ -30,17 +30,19 @@ package mage.cards.n; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.common.SpellMasteryCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInGraveyard; @@ -51,16 +53,15 @@ import mage.target.common.TargetCardInGraveyard; public class NecromanticSummons extends CardImpl { public NecromanticSummons(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); + this.getSpellAbility().addEffect(new NecromanticSummoningReplacementEffect());// has to be added before the moving effect // Put target creature card from a graveyard onto the battlefield under your control. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard"))); // Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, that creature enters the battlefield with two additional +1/+1 counters on it. - Effect effect = new ConditionalOneShotEffect(new NecromanticSummoningEffect(), - SpellMasteryCondition.instance, "
Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, that creature enters the battlefield with two additional +1/+1 counters on it"); - this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addEffect(new InfoEffect("\"
Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, that creature enters the battlefield with two additional +1/+1 counters on it\"")); } public NecromanticSummons(final NecromanticSummons card) { @@ -73,29 +74,46 @@ public class NecromanticSummons extends CardImpl { } } -class NecromanticSummoningEffect extends OneShotEffect { +class NecromanticSummoningReplacementEffect extends ReplacementEffectImpl { - public NecromanticSummoningEffect() { - super(Outcome.BoostCreature); - this.staticText = "
Spell mastery - If there are two or more instant and/or sorcery cards in your graveyard, that creature enters the battlefield with two additional +1/+1 counters on it"; + NecromanticSummoningReplacementEffect() { + super(Duration.EndOfStep, Outcome.BoostCreature); } - public NecromanticSummoningEffect(final NecromanticSummoningEffect effect) { + NecromanticSummoningReplacementEffect(NecromanticSummoningReplacementEffect effect) { super(effect); } @Override - public NecromanticSummoningEffect copy() { - return new NecromanticSummoningEffect(this); + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) { + return SpellMasteryCondition.instance.apply(game, source); + } + return false; } @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(2), source, game); - return true; + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + if (creature != null) { + creature.addCounters(CounterType.P1P1.createInstance(2), source, game, event.getAppliedEffects()); + discard(); } return false; } + + @Override + public NecromanticSummoningReplacementEffect copy() { + return new NecromanticSummoningReplacementEffect(this); + } } diff --git a/Mage.Sets/src/mage/cards/o/OketrasMonument.java b/Mage.Sets/src/mage/cards/o/OketrasMonument.java new file mode 100644 index 00000000000..725afe8a48e --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OketrasMonument.java @@ -0,0 +1,84 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.permanent.token.WarriorVigilantToken; + +/** + * + * @author fireshoes + */ +public class OketrasMonument extends CardImpl { + + private static final FilterCard filter = new FilterCard("White creature spells"); + private static final FilterSpell filter2 = new FilterSpell("a creature spell"); + + static { + filter.add(Predicates.and(new ColorPredicate(ObjectColor.WHITE), new CardTypePredicate(CardType.CREATURE))); + } + static { + filter2.add(new CardTypePredicate(CardType.CREATURE)); + } + + public OketrasMonument(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + addSuperType(SuperType.LEGENDARY); + + // White creature spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast a creature spell, create a 1/1 white Warrior creature token with vigilance. + this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new WarriorVigilantToken()), filter2, false)); + } + + public OketrasMonument(final OketrasMonument card) { + super(card); + } + + @Override + public OketrasMonument copy() { + return new OketrasMonument(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java index 9499e543896..53db6dfd14c 100644 --- a/Mage.Sets/src/mage/cards/o/OonasBlackguard.java +++ b/Mage.Sets/src/mage/cards/o/OonasBlackguard.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; public class OonasBlackguard extends CardImpl { public OonasBlackguard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add("Faerie"); this.subtype.add("Rogue"); this.power = new MageInt(1); @@ -121,7 +121,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/cards/o/OpalPalace.java b/Mage.Sets/src/mage/cards/o/OpalPalace.java index 09c48fda378..b746593bde6 100644 --- a/Mage.Sets/src/mage/cards/o/OpalPalace.java +++ b/Mage.Sets/src/mage/cards/o/OpalPalace.java @@ -110,7 +110,7 @@ class OpalPalaceWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.MANA_PAYED) { + if (event.getType() == GameEvent.EventType.MANA_PAID) { if (event.getData() != null && event.getData().equals(originalId)) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null) { diff --git a/Mage.Sets/src/mage/cards/o/OraclesVault.java b/Mage.Sets/src/mage/cards/o/OraclesVault.java new file mode 100644 index 00000000000..23f0b6e3545 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OraclesVault.java @@ -0,0 +1,163 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.MageObject; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.players.Library; +import mage.players.Player; + +/** + * + * @author fireshoes + */ +public class OraclesVault extends CardImpl { + + public OraclesVault(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + // {2}, {T}: Exile the top card of your library. Until end of turn, you may play that card. Put a brick counter on Oracle's Vault. + Effect effect = new OraclesVaultEffect(); + effect.setText("Exile the top card of your library. Until end of turn, you may play that card"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2)); + ability.addCost(new TapSourceCost()); + Effect effect2 = new AddCountersSourceEffect(CounterType.BRICK.createInstance()); + effect2.setText("Put a brick counter on {this}"); + ability.addEffect(effect2); + this.addAbility(ability); + + // {T}: Exile the top card of your library. Until end of turn, you may play that card without paying its mana cost. + // Activate this ability only if there are three or more brick counters on Oracle's Vault. + this.addAbility(new ConditionalActivatedAbility(Zone.BATTLEFIELD, + new OraclesVaultEffect(), new TapSourceCost(), new SourceHasCounterCondition(CounterType.BRICK, 3, Integer.MAX_VALUE), + "{T}: Exile the top card of your library. Until end of turn, you may play that card without paying its mana cost. " + + "Activate this ability only if there are three or more brick counters on {this}")); + } + + public OraclesVault(final OraclesVault card) { + super(card); + } + + @Override + public OraclesVault copy() { + return new OraclesVault(this); + } +} + +class OraclesVaultEffect extends OneShotEffect { + + public OraclesVaultEffect() { + super(Outcome.Benefit); + } + + public OraclesVaultEffect(final OraclesVaultEffect effect) { + super(effect); + } + + @Override + public OraclesVaultEffect copy() { + return new OraclesVaultEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) { + Library library = controller.getLibrary(); + Card card = library.removeFromTop(game); + if (card != null) { + controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " ", source.getSourceId(), game, Zone.LIBRARY, true); + game.addEffect(new OraclesVaultPlayEffect(new MageObjectReference(card, game)), source); + } + return true; + } + return false; + } +} + +class OraclesVaultPlayEffect extends AsThoughEffectImpl { + + private final MageObjectReference objectReference; + + public OraclesVaultPlayEffect(MageObjectReference objectReference) { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + this.objectReference = objectReference; + staticText = "Until end of turn, you may play that card without paying its mana cost"; + } + + public OraclesVaultPlayEffect(final OraclesVaultPlayEffect effect) { + super(effect); + this.objectReference = effect.objectReference; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public OraclesVaultPlayEffect copy() { + return new OraclesVaultPlayEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectReference.refersTo(objectId, game) && affectedControllerId.equals(source.getControllerId())) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + return true; + } else { + discard(); + } + } + return false; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/o/OtherworldlyJourney.java b/Mage.Sets/src/mage/cards/o/OtherworldlyJourney.java index 1c24520f24d..3caa3685779 100644 --- a/Mage.Sets/src/mage/cards/o/OtherworldlyJourney.java +++ b/Mage.Sets/src/mage/cards/o/OtherworldlyJourney.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreaturePermanent; public class OtherworldlyJourney extends CardImpl { public OtherworldlyJourney(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.subtype.add("Arcane"); // Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it. @@ -184,7 +184,7 @@ class OtherworldlyJourneyEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + permanent.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); discard(); // use only once } return false; diff --git a/Mage.Sets/src/mage/cards/p/PithingNeedle.java b/Mage.Sets/src/mage/cards/p/PithingNeedle.java index 7846dfbc157..7999199577f 100644 --- a/Mage.Sets/src/mage/cards/p/PithingNeedle.java +++ b/Mage.Sets/src/mage/cards/p/PithingNeedle.java @@ -27,7 +27,6 @@ */ package mage.cards.p; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -36,14 +35,13 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.NameACardEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; +import java.util.Optional; +import java.util.UUID; + /** * * @author jeffwadsworth, nox @@ -99,9 +97,9 @@ class PithingNeedleEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null && object != null) { - if (ability.getAbilityType() != AbilityType.MANA + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && object != null) { + if (ability.get().getAbilityType() != AbilityType.MANA && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { return true; } diff --git a/Mage.Sets/src/mage/cards/p/PrimalSurge.java b/Mage.Sets/src/mage/cards/p/PrimalSurge.java index d941e8f4a89..b02bd81704b 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalSurge.java +++ b/Mage.Sets/src/mage/cards/p/PrimalSurge.java @@ -27,21 +27,20 @@ */ package mage.cards.p; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; 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.game.permanent.Permanent; import mage.players.Player; +import java.util.UUID; + /** * * @author North @@ -96,10 +95,7 @@ class PrimalSurgeEffect extends OneShotEffect { Card card = player.getLibrary().removeFromTop(game); if (card != null) { card.moveToExile(null, "", source.getSourceId(), game); - Set cardType = card.getCardType(); - if ((cardType.contains(CardType.ARTIFACT) || cardType.contains(CardType.CREATURE) - || cardType.contains(CardType.ENCHANTMENT) || cardType.contains(CardType.LAND) - || cardType.contains(CardType.PLANESWALKER)) + if (card.isPermanent() && player.chooseUse(Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield?", source, game)) { card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); diff --git a/Mage.Sets/src/mage/cards/p/ProwlingSerpopard.java b/Mage.Sets/src/mage/cards/p/ProwlingSerpopard.java new file mode 100644 index 00000000000..93536124fdf --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/ProwlingSerpopard.java @@ -0,0 +1,78 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CantBeCounteredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CantBeCounteredControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author fireshoes + */ +public class ProwlingSerpopard extends CardImpl { + + private static final FilterSpell filterTarget = new FilterSpell("Creature spells you control"); + + static { + filterTarget.add(new CardTypePredicate(CardType.CREATURE)); + } + + public ProwlingSerpopard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + + this.subtype.add("Cat"); + this.subtype.add("Snake"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Prowling Serpopard can't be countered. + this.addAbility(new CantBeCounteredAbility()); + + // Creature spells you control can't be countered. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeCounteredControlledEffect(filterTarget, null, Duration.WhileOnBattlefield))); + } + + public ProwlingSerpopard(final ProwlingSerpopard card) { + super(card); + } + + @Override + public ProwlingSerpopard copy() { + return new ProwlingSerpopard(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java index c6920782835..b677532edc7 100644 --- a/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java +++ b/Mage.Sets/src/mage/cards/p/PyromancersGoggles.java @@ -106,7 +106,7 @@ class PyromancersGogglesTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.MANA_PAYED; + return event.getType() == EventType.MANA_PAID; } @Override diff --git a/Mage.Sets/src/mage/cards/r/RhonassMonument.java b/Mage.Sets/src/mage/cards/r/RhonassMonument.java new file mode 100644 index 00000000000..fe8192a9012 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RhonassMonument.java @@ -0,0 +1,94 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class RhonassMonument extends CardImpl { + + private static final FilterCard filter = new FilterCard("Green creature spells"); + private static final FilterSpell filter2 = new FilterSpell("a creature spell"); + + static { + filter.add(Predicates.and(new ColorPredicate(ObjectColor.GREEN), new CardTypePredicate(CardType.CREATURE))); + } + static { + filter2.add(new CardTypePredicate(CardType.CREATURE)); + } + + public RhonassMonument(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + addSuperType(SuperType.LEGENDARY); + + // Green creature spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast a creature spell, target creature you control gets +2/+2 and gains trample until end of turn. + Ability ability = new SpellCastControllerTriggeredAbility(new BoostTargetEffect(2, 2, Duration.EndOfTurn), filter2, false); + Effect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText(" and gains trample until end of turn"); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public RhonassMonument(final RhonassMonument card) { + super(card); + } + + @Override + public RhonassMonument copy() { + return new RhonassMonument(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SageOfFables.java b/Mage.Sets/src/mage/cards/s/SageOfFables.java index 1191c3f0e6a..8f8b69733f1 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfFables.java +++ b/Mage.Sets/src/mage/cards/s/SageOfFables.java @@ -56,7 +56,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class SageOfFables extends CardImpl { public SageOfFables(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add("Merfolk"); this.subtype.add("Wizard"); this.power = new MageInt(2); @@ -115,7 +115,7 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/cards/s/SavageSummoning.java b/Mage.Sets/src/mage/cards/s/SavageSummoning.java index fd659f974e3..3986eb24618 100644 --- a/Mage.Sets/src/mage/cards/s/SavageSummoning.java +++ b/Mage.Sets/src/mage/cards/s/SavageSummoning.java @@ -64,7 +64,7 @@ import mage.watchers.Watcher; public class SavageSummoning extends CardImpl { public SavageSummoning(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); // Savage Summoning can't be countered. Ability ability = new CantBeCounteredAbility(); @@ -315,7 +315,7 @@ class SavageSummoningEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } discard(); return false; diff --git a/Mage.Sets/src/mage/cards/s/ScatteredGroves.java b/Mage.Sets/src/mage/cards/s/ScatteredGroves.java new file mode 100644 index 00000000000..07d07c11d46 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScatteredGroves.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class ScatteredGroves extends CardImpl { + + public ScatteredGroves(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Forest"); + this.subtype.add("Plains"); + + // ({T}: Add {G} or {W} to your mana pool.) + this.addAbility(new GreenManaAbility()); + this.addAbility(new WhiteManaAbility()); + + // Scattered Groves enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public ScatteredGroves(final ScatteredGroves card) { + super(card); + } + + @Override + public ScatteredGroves copy() { + return new ScatteredGroves(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ScribeOfTheMindful.java b/Mage.Sets/src/mage/cards/s/ScribeOfTheMindful.java new file mode 100644 index 00000000000..e6e37fd6686 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScribeOfTheMindful.java @@ -0,0 +1,85 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author fireshoes + */ +public class ScribeOfTheMindful extends CardImpl { + + private static final FilterCard filter = new FilterCard("instant or sorcery card from your graveyard"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); + } + + public ScribeOfTheMindful(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}, {T}, Sacrifice Scribe of the Mindful: Return target instant or sorcery card from your graveyard to your hand. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + } + + public ScribeOfTheMindful(final ScribeOfTheMindful card) { + super(card); + } + + @Override + public ScribeOfTheMindful copy() { + return new ScribeOfTheMindful(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java b/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java index a1c0dee10e0..cea6d8f4cc2 100644 --- a/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java +++ b/Mage.Sets/src/mage/cards/s/SemblanceAnvil.java @@ -143,7 +143,7 @@ class SemblanceAnvilCostReductionEffect extends CostModificationEffectImpl { List imprinted = permanent.getImprinted(); if (!imprinted.isEmpty()) { Card imprintedCard = game.getCard(imprinted.get(0)); - if (imprintedCard != null && CardUtil.shareTypes(imprintedCard, sourceCard)) { + if (imprintedCard != null && imprintedCard.shareTypes(sourceCard)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/s/ShelteredThicket.java b/Mage.Sets/src/mage/cards/s/ShelteredThicket.java new file mode 100644 index 00000000000..fc9ac687146 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShelteredThicket.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class ShelteredThicket extends CardImpl { + + public ShelteredThicket(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add("Mountain"); + this.subtype.add("Forest"); + + // ({T}: Add {R} or {G} to your mana pool.) + this.addAbility(new RedManaAbility()); + this.addAbility(new GreenManaAbility()); + + // Sheltered Thicket enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public ShelteredThicket(final ShelteredThicket card) { + super(card); + } + + @Override + public ShelteredThicket copy() { + return new ShelteredThicket(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShiftingLoyalties.java b/Mage.Sets/src/mage/cards/s/ShiftingLoyalties.java index 922ea52de84..a059a4d5cf3 100644 --- a/Mage.Sets/src/mage/cards/s/ShiftingLoyalties.java +++ b/Mage.Sets/src/mage/cards/s/ShiftingLoyalties.java @@ -27,9 +27,6 @@ */ package mage.cards.s; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.common.continuous.ExchangeControlTargetEffect; @@ -41,7 +38,10 @@ import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; -import mage.util.CardUtil; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** * @@ -88,7 +88,7 @@ class TargetPermanentsThatShareCardType extends TargetPermanent { if (targetOne == null || targetTwo == null) { return false; } - return CardUtil.shareTypes(targetOne, targetTwo); + return targetOne.shareTypes(targetTwo); } return true; } diff --git a/Mage.Sets/src/mage/cards/s/SixthSense.java b/Mage.Sets/src/mage/cards/s/SixthSense.java new file mode 100644 index 00000000000..ac69a067220 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SixthSense.java @@ -0,0 +1,122 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; + +/** + * + * @author fireshoes + */ +public class SixthSense extends CardImpl { + + public SixthSense(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + + 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); + + // Enchanted creature has "Whenever this creature deals combat damage to a player, you may draw a card." + Effect effect = new GainAbilityAttachedEffect(new SixthSenseTriggeredAbility(), AttachmentType.AURA); + effect.setText("Enchanted creature has \"Whenever this creature deals combat damage to a player, you may draw a card.\""); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public SixthSense(final SixthSense card) { + super(card); + } + + @Override + public SixthSense copy() { + return new SixthSense(this); + } +} + +class SixthSenseTriggeredAbility extends TriggeredAbilityImpl { + + public SixthSenseTriggeredAbility() { + super(Zone.BATTLEFIELD, null, true); + } + + public SixthSenseTriggeredAbility(final SixthSenseTriggeredAbility ability) { + super(ability); + } + + @Override + public SixthSenseTriggeredAbility copy() { + return new SixthSenseTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (((DamagedEvent) event).isCombatDamage()) { + if (event.getSourceId().equals(getSourceId())) { + this.getEffects().clear(); + this.addEffect(new DrawCardSourceControllerEffect(1)); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever this creature deals combat damage to a player, you may draw a card."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SoulBurn.java b/Mage.Sets/src/mage/cards/s/SoulBurn.java new file mode 100644 index 00000000000..8d85b1b3467 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoulBurn.java @@ -0,0 +1,185 @@ +/* + * 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.s; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.costs.VariableCost; +import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterMana; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * @author Johnny E. Hastings + */ +public class SoulBurn extends CardImpl { + + public static final FilterMana filterBlackOrRed = new FilterMana(); + + static { + filterBlackOrRed.setBlack(true); + filterBlackOrRed.setRed(true); + } + + public SoulBurn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{2}{B}"); + + // Spend only black or red mana on X. + // Soul Burn deals X damage to target creature or player. You gain life equal to the damage dealt for each black mana spent on X; not more life than the player's life total before Soul Burn dealt damage, or the creature's toughness. + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + this.getSpellAbility().addEffect(new SoulBurnEffect()); + VariableCost variableCost = this.getSpellAbility().getManaCostsToPay().getVariableCosts().get(0); + if (variableCost instanceof VariableManaCost) { + ((VariableManaCost) variableCost).setFilter(filterBlackOrRed); + } + } + + public SoulBurn(final SoulBurn card) { + super(card); + } + + @Override + public SoulBurn copy() { + return new SoulBurn(this); + } +} + +class SoulBurnEffect extends OneShotEffect { + + public SoulBurnEffect() { + super(Outcome.Damage); + staticText = "{this} deals X damage to target creature or player for each black or red mana spent on X. You gain life equal to the damage dealt for each black mana spent; not more life than the player's life total before Soul Burn dealt damage, or the creature's toughness."; + } + + public SoulBurnEffect(final SoulBurnEffect effect) { + super(effect); + } + + /*** + * @param game + * @param source + * @return + */ + @Override + public boolean apply(Game game, Ability source) { + + // Get the colors we care about. (This isn't racist, honestly.) + int amountBlack = source.getManaCostsToPay().getPayment().getBlack(); + int amountRed = source.getManaCostsToPay().getPayment().getRed(); + + // Get the colors we don't really care about. (See note above.) + int amountWhite = source.getManaCostsToPay().getPayment().getWhite(); + int amountGreen = source.getManaCostsToPay().getPayment().getGreen(); + int amountBlue = source.getManaCostsToPay().getPayment().getBlue(); + int amountColorless = source.getManaCostsToPay().getPayment().getColorless(); + + // Figure out what was spent on the spell in total, determine proper values for + // black and red, minus initial casting cost. + int totalColorlessForCastingCost = amountWhite + amountGreen + amountBlue + amountColorless; + int amountOffsetByColorless = 0; + if (totalColorlessForCastingCost > 0) { + amountOffsetByColorless = totalColorlessForCastingCost; + if (amountOffsetByColorless > 2) { + // The game should never let this happen, but I'll check anyway since I don't know + // the guts of the game [yet]. + amountOffsetByColorless = 2; + } + } + + // Remove 1 black to account for casting cost. + amountBlack--; + + // Determine if we need to offset the red or black values any further due to the + // amount of non-red and non-black paid. + if (amountOffsetByColorless < 2) { + int amountToOffsetBy = 2 - amountOffsetByColorless; + + if (amountRed > 0) { + if (amountRed >= amountToOffsetBy) { + // Pay all additional unpaid casting cost with red. + amountRed = amountRed - amountToOffsetBy; + } else { + // Red paid doesn't cover the 2 default required by the spell. + // Pay some in red, and some in black. + // If we're here, red is 1, and amountToOffetBy is 2. + // That means we can subtract 1 from both red and black. + amountRed--; + amountBlack--; + } + } else { + // Pay all additional unpaid casting cost with black. + amountBlack = amountBlack - amountToOffsetBy; + } + } + + int totalXAmount = amountBlack + amountRed; + + int lifetogain = amountBlack; + if (totalXAmount > 0) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null ) { + if (permanent.getToughness().getValue() < lifetogain) { + lifetogain = permanent.getToughness().getValue(); + } + permanent.damage(totalXAmount, source.getSourceId(), game, false, true); + } else { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (player != null) { + if (player.getLife() < lifetogain) { + lifetogain = player.getLife(); + } + player.damage(totalXAmount, source.getSourceId(), game, false, true); + } else { + return false; + } + } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.gainLife(lifetogain, game); + } else { + return false; + } + } + return true; + } + + @Override + public SoulBurnEffect copy() { + return new SoulBurnEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/cards/s/SplendidAgony.java b/Mage.Sets/src/mage/cards/s/SplendidAgony.java new file mode 100644 index 00000000000..571b040cb7f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SplendidAgony.java @@ -0,0 +1,60 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.effects.common.counter.DistributeCountersEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author fireshoes + */ +public class SplendidAgony extends CardImpl { + + public SplendidAgony(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}"); + + // Distribute two -1/-1 counters among one or two target creatures. + getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.M1M1, 2, false, "one or two target creatures you control")); + getSpellAbility().addTarget(new TargetCreaturePermanentAmount(2)); + } + + public SplendidAgony(final SplendidAgony card) { + super(card); + } + + @Override + public SplendidAgony copy() { + return new SplendidAgony(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/StoneforgeMasterwork.java b/Mage.Sets/src/mage/cards/s/StoneforgeMasterwork.java index 4446847b127..fa3d53ccfe0 100644 --- a/Mage.Sets/src/mage/cards/s/StoneforgeMasterwork.java +++ b/Mage.Sets/src/mage/cards/s/StoneforgeMasterwork.java @@ -27,7 +27,6 @@ */ package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; @@ -43,7 +42,8 @@ import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.util.CardUtil; + +import java.util.UUID; /** * @@ -85,7 +85,7 @@ class StoneforgeMasterworkDynamicValue implements DynamicValue { if (equipped != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), sourceAbility.getControllerId(), game)) { if (!permanent.getId().equals(equipped.getId())) { - if (CardUtil.shareSubtypes(equipped, permanent, game)) { + if (equipped.shareSubtypes(permanent, game)) { xValue++; } } diff --git a/Mage.Sets/src/mage/cards/t/TatteredMummy.java b/Mage.Sets/src/mage/cards/t/TatteredMummy.java new file mode 100644 index 00000000000..b96dc4a4e85 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TatteredMummy.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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class TatteredMummy extends CardImpl { + + public TatteredMummy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Zombie"); + this.subtype.add("Jackal"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When Tattered Mummy dies, each opponent loses 2 life. + this.addAbility(new DiesTriggeredAbility(new LoseLifeOpponentsEffect(2))); + } + + public TatteredMummy(final TatteredMummy card) { + super(card); + } + + @Override + public TatteredMummy copy() { + return new TatteredMummy(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java index 69d32e78959..5f1fdc2b539 100644 --- a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java +++ b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java @@ -112,7 +112,7 @@ class TheGitrogMonsterTriggeredAbility extends TriggeredAbilityImpl { if (cardOwnerId != null && card.getOwnerId().equals(getControllerId()) && cardType != null - && cardType.contains(CardType.LAND)) { + && card.isLand()) { return true; } } diff --git a/Mage.Sets/src/mage/cards/t/ThoughtReflection.java b/Mage.Sets/src/mage/cards/t/ThoughtReflection.java index 68f161bf8f9..39a743dc066 100644 --- a/Mage.Sets/src/mage/cards/t/ThoughtReflection.java +++ b/Mage.Sets/src/mage/cards/t/ThoughtReflection.java @@ -49,8 +49,8 @@ import mage.players.Player; public class ThoughtReflection extends CardImpl { public ThoughtReflection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}{U}{U}"); + // If you would draw a card, draw two cards instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ThoughtReflectionReplacementEffect())); @@ -90,13 +90,13 @@ class ThoughtReflectionReplacementEffect extends ReplacementEffectImpl { @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.DRAW_CARD; - } + } @Override public boolean applies(GameEvent event, Ability source, Game game) { return event.getPlayerId().equals(source.getControllerId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player you = game.getPlayer(event.getPlayerId()); @@ -104,5 +104,5 @@ class ThoughtReflectionReplacementEffect extends ReplacementEffectImpl { you.drawCards(2, game, event.getAppliedEffects()); } return true; - } + } } diff --git a/Mage.Sets/src/mage/cards/t/ThranTurbine.java b/Mage.Sets/src/mage/cards/t/ThranTurbine.java index 8853d1bbee1..79eb14eceee 100644 --- a/Mage.Sets/src/mage/cards/t/ThranTurbine.java +++ b/Mage.Sets/src/mage/cards/t/ThranTurbine.java @@ -30,11 +30,9 @@ package mage.cards.t; import mage.ConditionalMana; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; -import mage.abilities.costs.mana.ManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AddConditionalColorlessManaEffect; import mage.abilities.mana.builder.ConditionalManaBuilder; @@ -53,6 +51,7 @@ import mage.players.Player; import java.util.HashSet; import java.util.UUID; +import mage.game.stack.Spell; /** * @@ -61,7 +60,7 @@ import java.util.UUID; public class ThranTurbine extends CardImpl { public ThranTurbine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); // At the beginning of your upkeep, you may add {C} or {C}{C} to your mana pool. You can't spend this mana to cast spells. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ThranTurbineEffect(), TargetController.YOU, true)); @@ -145,14 +144,9 @@ class ThranTurbineManaCondition extends ManaCondition implements Condition { @Override public boolean apply(Game game, Ability source, UUID originalId, Cost costToPay) { - if (!(source instanceof SpellAbility)) { - Permanent object = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (object != null && object.getColor(game).isColorless()) { - return true; - } - } - if (costToPay instanceof ManaCost) { - return ((ManaCost) costToPay).getText().contains("{C}"); + if (!(source instanceof Spell)) { + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + return permanent != null; } return false; } diff --git a/Mage.Sets/src/mage/cards/t/TrialOfKnowledge.java b/Mage.Sets/src/mage/cards/t/TrialOfKnowledge.java new file mode 100644 index 00000000000..90533602571 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrialOfKnowledge.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author fireshoes + */ +public class TrialOfKnowledge extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Cartouche"); + + static { + filter.add(new SubtypePredicate("Cartouche")); + } + + public TrialOfKnowledge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); + + // When Trial of Knowledge enters the battlefield, draw three cards, then discard a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 1), false)); + + // When a Cartouche enters the battlefield under your control, return Trial of Knowledge to its owner's hand. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new ReturnToHandSourceEffect(), filter, + "When a Cartouche enters the battlefield under your control, return {this} to its owner's hand")); + } + + public TrialOfKnowledge(final TrialOfKnowledge card) { + super(card); + } + + @Override + public TrialOfKnowledge copy() { + return new TrialOfKnowledge(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VigorMortis.java b/Mage.Sets/src/mage/cards/v/VigorMortis.java index 7bf05119abe..4bf838e0998 100644 --- a/Mage.Sets/src/mage/cards/v/VigorMortis.java +++ b/Mage.Sets/src/mage/cards/v/VigorMortis.java @@ -30,17 +30,20 @@ package mage.cards.v; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.common.ManaWasSpentCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; import mage.constants.Outcome; import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInYourGraveyard; @@ -51,12 +54,14 @@ import mage.target.common.TargetCardInYourGraveyard; public class VigorMortis extends CardImpl { public VigorMortis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); // Return target creature card from your graveyard to the battlefield. If {G} was spent to cast Vigor Mortis, that creature enters the battlefield with an additional +1/+1 counter on it. + this.getSpellAbility().addEffect(new VigorMortisReplacementEffect()); // has to be added before the moving effect this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); + this.getSpellAbility().addEffect(new InfoEffect("If {G} was spent to cast {this}, that creature enters the battlefield with an additional +1/+1 counter on it")); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard())); - this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new VigorMortisAddCounterEffect(), new ManaWasSpentCondition(ColoredManaSymbol.G))); + } public VigorMortis(final VigorMortis card) { @@ -69,29 +74,46 @@ public class VigorMortis extends CardImpl { } } -class VigorMortisAddCounterEffect extends OneShotEffect { - - VigorMortisAddCounterEffect() { - super(Outcome.BoostCreature); - this.staticText = "that creature enters the battlefield with an additional +1/+1 counter on it"; +class VigorMortisReplacementEffect extends ReplacementEffectImpl { + + VigorMortisReplacementEffect() { + super(Duration.EndOfStep, Outcome.BoostCreature); } - - VigorMortisAddCounterEffect(final VigorMortisAddCounterEffect effect) { + + VigorMortisReplacementEffect(VigorMortisReplacementEffect effect) { super(effect); } - + @Override - public VigorMortisAddCounterEffect copy() { - return new VigorMortisAddCounterEffect(this); + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override - public boolean apply(Game game, Ability source) { - // targetPointer can't be used because target moved from graveyard to battlefield - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) { + return new ManaWasSpentCondition(ColoredManaSymbol.G).apply(game, source); } return false; } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + if (creature != null) { + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); + discard(); + } + return false; + } + + @Override + public VigorMortisReplacementEffect copy() { + return new VigorMortisReplacementEffect(this); + } } diff --git a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java index dad82f569fb..b77db39c7b7 100644 --- a/Mage.Sets/src/mage/cards/w/WeightOfConscience.java +++ b/Mage.Sets/src/mage/cards/w/WeightOfConscience.java @@ -27,10 +27,6 @@ */ package mage.cards.w; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -56,6 +52,11 @@ import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; import mage.util.CardUtil; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + /** * * @author emerald000 @@ -158,7 +159,7 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent { Permanent firstTargetCreature = game.getPermanent(firstTargetId); if (firstTargetCreature != null) { for (Permanent permanent : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) { - if (!permanent.getId().equals(firstTargetId) && CardUtil.shareSubtypes(firstTargetCreature, permanent, game)) { + if (!permanent.getId().equals(firstTargetId) && firstTargetCreature.shareSubtypes(permanent, game)) { possibleTargets.add(permanent.getId()); } } @@ -172,7 +173,7 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent { public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { for (Permanent permanent1 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) { for (Permanent permanent2 : game.getBattlefield().getActivePermanents(filterUntapped, sourceControllerId, game)) { - if (!Objects.equals(permanent1, permanent2) && CardUtil.shareSubtypes(permanent1, permanent2, game)) { + if (!Objects.equals(permanent1, permanent2) && permanent1.shareSubtypes(permanent2, game)) { return true; } } @@ -198,7 +199,7 @@ class WeightOfConscienceTarget extends TargetControlledCreaturePermanent { } else { Permanent firstTarget = game.getPermanent(this.getTargets().get(0)); - if (firstTarget != null && CardUtil.shareSubtypes(firstTarget, targetPermanent, game)) { + if (firstTarget != null && firstTarget.shareSubtypes(targetPermanent, game)) { return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WookieeMystic.java b/Mage.Sets/src/mage/cards/w/WookieeMystic.java index ff84557fb03..05211b93998 100644 --- a/Mage.Sets/src/mage/cards/w/WookieeMystic.java +++ b/Mage.Sets/src/mage/cards/w/WookieeMystic.java @@ -120,7 +120,7 @@ class WookieeMysticWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.MANA_PAYED) { + if (event.getType() == GameEvent.EventType.MANA_PAID) { MageObject target = game.getObject(event.getTargetId()); if (event.getSourceId() != null && event.getSourceId().equals(this.getSourceId()) diff --git a/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java b/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java index 986e717a004..b691159e4f0 100644 --- a/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java +++ b/Mage.Sets/src/mage/cards/z/ZameckGuildmage.java @@ -55,7 +55,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class ZameckGuildmage extends CardImpl { public ZameckGuildmage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}"); this.subtype.add("Elf"); this.subtype.add("Wizard"); @@ -112,7 +112,7 @@ class ZameckGuildmageEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { - target.addCounters(CounterType.P1P1.createInstance(), source, game); + target.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } return false; } diff --git a/Mage.Sets/src/mage/sets/Amonkhet.java b/Mage.Sets/src/mage/sets/Amonkhet.java index d485a52634d..5c844c71845 100644 --- a/Mage.Sets/src/mage/sets/Amonkhet.java +++ b/Mage.Sets/src/mage/sets/Amonkhet.java @@ -27,7 +27,13 @@ */ package mage.sets; +import java.util.ArrayList; +import java.util.List; +import mage.cards.CardGraphicInfo; import mage.cards.ExpansionSet; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; import mage.constants.Rarity; import mage.constants.SetType; @@ -43,18 +49,107 @@ public class Amonkhet extends ExpansionSet { return instance; } + protected final List savedSpecialLand = new ArrayList<>(); + private Amonkhet() { super("Amonkhet", "AKH", ExpansionSet.buildDate(2017, 4, 28), SetType.EXPANSION); this.blockName = "Amonkhet"; this.hasBoosters = true; + this.hasBasicLands = true; this.numBoosterLands = 1; this.numBoosterCommon = 10; this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Dusk // Dawn", 210, Rarity.RARE, mage.cards.d.DuskDawn.class)); + this.maxCardNumberInBooster = 269; + this.ratioBoosterSpecialLand = 144; + + cards.add(new SetCardInfo("Ancient Crab", 40, Rarity.COMMON, mage.cards.a.AncientCrab.class)); + cards.add(new SetCardInfo("Angler Drake", 41, Rarity.UNCOMMON, mage.cards.a.AnglerDrake.class)); + cards.add(new SetCardInfo("Archfiend of Ifnir", 78, Rarity.RARE, mage.cards.a.ArchfiendOfIfnir.class)); + cards.add(new SetCardInfo("Aven Mindcensor", 5, Rarity.RARE, mage.cards.a.AvenMindcensor.class)); + cards.add(new SetCardInfo("Bontu's Monument", 225, Rarity.UNCOMMON, mage.cards.b.BontusMonument.class)); + cards.add(new SetCardInfo("Canyon Slough", 239, Rarity.RARE, mage.cards.c.CanyonSlough.class)); + cards.add(new SetCardInfo("Cartouche of Solidarity", 7, Rarity.COMMON, mage.cards.c.CartoucheOfSolidarity.class)); + cards.add(new SetCardInfo("Cast Out", 8, Rarity.UNCOMMON, mage.cards.c.CastOut.class)); + cards.add(new SetCardInfo("Channeler Initiate", 160, Rarity.RARE, mage.cards.c.ChannelerInitiate.class)); + cards.add(new SetCardInfo("Consuming Fervor", 126, Rarity.UNCOMMON, mage.cards.c.ConsumingFervor.class)); + cards.add(new SetCardInfo("Crocodile of the Crossing", 162, Rarity.UNCOMMON, mage.cards.c.CrocodileOfTheCrossing.class)); + cards.add(new SetCardInfo("Cursed Minotaur", 85, Rarity.COMMON, mage.cards.c.CursedMinotaur.class)); + cards.add(new SetCardInfo("Decision Paralysis", 50, Rarity.COMMON, mage.cards.d.DecisionParalysis.class)); cards.add(new SetCardInfo("Destined // Lead", 217, Rarity.UNCOMMON, mage.cards.d.DestinedLead.class)); + cards.add(new SetCardInfo("Djeru's Resolve", 11, Rarity.COMMON, mage.cards.d.DjerusResolve.class)); + cards.add(new SetCardInfo("Drake Haven", 51, Rarity.RARE, mage.cards.d.DrakeHaven.class)); + cards.add(new SetCardInfo("Dune Beetle", 89, Rarity.COMMON, mage.cards.d.DuneBeetle.class)); + cards.add(new SetCardInfo("Dusk // Dawn", 210, Rarity.RARE, mage.cards.d.DuskDawn.class)); + cards.add(new SetCardInfo("Essence Scatter", 52, Rarity.COMMON, mage.cards.e.EssenceScatter.class)); + cards.add(new SetCardInfo("Exemplar of Strength", 165, Rarity.UNCOMMON, mage.cards.e.ExemplarOfStrength.class)); + cards.add(new SetCardInfo("Fetid Pools", 243, Rarity.RARE, mage.cards.f.FetidPools.class)); + cards.add(new SetCardInfo("Flameblade Adept", 131, Rarity.UNCOMMON, mage.cards.f.FlamebladeAdept.class)); + cards.add(new SetCardInfo("Fling", 132, Rarity.COMMON, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 267, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 268, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 269, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Giant Spider", 166, Rarity.COMMON, mage.cards.g.GiantSpider.class)); + cards.add(new SetCardInfo("Gideon, Martial Paragon", 270, Rarity.MYTHIC, mage.cards.g.GideonMartialParagon.class)); + cards.add(new SetCardInfo("Graceful Cat", 273, Rarity.COMMON, mage.cards.g.GracefulCat.class)); + cards.add(new SetCardInfo("Gravedigger", 93, Rarity.UNCOMMON, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Hazoret the Fervent", 136, Rarity.MYTHIC, mage.cards.h.HazoretTheFervent.class)); + cards.add(new SetCardInfo("Hazoret's Monument", 229, Rarity.UNCOMMON, mage.cards.h.HazoretsMonument.class)); + cards.add(new SetCardInfo("Hyena Pack", 139, Rarity.COMMON, mage.cards.h.HyenaPack.class)); + cards.add(new SetCardInfo("Impeccable Timing", 18, Rarity.COMMON, mage.cards.i.ImpeccableTiming.class)); + cards.add(new SetCardInfo("In Oketra's Name", 19, Rarity.COMMON, mage.cards.i.InOketrasName.class)); + cards.add(new SetCardInfo("Irrigated Farmland", 245, Rarity.RARE, mage.cards.i.IrrigatedFarmland.class)); + cards.add(new SetCardInfo("Island", 251, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 258, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 259, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 260, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Kefnet's Monument", 231, Rarity.UNCOMMON, mage.cards.k.KefnetsMonument.class)); + cards.add(new SetCardInfo("Lay Bare the Heart", 96, Rarity.UNCOMMON, mage.cards.l.LayBareTheHeart.class)); + cards.add(new SetCardInfo("Liliana, Death Wielder", 274, Rarity.MYTHIC, mage.cards.l.LilianaDeathWielder.class)); + cards.add(new SetCardInfo("Limits of Solidarity", 140, Rarity.UNCOMMON, mage.cards.l.LimitsOfSolidarity.class)); + cards.add(new SetCardInfo("Miasma Mummy", 100, Rarity.COMMON, mage.cards.m.MiasmaMummy.class)); + cards.add(new SetCardInfo("Mighty Leap", 20, Rarity.COMMON, mage.cards.m.MightyLeap.class)); + cards.add(new SetCardInfo("Mountain", 253, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 264, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 265, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 266, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Oketra's Monument", 233, Rarity.UNCOMMON, mage.cards.o.OketrasMonument.class)); cards.add(new SetCardInfo("Onward // Victory", 218, Rarity.UNCOMMON, mage.cards.o.OnwardVictory.class)); + cards.add(new SetCardInfo("Oracle's Vault", 234, Rarity.RARE, mage.cards.o.OraclesVault.class)); + cards.add(new SetCardInfo("Plains", 250, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 255, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 256, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 257, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); cards.add(new SetCardInfo("Prepared // Fight", 220, Rarity.RARE, mage.cards.p.PreparedFight.class)); + cards.add(new SetCardInfo("Prowling Serpopard", 180, Rarity.RARE, mage.cards.p.ProwlingSerpopard.class)); + cards.add(new SetCardInfo("Renewed Faith", 25, Rarity.UNCOMMON, mage.cards.r.RenewedFaith.class)); + cards.add(new SetCardInfo("Rhonas's Monument", 236, Rarity.UNCOMMON, mage.cards.r.RhonassMonument.class)); + cards.add(new SetCardInfo("Scattered Groves", 247, Rarity.RARE, mage.cards.s.ScatteredGroves.class)); + cards.add(new SetCardInfo("Scribe of the Mindful", 68, Rarity.COMMON, mage.cards.s.ScribeOfTheMindful.class)); + cards.add(new SetCardInfo("Sheltered Thicket", 248, Rarity.RARE, mage.cards.s.ShelteredThicket.class)); + cards.add(new SetCardInfo("Sixth Sense", 187, Rarity.UNCOMMON, mage.cards.s.SixthSense.class)); + cards.add(new SetCardInfo("Spidery Grasp", 188, Rarity.COMMON, mage.cards.s.SpideryGrasp.class)); + cards.add(new SetCardInfo("Splendid Agony", 109, Rarity.COMMON, mage.cards.s.SplendidAgony.class)); + cards.add(new SetCardInfo("Swamp", 252, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 261, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 262, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 263, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Tattered Mummy", 278, Rarity.COMMON, mage.cards.t.TatteredMummy.class)); + cards.add(new SetCardInfo("Trial of Knowledge", 73, Rarity.UNCOMMON, mage.cards.t.TrialOfKnowledge.class)); + } + + @Override + public List getSpecialLand() { + if (savedSpecialLand.isEmpty()) { + CardCriteria criteria = new CardCriteria(); + criteria.setCodes("MPS-AKH"); + criteria.minCardNumber(1); + criteria.maxCardNumber(30); + savedSpecialLand.addAll(CardRepository.instance.findCards(criteria)); + } + + return new ArrayList<>(savedSpecialLand); } } diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index 7883329e504..d4a474951f2 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -58,6 +58,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Darksteel Reactor", 114, Rarity.RARE, mage.cards.d.DarksteelReactor.class)); cards.add(new SetCardInfo("Death Cloud", 40, Rarity.RARE, mage.cards.d.DeathCloud.class)); cards.add(new SetCardInfo("Demon's Horn", 116, Rarity.UNCOMMON, mage.cards.d.DemonsHorn.class)); + cards.add(new SetCardInfo("Dismantle", 57, Rarity.UNCOMMON, mage.cards.d.Dismantle.class)); cards.add(new SetCardInfo("Dragon's Claw", 117, Rarity.UNCOMMON, mage.cards.d.DragonsClaw.class)); cards.add(new SetCardInfo("Drill-Skimmer", 118, Rarity.COMMON, mage.cards.d.DrillSkimmer.class)); cards.add(new SetCardInfo("Drooling Ogre", 58, Rarity.COMMON, mage.cards.d.DroolingOgre.class)); diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index 1dbbd6dbccd..f1d9450fbf1 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -73,6 +73,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Bound // Determined", 149, Rarity.RARE, mage.cards.b.BoundDetermined.class)); cards.add(new SetCardInfo("Brain Pry", 39, Rarity.UNCOMMON, mage.cards.b.BrainPry.class)); cards.add(new SetCardInfo("Breeding Pool", 172, Rarity.RARE, mage.cards.b.BreedingPool.class)); + cards.add(new SetCardInfo("Bronze Bombshell", 160, Rarity.RARE, mage.cards.b.BronzeBombshell.class)); cards.add(new SetCardInfo("Cackling Flames", 59, Rarity.COMMON, mage.cards.c.CacklingFlames.class)); cards.add(new SetCardInfo("Carom", 6, Rarity.COMMON, mage.cards.c.Carom.class)); cards.add(new SetCardInfo("Celestial Ancient", 7, Rarity.RARE, mage.cards.c.CelestialAncient.class)); diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index c8904941765..1605d5537f9 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -27,10 +27,10 @@ */ package mage.sets; -import mage.cards.CardGraphicInfo; import mage.cards.ExpansionSet; -import mage.constants.Rarity; import mage.constants.SetType; +import mage.constants.Rarity; +import mage.cards.CardGraphicInfo; /** * @@ -247,6 +247,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Soldevi Simulacrum", 314, Rarity.UNCOMMON, mage.cards.s.SoldeviSimulacrum.class)); cards.add(new SetCardInfo("Songs of the Damned", 48, Rarity.COMMON, mage.cards.s.SongsOfTheDamned.class)); cards.add(new SetCardInfo("Soul Barrier", 103, Rarity.UNCOMMON, mage.cards.s.SoulBarrier.class)); + cards.add(new SetCardInfo("Soul Burn", 361, Rarity.COMMON, mage.cards.s.SoulBurn.class)); cards.add(new SetCardInfo("Soul Kiss", 50, Rarity.COMMON, mage.cards.s.SoulKiss.class)); cards.add(new SetCardInfo("Spoils of Evil", 51, Rarity.RARE, mage.cards.s.SpoilsOfEvil.class)); cards.add(new SetCardInfo("Stampede", 153, Rarity.RARE, mage.cards.s.Stampede.class)); diff --git a/Mage.Sets/src/mage/sets/Invasion.java b/Mage.Sets/src/mage/sets/Invasion.java index e682d03e317..4099bbcccee 100644 --- a/Mage.Sets/src/mage/sets/Invasion.java +++ b/Mage.Sets/src/mage/sets/Invasion.java @@ -75,7 +75,6 @@ public class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Aura Mutation", 232, Rarity.RARE, mage.cards.a.AuraMutation.class)); cards.add(new SetCardInfo("Aura Shards", 233, Rarity.UNCOMMON, mage.cards.a.AuraShards.class)); cards.add(new SetCardInfo("Backlash", 234, Rarity.UNCOMMON, mage.cards.b.Backlash.class)); - cards.add(new SetCardInfo("Barrin's Spite", 235, Rarity.RARE, mage.cards.b.BarrinsSpite.class)); cards.add(new SetCardInfo("Benalish Emissary", 5, Rarity.UNCOMMON, mage.cards.b.BenalishEmissary.class)); cards.add(new SetCardInfo("Benalish Heralds", 6, Rarity.UNCOMMON, mage.cards.b.BenalishHeralds.class)); cards.add(new SetCardInfo("Benalish Lancer", 7, Rarity.COMMON, mage.cards.b.BenalishLancer.class)); @@ -287,6 +286,7 @@ public class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Slimy Kavu", 170, Rarity.COMMON, mage.cards.s.SlimyKavu.class)); cards.add(new SetCardInfo("Slinking Serpent", 274, Rarity.UNCOMMON, mage.cards.s.SlinkingSerpent.class)); cards.add(new SetCardInfo("Smoldering Tar", 275, Rarity.UNCOMMON, mage.cards.s.SmolderingTar.class)); + cards.add(new SetCardInfo("Soul Burn", 351, Rarity.COMMON, mage.cards.s.SoulBurn.class)); cards.add(new SetCardInfo("Sparring Golem", 312, Rarity.UNCOMMON, mage.cards.s.SparringGolem.class)); cards.add(new SetCardInfo("Spinal Embrace", 276, Rarity.RARE, mage.cards.s.SpinalEmbrace.class)); cards.add(new SetCardInfo("Spirit of Resistance", 38, Rarity.RARE, mage.cards.s.SpiritOfResistance.class)); diff --git a/Mage.Sets/src/mage/sets/LaunchParty.java b/Mage.Sets/src/mage/sets/LaunchParty.java index 9bd0bb0d6bb..13123cebec0 100644 --- a/Mage.Sets/src/mage/sets/LaunchParty.java +++ b/Mage.Sets/src/mage/sets/LaunchParty.java @@ -1,92 +1,93 @@ -/* -* 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.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author fireshoes - */ -public class LaunchParty extends ExpansionSet { - - private static final LaunchParty instance = new LaunchParty(); - - public static LaunchParty getInstance() { - return instance; - } - - private LaunchParty() { - super("Launch Party", "MLP", ExpansionSet.buildDate(2011, 6, 17), SetType.PROMOTIONAL); - this.hasBoosters = false; - this.hasBasicLands = false; - cards.add(new SetCardInfo("Ajani Vengeant", 4, Rarity.MYTHIC, mage.cards.a.AjaniVengeant.class)); - cards.add(new SetCardInfo("Ancient Hellkite", 11, Rarity.RARE, mage.cards.a.AncientHellkite.class)); - cards.add(new SetCardInfo("Angel of Deliverance", 35, Rarity.RARE, mage.cards.a.AngelOfDeliverance.class)); - cards.add(new SetCardInfo("Ant Queen", 7, Rarity.RARE, mage.cards.a.AntQueen.class)); - cards.add(new SetCardInfo("Bident of Thassa", 24, Rarity.RARE, mage.cards.b.BidentOfThassa.class)); - cards.add(new SetCardInfo("Blight Herder", 32, Rarity.RARE, mage.cards.b.BlightHerder.class)); - cards.add(new SetCardInfo("Breaking // Entering", 22, Rarity.RARE, mage.cards.b.BreakingEntering.class)); - cards.add(new SetCardInfo("Colossal Whale", 23, Rarity.RARE, mage.cards.c.ColossalWhale.class)); - cards.add(new SetCardInfo("Deadbridge Goliath", 20, Rarity.RARE, mage.cards.d.DeadbridgeGoliath.class)); - cards.add(new SetCardInfo("Deathbringer Regent", 30, Rarity.RARE, mage.cards.d.DeathbringerRegent.class)); - cards.add(new SetCardInfo("Dictate of the Twin Gods", 26, Rarity.RARE, mage.cards.d.DictateOfTheTwinGods.class)); - cards.add(new SetCardInfo("Dragon Throne of Tarkir", 27, Rarity.RARE, mage.cards.d.DragonThroneOfTarkir.class)); - cards.add(new SetCardInfo("Earwig Squad", 1, Rarity.RARE, mage.cards.e.EarwigSquad.class)); - cards.add(new SetCardInfo("Endbringer", 34, Rarity.RARE, mage.cards.e.Endbringer.class)); - cards.add(new SetCardInfo("Figure of Destiny", 3, Rarity.RARE, mage.cards.f.FigureOfDestiny.class)); - cards.add(new SetCardInfo("Garruk's Horde", 15, Rarity.RARE, mage.cards.g.GarruksHorde.class)); - cards.add(new SetCardInfo("Identity Thief", 33, Rarity.RARE, mage.cards.i.IdentityThief.class)); - cards.add(new SetCardInfo("In Garruk's Wake", 28, Rarity.RARE, mage.cards.i.InGarruksWake.class)); - cards.add(new SetCardInfo("Joraga Warcaller", 9, Rarity.RARE, mage.cards.j.JoragaWarcaller.class)); - cards.add(new SetCardInfo("Knight of New Alara", 6, Rarity.RARE, mage.cards.k.KnightOfNewAlara.class)); - cards.add(new SetCardInfo("Lord of Shatterskull Pass", 10, Rarity.RARE, mage.cards.l.LordOfShatterskullPass.class)); - cards.add(new SetCardInfo("Ludevic's Abomination", 1064, Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); - cards.add(new SetCardInfo("Ludevic's Test Subject", 16, Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); - cards.add(new SetCardInfo("Mizzium Meddler", 31, Rarity.RARE, mage.cards.m.MizziumMeddler.class)); - cards.add(new SetCardInfo("Mondronen Shaman", 17, Rarity.RARE, mage.cards.m.MondronenShaman.class)); - cards.add(new SetCardInfo("Obelisk of Alara", 5, Rarity.RARE, mage.cards.o.ObeliskOfAlara.class)); - cards.add(new SetCardInfo("Phyrexian Metamorph", 14, Rarity.RARE, mage.cards.p.PhyrexianMetamorph.class)); - cards.add(new SetCardInfo("Quicksmith Rebel", 38, Rarity.RARE, mage.cards.q.QuicksmithRebel.class)); - cards.add(new SetCardInfo("Restoration Angel", 18, Rarity.RARE, mage.cards.r.RestorationAngel.class)); - cards.add(new SetCardInfo("Saheeli's Artistry", 37, Rarity.RARE, mage.cards.s.SaheelisArtistry.class)); - cards.add(new SetCardInfo("Sandsteppe Mastodon", 29, Rarity.RARE, mage.cards.s.SandsteppeMastodon.class)); - cards.add(new SetCardInfo("Skarrg Goliath", 21, Rarity.RARE, mage.cards.s.SkarrgGoliath.class)); - cards.add(new SetCardInfo("Staff of Nin", 19, Rarity.RARE, mage.cards.s.StaffOfNin.class)); - cards.add(new SetCardInfo("Steel Hellkite", 12, Rarity.RARE, mage.cards.s.SteelHellkite.class)); - cards.add(new SetCardInfo("Thopter Assembly", 13, Rarity.RARE, mage.cards.t.ThopterAssembly.class)); - cards.add(new SetCardInfo("Tovolar's Magehunter", 98, Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); - cards.add(new SetCardInfo("Tromokratis", 25, Rarity.RARE, mage.cards.t.Tromokratis.class)); - cards.add(new SetCardInfo("Valakut, the Molten Pinnacle", 8, Rarity.RARE, mage.cards.v.ValakutTheMoltenPinnacle.class)); - cards.add(new SetCardInfo("Vexing Shusher", 2, Rarity.RARE, mage.cards.v.VexingShusher.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; + +/** + * + * @author fireshoes + */ +public class LaunchParty extends ExpansionSet { + + private static final LaunchParty instance = new LaunchParty(); + + public static LaunchParty getInstance() { + return instance; + } + + private LaunchParty() { + super("Launch Party", "MLP", ExpansionSet.buildDate(2011, 6, 17), SetType.PROMOTIONAL); + this.hasBoosters = false; + this.hasBasicLands = false; + cards.add(new SetCardInfo("Ajani Vengeant", 4, Rarity.MYTHIC, mage.cards.a.AjaniVengeant.class)); + cards.add(new SetCardInfo("Ancient Hellkite", 11, Rarity.RARE, mage.cards.a.AncientHellkite.class)); + cards.add(new SetCardInfo("Angel of Deliverance", 35, Rarity.RARE, mage.cards.a.AngelOfDeliverance.class)); + cards.add(new SetCardInfo("Ant Queen", 7, Rarity.RARE, mage.cards.a.AntQueen.class)); + cards.add(new SetCardInfo("Bident of Thassa", 24, Rarity.RARE, mage.cards.b.BidentOfThassa.class)); + cards.add(new SetCardInfo("Blight Herder", 32, Rarity.RARE, mage.cards.b.BlightHerder.class)); + cards.add(new SetCardInfo("Breaking // Entering", 22, Rarity.RARE, mage.cards.b.BreakingEntering.class)); + cards.add(new SetCardInfo("Colossal Whale", 23, Rarity.RARE, mage.cards.c.ColossalWhale.class)); + cards.add(new SetCardInfo("Deadbridge Goliath", 20, Rarity.RARE, mage.cards.d.DeadbridgeGoliath.class)); + cards.add(new SetCardInfo("Deathbringer Regent", 30, Rarity.RARE, mage.cards.d.DeathbringerRegent.class)); + cards.add(new SetCardInfo("Dictate of the Twin Gods", 26, Rarity.RARE, mage.cards.d.DictateOfTheTwinGods.class)); + cards.add(new SetCardInfo("Dragon Throne of Tarkir", 27, Rarity.RARE, mage.cards.d.DragonThroneOfTarkir.class)); + cards.add(new SetCardInfo("Earwig Squad", 1, Rarity.RARE, mage.cards.e.EarwigSquad.class)); + cards.add(new SetCardInfo("Endbringer", 34, Rarity.RARE, mage.cards.e.Endbringer.class)); + cards.add(new SetCardInfo("Figure of Destiny", 3, Rarity.RARE, mage.cards.f.FigureOfDestiny.class)); + cards.add(new SetCardInfo("Garruk's Horde", 15, Rarity.RARE, mage.cards.g.GarruksHorde.class)); + cards.add(new SetCardInfo("Identity Thief", 33, Rarity.RARE, mage.cards.i.IdentityThief.class)); + cards.add(new SetCardInfo("In Garruk's Wake", 28, Rarity.RARE, mage.cards.i.InGarruksWake.class)); + cards.add(new SetCardInfo("Joraga Warcaller", 9, Rarity.RARE, mage.cards.j.JoragaWarcaller.class)); + cards.add(new SetCardInfo("Knight of New Alara", 6, Rarity.RARE, mage.cards.k.KnightOfNewAlara.class)); + cards.add(new SetCardInfo("Lord of Shatterskull Pass", 10, Rarity.RARE, mage.cards.l.LordOfShatterskullPass.class)); + cards.add(new SetCardInfo("Ludevic's Abomination", 1064, Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); + cards.add(new SetCardInfo("Ludevic's Test Subject", 16, Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); + cards.add(new SetCardInfo("Mizzium Meddler", 31, Rarity.RARE, mage.cards.m.MizziumMeddler.class)); + cards.add(new SetCardInfo("Mondronen Shaman", 17, Rarity.RARE, mage.cards.m.MondronenShaman.class)); + cards.add(new SetCardInfo("Obelisk of Alara", 5, Rarity.RARE, mage.cards.o.ObeliskOfAlara.class)); + cards.add(new SetCardInfo("Oracle's Vault", 39, Rarity.RARE, mage.cards.o.OraclesVault.class)); + cards.add(new SetCardInfo("Phyrexian Metamorph", 14, Rarity.RARE, mage.cards.p.PhyrexianMetamorph.class)); + cards.add(new SetCardInfo("Quicksmith Rebel", 38, Rarity.RARE, mage.cards.q.QuicksmithRebel.class)); + cards.add(new SetCardInfo("Restoration Angel", 18, Rarity.RARE, mage.cards.r.RestorationAngel.class)); + cards.add(new SetCardInfo("Saheeli's Artistry", 37, Rarity.RARE, mage.cards.s.SaheelisArtistry.class)); + cards.add(new SetCardInfo("Sandsteppe Mastodon", 29, Rarity.RARE, mage.cards.s.SandsteppeMastodon.class)); + cards.add(new SetCardInfo("Skarrg Goliath", 21, Rarity.RARE, mage.cards.s.SkarrgGoliath.class)); + cards.add(new SetCardInfo("Staff of Nin", 19, Rarity.RARE, mage.cards.s.StaffOfNin.class)); + cards.add(new SetCardInfo("Steel Hellkite", 12, Rarity.RARE, mage.cards.s.SteelHellkite.class)); + cards.add(new SetCardInfo("Thopter Assembly", 13, Rarity.RARE, mage.cards.t.ThopterAssembly.class)); + cards.add(new SetCardInfo("Tovolar's Magehunter", 98, Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); + cards.add(new SetCardInfo("Tromokratis", 25, Rarity.RARE, mage.cards.t.Tromokratis.class)); + cards.add(new SetCardInfo("Valakut, the Molten Pinnacle", 8, Rarity.RARE, mage.cards.v.ValakutTheMoltenPinnacle.class)); + cards.add(new SetCardInfo("Vexing Shusher", 2, Rarity.RARE, mage.cards.v.VexingShusher.class)); + } + +} diff --git a/Mage.Sets/src/mage/sets/MasterpieceSeries.java b/Mage.Sets/src/mage/sets/MasterpieceSeries.java index 16996b94917..affbb7260e2 100644 --- a/Mage.Sets/src/mage/sets/MasterpieceSeries.java +++ b/Mage.Sets/src/mage/sets/MasterpieceSeries.java @@ -47,6 +47,7 @@ public class MasterpieceSeries extends ExpansionSet { private MasterpieceSeries() { super("Masterpiece Series", "MPS", ExpansionSet.buildDate(2016, 9, 30), SetType.PROMOTIONAL); + this.blockName = "Masterpiece Series"; this.hasBoosters = false; this.hasBasicLands = false; CardGraphicInfo cardGraphicInfo = new CardGraphicInfo(FrameStyle.KLD_INVENTION, false); diff --git a/Mage.Sets/src/mage/sets/MasterpieceSeriesAmonkhet.java b/Mage.Sets/src/mage/sets/MasterpieceSeriesAmonkhet.java new file mode 100644 index 00000000000..6798cc2400a --- /dev/null +++ b/Mage.Sets/src/mage/sets/MasterpieceSeriesAmonkhet.java @@ -0,0 +1,82 @@ +/* + * 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.cards.CardGraphicInfo; +import mage.cards.ExpansionSet; +import mage.cards.FrameStyle; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author fireshoes + */ +public class MasterpieceSeriesAmonkhet extends ExpansionSet { + + private static final MasterpieceSeriesAmonkhet instance = new MasterpieceSeriesAmonkhet(); + + public static MasterpieceSeriesAmonkhet getInstance() { + return instance; + } + + private MasterpieceSeriesAmonkhet() { + super("Masterpiece Series Amonkhet", "MPS-AKH", ExpansionSet.buildDate(2017, 4, 28), SetType.PROMOTIONAL); + this.blockName = "Masterpiece Series"; + this.hasBoosters = false; + this.hasBasicLands = false; + CardGraphicInfo cardGraphicInfo = new CardGraphicInfo(FrameStyle.KLD_INVENTION, false); + + cards.add(new SetCardInfo("Aggravated Assault", 25, Rarity.SPECIAL, mage.cards.a.AggravatedAssault.class)); + cards.add(new SetCardInfo("Attrition", 19, Rarity.SPECIAL, mage.cards.a.Attrition.class)); + cards.add(new SetCardInfo("Austere Command", 1, Rarity.SPECIAL, mage.cards.a.AustereCommand.class)); + cards.add(new SetCardInfo("Aven Mindcensor", 2, Rarity.SPECIAL, mage.cards.a.AvenMindcensor.class)); + cards.add(new SetCardInfo("Chain Lightning", 26, Rarity.SPECIAL, mage.cards.c.ChainLightning.class)); + cards.add(new SetCardInfo("Consecrated Sphinx", 8, Rarity.SPECIAL, mage.cards.c.ConsecratedSphinx.class)); + cards.add(new SetCardInfo("Containment Priest", 3, Rarity.SPECIAL, mage.cards.c.ContainmentPriest.class)); + cards.add(new SetCardInfo("Counterbalance", 9, Rarity.SPECIAL, mage.cards.c.Counterbalance.class)); + cards.add(new SetCardInfo("Counterspell", 10, Rarity.SPECIAL, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Cryptic Command", 11, Rarity.SPECIAL, mage.cards.c.CrypticCommand.class)); + cards.add(new SetCardInfo("Dark Ritual", 21, Rarity.SPECIAL, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Daze", 12, Rarity.SPECIAL, mage.cards.d.Daze.class)); + cards.add(new SetCardInfo("Diabolic Intent", 22, Rarity.SPECIAL, mage.cards.d.DiabolicIntent.class)); + cards.add(new SetCardInfo("Divert", 13, Rarity.SPECIAL, mage.cards.d.Divert.class)); + cards.add(new SetCardInfo("Entomb", 23, Rarity.SPECIAL, mage.cards.e.Entomb.class)); + cards.add(new SetCardInfo("Force of Will", 14, Rarity.SPECIAL, mage.cards.f.ForceOfWill.class)); + cards.add(new SetCardInfo("Hazoret the Fervent", 27, Rarity.SPECIAL, mage.cards.h.HazoretTheFervent.class)); + cards.add(new SetCardInfo("Loyal Retainers", 4, Rarity.SPECIAL, mage.cards.l.LoyalRetainers.class)); + cards.add(new SetCardInfo("Maelstrom Pulse", 29, Rarity.SPECIAL, mage.cards.m.MaelstromPulse.class)); + cards.add(new SetCardInfo("Mind Twist", 24, Rarity.SPECIAL, mage.cards.m.MindTwist.class)); + cards.add(new SetCardInfo("Pact of Negation", 16, Rarity.SPECIAL, mage.cards.p.PactOfNegation.class)); + cards.add(new SetCardInfo("Spell Pierce", 17, Rarity.SPECIAL, mage.cards.s.SpellPierce.class)); + cards.add(new SetCardInfo("Stifle", 18, Rarity.SPECIAL, mage.cards.s.Stifle.class)); + cards.add(new SetCardInfo("Vindicate", 30, Rarity.SPECIAL, mage.cards.v.Vindicate.class)); + cards.add(new SetCardInfo("Worship", 6, Rarity.SPECIAL, mage.cards.w.Worship.class)); + cards.add(new SetCardInfo("Wrath of God", 7, Rarity.SPECIAL, mage.cards.w.WrathOfGod.class)); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/MediaInserts.java b/Mage.Sets/src/mage/sets/MediaInserts.java index 9a0d085ff7a..267eaa48dde 100644 --- a/Mage.Sets/src/mage/sets/MediaInserts.java +++ b/Mage.Sets/src/mage/sets/MediaInserts.java @@ -1,221 +1,222 @@ -/* - * 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.cards.CardGraphicInfo; -import mage.cards.ExpansionSet; -import mage.cards.h.HighTide; -import mage.constants.Rarity; -import mage.constants.SetType; - -public class MediaInserts extends ExpansionSet { - - private static final MediaInserts instance = new MediaInserts(); - - public static MediaInserts getInstance() { - return instance; - } - - private MediaInserts() { - super("Media Inserts", "MBP", ExpansionSet.buildDate(1990, 1, 1), SetType.PROMOTIONAL); - this.hasBoosters = false; - this.hasBasicLands = false; - cards.add(new SetCardInfo("Acquire", 83, Rarity.RARE, mage.cards.a.Acquire.class)); - cards.add(new SetCardInfo("Aeronaut Tinkerer", 118, Rarity.COMMON, mage.cards.a.AeronautTinkerer.class)); - cards.add(new SetCardInfo("Ajani, Caller of the Pride", 72, Rarity.MYTHIC, mage.cards.a.AjaniCallerOfThePride.class)); - cards.add(new SetCardInfo("Ajani Steadfast", 99, Rarity.MYTHIC, mage.cards.a.AjaniSteadfast.class)); - cards.add(new SetCardInfo("Alhammarret, High Arbiter", 124, Rarity.SPECIAL, mage.cards.a.AlhammarretHighArbiter.class)); - cards.add(new SetCardInfo("Angelic Skirmisher", 90, Rarity.RARE, mage.cards.a.AngelicSkirmisher.class)); - cards.add(new SetCardInfo("Angel of Glory's Rise", 59, Rarity.RARE, mage.cards.a.AngelOfGlorysRise.class)); - cards.add(new SetCardInfo("Ankle Shanker", 93, Rarity.RARE, mage.cards.a.AnkleShanker.class)); - cards.add(new SetCardInfo("Arashin Sovereign", 112, Rarity.SPECIAL, mage.cards.a.ArashinSovereign.class)); - cards.add(new SetCardInfo("Archfiend of Depravity", 109, Rarity.SPECIAL, mage.cards.a.ArchfiendOfDepravity.class)); - cards.add(new SetCardInfo("Arena", 1, Rarity.SPECIAL, mage.cards.a.Arena.class)); - cards.add(new SetCardInfo("Arrest", 53, Rarity.COMMON, mage.cards.a.Arrest.class)); - cards.add(new SetCardInfo("Assembled Alphas", 160, Rarity.RARE, mage.cards.a.AssembledAlphas.class)); - cards.add(new SetCardInfo("Avalanche Tusker", 94, Rarity.RARE, mage.cards.a.AvalancheTusker.class)); - cards.add(new SetCardInfo("Barrage Tyrant", 139, Rarity.SPECIAL, mage.cards.b.BarrageTyrant.class)); - cards.add(new SetCardInfo("Birds of Paradise", 28, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); - cards.add(new SetCardInfo("Bloodthrone Vampire", 31, Rarity.COMMON, mage.cards.b.BloodthroneVampire.class)); - cards.add(new SetCardInfo("Blue Elemental Blast", 5, Rarity.COMMON, mage.cards.b.BlueElementalBlast.class)); - cards.add(new SetCardInfo("Boltwing Marauder", 115, Rarity.SPECIAL, mage.cards.b.BoltwingMarauder.class)); - cards.add(new SetCardInfo("Bonescythe Sliver", 68, Rarity.RARE, mage.cards.b.BonescytheSliver.class)); - cards.add(new SetCardInfo("Breath of Malfegor", 58, Rarity.COMMON, mage.cards.b.BreathOfMalfegor.class)); - cards.add(new SetCardInfo("Brion Stoutarm", 17, Rarity.RARE, mage.cards.b.BrionStoutarm.class)); - cards.add(new SetCardInfo("Broodmate Dragon", 19, Rarity.RARE, mage.cards.b.BroodmateDragon.class)); - cards.add(new SetCardInfo("Cathedral of War", 51, Rarity.RARE, mage.cards.c.CathedralOfWar.class)); - cards.add(new SetCardInfo("Celestial Colonnade", 23, Rarity.SPECIAL, mage.cards.c.CelestialColonnade.class)); - cards.add(new SetCardInfo("Chandra, Fire of Kaladesh", 997, Rarity.SPECIAL, mage.cards.c.ChandraFireOfKaladesh.class)); - cards.add(new SetCardInfo("Chandra, Pyromaster", 75, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class)); - cards.add(new SetCardInfo("Chandra, Pyromaster", 102, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Chandra, Roaring Flame", 997, Rarity.SPECIAL, mage.cards.c.ChandraRoaringFlame.class)); - cards.add(new SetCardInfo("Chandra's Fury", 65, Rarity.COMMON, mage.cards.c.ChandrasFury.class)); - cards.add(new SetCardInfo("Chandra's Phoenix", 37, Rarity.RARE, mage.cards.c.ChandrasPhoenix.class)); - cards.add(new SetCardInfo("Consume Spirit", 54, Rarity.UNCOMMON, mage.cards.c.ConsumeSpirit.class)); - cards.add(new SetCardInfo("Corrupt", 64, Rarity.UNCOMMON, mage.cards.c.Corrupt.class)); - cards.add(new SetCardInfo("Day of Judgment", 22, Rarity.RARE, mage.cards.d.DayOfJudgment.class)); - cards.add(new SetCardInfo("Deepfathom Skulker", 144, Rarity.RARE, mage.cards.d.DeepfathomSkulker.class)); - cards.add(new SetCardInfo("Defiant Bloodlord", 138, Rarity.SPECIAL, mage.cards.d.DefiantBloodlord.class)); - cards.add(new SetCardInfo("Devil's Play", 40, Rarity.RARE, mage.cards.d.DevilsPlay.class)); - cards.add(new SetCardInfo("Dragon Fodder", 119, Rarity.COMMON, mage.cards.d.DragonFodder.class)); - cards.add(new SetCardInfo("Dragonlord's Servant", 120, Rarity.SPECIAL, mage.cards.d.DragonlordsServant.class)); - cards.add(new SetCardInfo("Dragonscale General", 107, Rarity.SPECIAL, mage.cards.d.DragonscaleGeneral.class)); - cards.add(new SetCardInfo("Dread Defiler", 145, Rarity.RARE, mage.cards.d.DreadDefiler.class)); - cards.add(new SetCardInfo("Dreg Mangler", 55, Rarity.UNCOMMON, mage.cards.d.DregMangler.class)); - cards.add(new SetCardInfo("Drogskol Cavalry", 149, Rarity.RARE, mage.cards.d.DrogskolCavalry.class)); - cards.add(new SetCardInfo("Dromoka, the Eternal", 132, Rarity.SPECIAL, mage.cards.d.DromokaTheEternal.class)); - cards.add(new SetCardInfo("Drowner of Hope", 137, Rarity.SPECIAL, mage.cards.d.DrownerOfHope.class)); - cards.add(new SetCardInfo("Duress", 84, Rarity.COMMON, mage.cards.d.Duress.class)); - cards.add(new SetCardInfo("Dwynen, Gilt-Leaf Daen", 125, Rarity.SPECIAL, mage.cards.d.DwynenGiltLeafDaen.class)); - cards.add(new SetCardInfo("Eidolon of Blossoms", 85, Rarity.RARE, mage.cards.e.EidolonOfBlossoms.class)); - cards.add(new SetCardInfo("Electrolyze", 42, Rarity.UNCOMMON, mage.cards.e.Electrolyze.class)); - cards.add(new SetCardInfo("Elusive Tormentor", 154, Rarity.RARE, mage.cards.e.ElusiveTormentor.class)); - cards.add(new SetCardInfo("Emrakul, the Aeons Torn", 163, Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); - cards.add(new SetCardInfo("Evolving Wilds", 121, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); - cards.add(new SetCardInfo("Faithless Looting", 39, Rarity.COMMON, mage.cards.f.FaithlessLooting.class)); - cards.add(new SetCardInfo("Fated Conflagration", 79, Rarity.RARE, mage.cards.f.FatedConflagration.class)); - cards.add(new SetCardInfo("Feast of Blood", 43, Rarity.UNCOMMON, mage.cards.f.FeastOfBlood.class)); - cards.add(new SetCardInfo("Fireball", 4, Rarity.COMMON, mage.cards.f.Fireball.class)); - cards.add(new SetCardInfo("Flameblade Angel", 152, Rarity.RARE, mage.cards.f.FlamebladeAngel.class)); - cards.add(new SetCardInfo("Flamerush Rider", 110, Rarity.SPECIAL, mage.cards.f.FlamerushRider.class)); - cards.add(new SetCardInfo("Foe-Razer Regent", 122, Rarity.SPECIAL, mage.cards.f.FoeRazerRegent.class)); - cards.add(new SetCardInfo("Frost Titan", 34, Rarity.MYTHIC, mage.cards.f.FrostTitan.class)); - cards.add(new SetCardInfo("Garruk, Apex Predator", 104, Rarity.MYTHIC, mage.cards.g.GarrukApexPredator.class)); - cards.add(new SetCardInfo("Garruk, Caller of Beasts", 76, Rarity.MYTHIC, mage.cards.g.GarrukCallerOfBeasts.class)); - cards.add(new SetCardInfo("Garruk Wildspeaker", 16, Rarity.RARE, mage.cards.g.GarrukWildspeaker.class)); - cards.add(new SetCardInfo("Gaze of Granite", 81, Rarity.RARE, mage.cards.g.GazeOfGranite.class)); - cards.add(new SetCardInfo("Genesis Hydra", 142, Rarity.SPECIAL, mage.cards.g.GenesisHydra.class)); - cards.add(new SetCardInfo("Giant Badger", 8, Rarity.SPECIAL, mage.cards.g.GiantBadger.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", 994, Rarity.SPECIAL, mage.cards.g.GideonBattleForged.class)); - cards.add(new SetCardInfo("Gladehart Cavalry", 147, Rarity.RARE, mage.cards.g.GladehartCavalry.class)); - cards.add(new SetCardInfo("Goblin Dark-Dwellers", 148, Rarity.RARE, mage.cards.g.GoblinDarkDwellers.class)); - cards.add(new SetCardInfo("Goblin Rabblemaster", 98, Rarity.RARE, mage.cards.g.GoblinRabblemaster.class)); - cards.add(new SetCardInfo("Gravecrawler", 41, Rarity.RARE, mage.cards.g.Gravecrawler.class)); - cards.add(new SetCardInfo("Grave Titan", 35, Rarity.MYTHIC, mage.cards.g.GraveTitan.class)); - cards.add(new SetCardInfo("Guul Draz Assassin", 26, Rarity.RARE, mage.cards.g.GuulDrazAssassin.class)); - cards.add(new SetCardInfo("Hamletback Goliath", 71, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); - cards.add(new SetCardInfo("Harbinger of the Hunt", 116, Rarity.SPECIAL, mage.cards.h.HarbingerOfTheHunt.class)); - cards.add(new SetCardInfo("Hero of Goma Fada", 136, Rarity.SPECIAL, mage.cards.h.HeroOfGomaFada.class)); - cards.add(new SetCardInfo("High Tide", 80, Rarity.COMMON, HighTide.class)); - cards.add(new SetCardInfo("Hixus, Prison Warden", 126, Rarity.SPECIAL, mage.cards.h.HixusPrisonWarden.class)); - cards.add(new SetCardInfo("Honored Hierarch", 129, Rarity.SPECIAL, mage.cards.h.HonoredHierarch.class)); - cards.add(new SetCardInfo("Honor of the Pure", 20, Rarity.RARE, mage.cards.h.HonorOfThePure.class)); - cards.add(new SetCardInfo("Inferno Titan", 36, Rarity.MYTHIC, mage.cards.i.InfernoTitan.class)); - cards.add(new SetCardInfo("Insidious Mist", 154, Rarity.RARE, mage.cards.i.InsidiousMist.class)); - cards.add(new SetCardInfo("Ivorytusk Fortress", 95, Rarity.RARE, mage.cards.i.IvorytuskFortress.class)); - cards.add(new SetCardInfo("Jace Beleren", 15, Rarity.RARE, mage.cards.j.JaceBeleren.class)); - cards.add(new SetCardInfo("Jace, Memory Adept", 73, Rarity.MYTHIC, mage.cards.j.JaceMemoryAdept.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", 995, Rarity.SPECIAL, mage.cards.j.JaceTelepathUnbound.class)); - cards.add(new SetCardInfo("Jace, the Living Guildpact", 100, Rarity.MYTHIC, mage.cards.j.JaceTheLivingGuildpact.class)); - cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 995, Rarity.SPECIAL, mage.cards.j.JaceVrynsProdigy.class)); - cards.add(new SetCardInfo("Jaya Ballard, Task Mage", 18, Rarity.RARE, mage.cards.j.JayaBallardTaskMage.class)); - cards.add(new SetCardInfo("Karametra's Acolyte", 78, Rarity.UNCOMMON, mage.cards.k.KarametrasAcolyte.class)); - cards.add(new SetCardInfo("Knight Exemplar", 46, Rarity.RARE, mage.cards.k.KnightExemplar.class)); - cards.add(new SetCardInfo("Kor Skyfisher", 25, Rarity.COMMON, mage.cards.k.KorSkyfisher.class)); - cards.add(new SetCardInfo("Kothophed, Soul Hoarder", 127, Rarity.SPECIAL, mage.cards.k.KothophedSoulHoarder.class)); - cards.add(new SetCardInfo("Kytheon, Hero of Akros", 994, Rarity.SPECIAL, mage.cards.k.KytheonHeroOfAkros.class)); - cards.add(new SetCardInfo("Lightning Hounds", 10, Rarity.SPECIAL, mage.cards.l.LightningHounds.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 996, Rarity.SPECIAL, mage.cards.l.LilianaDefiantNecromancer.class)); - cards.add(new SetCardInfo("Liliana, Heretical Healer", 996, Rarity.SPECIAL, mage.cards.l.LilianaHereticalHealer.class)); - cards.add(new SetCardInfo("Liliana of the Dark Realms", 74, Rarity.MYTHIC, mage.cards.l.LilianaOfTheDarkRealms.class)); - cards.add(new SetCardInfo("Liliana Vess", 30, Rarity.RARE, mage.cards.l.LilianaVess.class)); - cards.add(new SetCardInfo("Liliana Vess", 101, Rarity.MYTHIC, mage.cards.l.LilianaVess.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Magister of Worth", 86, Rarity.SPECIAL, mage.cards.m.MagisterOfWorth.class)); - cards.add(new SetCardInfo("Mana Crypt", 6, Rarity.RARE, mage.cards.m.ManaCrypt.class)); - cards.add(new SetCardInfo("Markov Dreadknight", 151, Rarity.RARE, mage.cards.m.MarkovDreadknight.class)); - cards.add(new SetCardInfo("Memoricide", 29, Rarity.RARE, mage.cards.m.Memoricide.class)); - cards.add(new SetCardInfo("Merfolk Mesmerist", 45, Rarity.COMMON, mage.cards.m.MerfolkMesmerist.class)); - cards.add(new SetCardInfo("Mirran Crusader", 32, Rarity.RARE, mage.cards.m.MirranCrusader.class)); - cards.add(new SetCardInfo("Munda's Vanguard", 143, Rarity.RARE, mage.cards.m.MundasVanguard.class)); - cards.add(new SetCardInfo("Necromaster Dragon", 114, Rarity.SPECIAL, mage.cards.n.NecromasterDragon.class)); - cards.add(new SetCardInfo("Nephalia Moondrakes", 150, Rarity.RARE, mage.cards.n.NephaliaMoondrakes.class)); - cards.add(new SetCardInfo("Niblis of Frost", 158, Rarity.RARE, mage.cards.n.NiblisOfFrost.class)); - cards.add(new SetCardInfo("Nightveil Specter", 61, Rarity.RARE, mage.cards.n.NightveilSpecter.class)); - cards.add(new SetCardInfo("Nissa Revane", 27, Rarity.MYTHIC, mage.cards.n.NissaRevane.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", 998, Rarity.SPECIAL, mage.cards.n.NissaSageAnimist.class)); - cards.add(new SetCardInfo("Nissa, Vastwood Seer", 998, Rarity.SPECIAL, mage.cards.n.NissaVastwoodSeer.class)); - cards.add(new SetCardInfo("Nissa, Worldwaker", 103, Rarity.MYTHIC, mage.cards.n.NissaWorldwaker.class)); - cards.add(new SetCardInfo("Noosegraf Mob", 159, Rarity.RARE, mage.cards.n.NoosegrafMob.class)); - cards.add(new SetCardInfo("Ogre Arsonist", 63, Rarity.SPECIAL, mage.cards.o.OgreArsonist.class)); - cards.add(new SetCardInfo("Ogre Battledriver", 69, Rarity.RARE, mage.cards.o.OgreBattledriver.class)); - cards.add(new SetCardInfo("Ojutai's Command", 106, Rarity.SPECIAL, mage.cards.o.OjutaisCommand.class)); - cards.add(new SetCardInfo("Oran-Rief Hydra", 140, Rarity.SPECIAL, mage.cards.o.OranRiefHydra.class)); - cards.add(new SetCardInfo("Phyrexian Rager", 14, Rarity.COMMON, mage.cards.p.PhyrexianRager.class)); - cards.add(new SetCardInfo("Pia and Kiran Nalaar", 128, Rarity.SPECIAL, mage.cards.p.PiaAndKiranNalaar.class)); - cards.add(new SetCardInfo("Primordial Hydra", 49, Rarity.MYTHIC, mage.cards.p.PrimordialHydra.class)); - cards.add(new SetCardInfo("Pristine Skywise", 113, Rarity.SPECIAL, mage.cards.p.PristineSkywise.class)); - cards.add(new SetCardInfo("Rakshasa Vizier", 96, Rarity.RARE, mage.cards.r.RakshasaVizier.class)); - cards.add(new SetCardInfo("Ratchet Bomb", 67, Rarity.RARE, mage.cards.r.RatchetBomb.class)); - cards.add(new SetCardInfo("Rattleclaw Mystic", 92, Rarity.RARE, mage.cards.r.RattleclawMystic.class)); - cards.add(new SetCardInfo("Ravenous Bloodseeker", 155, Rarity.UNCOMMON, mage.cards.r.RavenousBloodseeker.class)); - cards.add(new SetCardInfo("Relic Seeker", 123, Rarity.RARE, mage.cards.r.RelicSeeker.class)); - cards.add(new SetCardInfo("Render Silent", 66, Rarity.RARE, mage.cards.r.RenderSilent.class)); - cards.add(new SetCardInfo("Retaliator Griffin", 24, Rarity.RARE, mage.cards.r.RetaliatorGriffin.class)); - cards.add(new SetCardInfo("Ruinous Path", 135, Rarity.SPECIAL, mage.cards.r.RuinousPath.class)); - cards.add(new SetCardInfo("Sage-Eye Avengers", 108, Rarity.SPECIAL, mage.cards.s.SageEyeAvengers.class)); - cards.add(new SetCardInfo("Sage of the Inward Eye", 97, Rarity.RARE, mage.cards.s.SageOfTheInwardEye.class)); - cards.add(new SetCardInfo("Sanctifier of Souls", 157, Rarity.RARE, mage.cards.s.SanctifierOfSouls.class)); - cards.add(new SetCardInfo("Sandsteppe Citadel", 134, Rarity.SPECIAL, mage.cards.s.SandsteppeCitadel.class)); - cards.add(new SetCardInfo("Scavenging Ooze", 70, Rarity.RARE, mage.cards.s.ScavengingOoze.class)); - cards.add(new SetCardInfo("Scrap Trawler", 164, Rarity.RARE, mage.cards.s.ScrapTrawler.class)); - cards.add(new SetCardInfo("Scythe Leopard", 141, Rarity.SPECIAL, mage.cards.s.ScytheLeopard.class)); - cards.add(new SetCardInfo("Seeker of the Way", 130, Rarity.SPECIAL, mage.cards.s.SeekerOfTheWay.class)); - cards.add(new SetCardInfo("Serra Avatar", 48, Rarity.MYTHIC, mage.cards.s.SerraAvatar.class)); - cards.add(new SetCardInfo("Shamanic Revelation", 105, Rarity.SPECIAL, mage.cards.s.ShamanicRevelation.class)); - cards.add(new SetCardInfo("Siege Rhino", 133, Rarity.SPECIAL, mage.cards.s.SiegeRhino.class)); - cards.add(new SetCardInfo("Silverblade Paladin", 44, Rarity.RARE, mage.cards.s.SilverbladePaladin.class)); - cards.add(new SetCardInfo("Silver Drake", 13, Rarity.SPECIAL, mage.cards.s.SilverDrake.class)); - cards.add(new SetCardInfo("Skyship Stalker", 162, Rarity.RARE, mage.cards.s.SkyshipStalker.class)); - cards.add(new SetCardInfo("Soul of Ravnica", 87, Rarity.MYTHIC, mage.cards.s.SoulOfRavnica.class)); - cards.add(new SetCardInfo("Soul of Zendikar", 88, Rarity.MYTHIC, mage.cards.s.SoulOfZendikar.class)); - cards.add(new SetCardInfo("Soul Swallower", 153, Rarity.RARE, mage.cards.s.SoulSwallower.class)); - cards.add(new SetCardInfo("Spined Wurm", 11, Rarity.SPECIAL, mage.cards.s.SpinedWurm.class)); - cards.add(new SetCardInfo("Standstill", 57, Rarity.UNCOMMON, mage.cards.s.Standstill.class)); - cards.add(new SetCardInfo("Stealer of Secrets", 89, Rarity.COMMON, mage.cards.s.StealerOfSecrets.class)); - cards.add(new SetCardInfo("Steward of Valeron", 21, Rarity.COMMON, mage.cards.s.StewardOfValeron.class)); - cards.add(new SetCardInfo("Sultai Charm", 117, Rarity.SPECIAL, mage.cards.s.SultaiCharm.class)); - cards.add(new SetCardInfo("Sunblast Angel", 47, Rarity.RARE, mage.cards.s.SunblastAngel.class)); - cards.add(new SetCardInfo("Supreme Verdict", 56, Rarity.RARE, mage.cards.s.SupremeVerdict.class)); - cards.add(new SetCardInfo("Surgical Extraction", 33, Rarity.RARE, mage.cards.s.SurgicalExtraction.class)); - cards.add(new SetCardInfo("Sylvan Caryatid", 77, Rarity.RARE, mage.cards.s.SylvanCaryatid.class)); - cards.add(new SetCardInfo("Temur War Shaman", 111, Rarity.SPECIAL, mage.cards.t.TemurWarShaman.class)); - cards.add(new SetCardInfo("Terastodon", 52, Rarity.RARE, mage.cards.t.Terastodon.class)); - cards.add(new SetCardInfo("Thalia, Heretic Cathar", 156, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class)); - cards.add(new SetCardInfo("Treasure Hunt", 38, Rarity.COMMON, mage.cards.t.TreasureHunt.class)); - cards.add(new SetCardInfo("Turnabout", 60, Rarity.UNCOMMON, mage.cards.t.Turnabout.class)); - cards.add(new SetCardInfo("Tyrant of Valakut", 146, Rarity.RARE, mage.cards.t.TyrantOfValakut.class)); - cards.add(new SetCardInfo("Ulvenwald Observer", 161, Rarity.RARE, mage.cards.u.UlvenwaldObserver.class)); - cards.add(new SetCardInfo("Valorous Stance", 131, Rarity.SPECIAL, mage.cards.v.ValorousStance.class)); - cards.add(new SetCardInfo("Vampire Nocturnus", 50, Rarity.MYTHIC, mage.cards.v.VampireNocturnus.class)); - cards.add(new SetCardInfo("Voidmage Husher", 62, Rarity.SPECIAL, mage.cards.v.VoidmageHusher.class)); - cards.add(new SetCardInfo("Warmonger", 12, Rarity.SPECIAL, mage.cards.w.Warmonger.class)); - cards.add(new SetCardInfo("Wash Out", 82, Rarity.UNCOMMON, mage.cards.w.WashOut.class)); - cards.add(new SetCardInfo("Windseeker Centaur", 7, Rarity.SPECIAL, mage.cards.w.WindseekerCentaur.class)); - cards.add(new SetCardInfo("Xathrid Necromancer", 91, Rarity.SPECIAL, mage.cards.x.XathridNecromancer.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.cards.CardGraphicInfo; +import mage.cards.ExpansionSet; +import mage.cards.h.HighTide; +import mage.constants.Rarity; +import mage.constants.SetType; + +public class MediaInserts extends ExpansionSet { + + private static final MediaInserts instance = new MediaInserts(); + + public static MediaInserts getInstance() { + return instance; + } + + private MediaInserts() { + super("Media Inserts", "MBP", ExpansionSet.buildDate(1990, 1, 1), SetType.PROMOTIONAL); + this.hasBoosters = false; + this.hasBasicLands = false; + cards.add(new SetCardInfo("Acquire", 83, Rarity.RARE, mage.cards.a.Acquire.class)); + cards.add(new SetCardInfo("Aeronaut Tinkerer", 118, Rarity.COMMON, mage.cards.a.AeronautTinkerer.class)); + cards.add(new SetCardInfo("Ajani, Caller of the Pride", 72, Rarity.MYTHIC, mage.cards.a.AjaniCallerOfThePride.class)); + cards.add(new SetCardInfo("Ajani Steadfast", 99, Rarity.MYTHIC, mage.cards.a.AjaniSteadfast.class)); + cards.add(new SetCardInfo("Alhammarret, High Arbiter", 124, Rarity.SPECIAL, mage.cards.a.AlhammarretHighArbiter.class)); + cards.add(new SetCardInfo("Angelic Skirmisher", 90, Rarity.RARE, mage.cards.a.AngelicSkirmisher.class)); + cards.add(new SetCardInfo("Angel of Glory's Rise", 59, Rarity.RARE, mage.cards.a.AngelOfGlorysRise.class)); + cards.add(new SetCardInfo("Ankle Shanker", 93, Rarity.RARE, mage.cards.a.AnkleShanker.class)); + cards.add(new SetCardInfo("Arashin Sovereign", 112, Rarity.SPECIAL, mage.cards.a.ArashinSovereign.class)); + cards.add(new SetCardInfo("Archfiend of Depravity", 109, Rarity.SPECIAL, mage.cards.a.ArchfiendOfDepravity.class)); + cards.add(new SetCardInfo("Archfiend of Ifnir", 165, Rarity.RARE, mage.cards.a.ArchfiendOfIfnir.class)); + cards.add(new SetCardInfo("Arena", 1, Rarity.SPECIAL, mage.cards.a.Arena.class)); + cards.add(new SetCardInfo("Arrest", 53, Rarity.COMMON, mage.cards.a.Arrest.class)); + cards.add(new SetCardInfo("Assembled Alphas", 160, Rarity.RARE, mage.cards.a.AssembledAlphas.class)); + cards.add(new SetCardInfo("Avalanche Tusker", 94, Rarity.RARE, mage.cards.a.AvalancheTusker.class)); + cards.add(new SetCardInfo("Barrage Tyrant", 139, Rarity.SPECIAL, mage.cards.b.BarrageTyrant.class)); + cards.add(new SetCardInfo("Birds of Paradise", 28, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); + cards.add(new SetCardInfo("Bloodthrone Vampire", 31, Rarity.COMMON, mage.cards.b.BloodthroneVampire.class)); + cards.add(new SetCardInfo("Blue Elemental Blast", 5, Rarity.COMMON, mage.cards.b.BlueElementalBlast.class)); + cards.add(new SetCardInfo("Boltwing Marauder", 115, Rarity.SPECIAL, mage.cards.b.BoltwingMarauder.class)); + cards.add(new SetCardInfo("Bonescythe Sliver", 68, Rarity.RARE, mage.cards.b.BonescytheSliver.class)); + cards.add(new SetCardInfo("Breath of Malfegor", 58, Rarity.COMMON, mage.cards.b.BreathOfMalfegor.class)); + cards.add(new SetCardInfo("Brion Stoutarm", 17, Rarity.RARE, mage.cards.b.BrionStoutarm.class)); + cards.add(new SetCardInfo("Broodmate Dragon", 19, Rarity.RARE, mage.cards.b.BroodmateDragon.class)); + cards.add(new SetCardInfo("Cathedral of War", 51, Rarity.RARE, mage.cards.c.CathedralOfWar.class)); + cards.add(new SetCardInfo("Celestial Colonnade", 23, Rarity.SPECIAL, mage.cards.c.CelestialColonnade.class)); + cards.add(new SetCardInfo("Chandra, Fire of Kaladesh", 997, Rarity.SPECIAL, mage.cards.c.ChandraFireOfKaladesh.class)); + cards.add(new SetCardInfo("Chandra, Pyromaster", 75, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class)); + cards.add(new SetCardInfo("Chandra, Pyromaster", 102, Rarity.MYTHIC, mage.cards.c.ChandraPyromaster.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Chandra, Roaring Flame", 997, Rarity.SPECIAL, mage.cards.c.ChandraRoaringFlame.class)); + cards.add(new SetCardInfo("Chandra's Fury", 65, Rarity.COMMON, mage.cards.c.ChandrasFury.class)); + cards.add(new SetCardInfo("Chandra's Phoenix", 37, Rarity.RARE, mage.cards.c.ChandrasPhoenix.class)); + cards.add(new SetCardInfo("Consume Spirit", 54, Rarity.UNCOMMON, mage.cards.c.ConsumeSpirit.class)); + cards.add(new SetCardInfo("Corrupt", 64, Rarity.UNCOMMON, mage.cards.c.Corrupt.class)); + cards.add(new SetCardInfo("Day of Judgment", 22, Rarity.RARE, mage.cards.d.DayOfJudgment.class)); + cards.add(new SetCardInfo("Deepfathom Skulker", 144, Rarity.RARE, mage.cards.d.DeepfathomSkulker.class)); + cards.add(new SetCardInfo("Defiant Bloodlord", 138, Rarity.SPECIAL, mage.cards.d.DefiantBloodlord.class)); + cards.add(new SetCardInfo("Devil's Play", 40, Rarity.RARE, mage.cards.d.DevilsPlay.class)); + cards.add(new SetCardInfo("Dragon Fodder", 119, Rarity.COMMON, mage.cards.d.DragonFodder.class)); + cards.add(new SetCardInfo("Dragonlord's Servant", 120, Rarity.SPECIAL, mage.cards.d.DragonlordsServant.class)); + cards.add(new SetCardInfo("Dragonscale General", 107, Rarity.SPECIAL, mage.cards.d.DragonscaleGeneral.class)); + cards.add(new SetCardInfo("Dread Defiler", 145, Rarity.RARE, mage.cards.d.DreadDefiler.class)); + cards.add(new SetCardInfo("Dreg Mangler", 55, Rarity.UNCOMMON, mage.cards.d.DregMangler.class)); + cards.add(new SetCardInfo("Drogskol Cavalry", 149, Rarity.RARE, mage.cards.d.DrogskolCavalry.class)); + cards.add(new SetCardInfo("Dromoka, the Eternal", 132, Rarity.SPECIAL, mage.cards.d.DromokaTheEternal.class)); + cards.add(new SetCardInfo("Drowner of Hope", 137, Rarity.SPECIAL, mage.cards.d.DrownerOfHope.class)); + cards.add(new SetCardInfo("Duress", 84, Rarity.COMMON, mage.cards.d.Duress.class)); + cards.add(new SetCardInfo("Dwynen, Gilt-Leaf Daen", 125, Rarity.SPECIAL, mage.cards.d.DwynenGiltLeafDaen.class)); + cards.add(new SetCardInfo("Eidolon of Blossoms", 85, Rarity.RARE, mage.cards.e.EidolonOfBlossoms.class)); + cards.add(new SetCardInfo("Electrolyze", 42, Rarity.UNCOMMON, mage.cards.e.Electrolyze.class)); + cards.add(new SetCardInfo("Elusive Tormentor", 154, Rarity.RARE, mage.cards.e.ElusiveTormentor.class)); + cards.add(new SetCardInfo("Emrakul, the Aeons Torn", 163, Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); + cards.add(new SetCardInfo("Evolving Wilds", 121, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); + cards.add(new SetCardInfo("Faithless Looting", 39, Rarity.COMMON, mage.cards.f.FaithlessLooting.class)); + cards.add(new SetCardInfo("Fated Conflagration", 79, Rarity.RARE, mage.cards.f.FatedConflagration.class)); + cards.add(new SetCardInfo("Feast of Blood", 43, Rarity.UNCOMMON, mage.cards.f.FeastOfBlood.class)); + cards.add(new SetCardInfo("Fireball", 4, Rarity.COMMON, mage.cards.f.Fireball.class)); + cards.add(new SetCardInfo("Flameblade Angel", 152, Rarity.RARE, mage.cards.f.FlamebladeAngel.class)); + cards.add(new SetCardInfo("Flamerush Rider", 110, Rarity.SPECIAL, mage.cards.f.FlamerushRider.class)); + cards.add(new SetCardInfo("Foe-Razer Regent", 122, Rarity.SPECIAL, mage.cards.f.FoeRazerRegent.class)); + cards.add(new SetCardInfo("Frost Titan", 34, Rarity.MYTHIC, mage.cards.f.FrostTitan.class)); + cards.add(new SetCardInfo("Garruk, Apex Predator", 104, Rarity.MYTHIC, mage.cards.g.GarrukApexPredator.class)); + cards.add(new SetCardInfo("Garruk, Caller of Beasts", 76, Rarity.MYTHIC, mage.cards.g.GarrukCallerOfBeasts.class)); + cards.add(new SetCardInfo("Garruk Wildspeaker", 16, Rarity.RARE, mage.cards.g.GarrukWildspeaker.class)); + cards.add(new SetCardInfo("Gaze of Granite", 81, Rarity.RARE, mage.cards.g.GazeOfGranite.class)); + cards.add(new SetCardInfo("Genesis Hydra", 142, Rarity.SPECIAL, mage.cards.g.GenesisHydra.class)); + cards.add(new SetCardInfo("Giant Badger", 8, Rarity.SPECIAL, mage.cards.g.GiantBadger.class)); + cards.add(new SetCardInfo("Gideon, Battle-Forged", 994, Rarity.SPECIAL, mage.cards.g.GideonBattleForged.class)); + cards.add(new SetCardInfo("Gladehart Cavalry", 147, Rarity.RARE, mage.cards.g.GladehartCavalry.class)); + cards.add(new SetCardInfo("Goblin Dark-Dwellers", 148, Rarity.RARE, mage.cards.g.GoblinDarkDwellers.class)); + cards.add(new SetCardInfo("Goblin Rabblemaster", 98, Rarity.RARE, mage.cards.g.GoblinRabblemaster.class)); + cards.add(new SetCardInfo("Gravecrawler", 41, Rarity.RARE, mage.cards.g.Gravecrawler.class)); + cards.add(new SetCardInfo("Grave Titan", 35, Rarity.MYTHIC, mage.cards.g.GraveTitan.class)); + cards.add(new SetCardInfo("Guul Draz Assassin", 26, Rarity.RARE, mage.cards.g.GuulDrazAssassin.class)); + cards.add(new SetCardInfo("Hamletback Goliath", 71, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); + cards.add(new SetCardInfo("Harbinger of the Hunt", 116, Rarity.SPECIAL, mage.cards.h.HarbingerOfTheHunt.class)); + cards.add(new SetCardInfo("Hero of Goma Fada", 136, Rarity.SPECIAL, mage.cards.h.HeroOfGomaFada.class)); + cards.add(new SetCardInfo("High Tide", 80, Rarity.COMMON, HighTide.class)); + cards.add(new SetCardInfo("Hixus, Prison Warden", 126, Rarity.SPECIAL, mage.cards.h.HixusPrisonWarden.class)); + cards.add(new SetCardInfo("Honored Hierarch", 129, Rarity.SPECIAL, mage.cards.h.HonoredHierarch.class)); + cards.add(new SetCardInfo("Honor of the Pure", 20, Rarity.RARE, mage.cards.h.HonorOfThePure.class)); + cards.add(new SetCardInfo("Inferno Titan", 36, Rarity.MYTHIC, mage.cards.i.InfernoTitan.class)); + cards.add(new SetCardInfo("Insidious Mist", 154, Rarity.RARE, mage.cards.i.InsidiousMist.class)); + cards.add(new SetCardInfo("Ivorytusk Fortress", 95, Rarity.RARE, mage.cards.i.IvorytuskFortress.class)); + cards.add(new SetCardInfo("Jace Beleren", 15, Rarity.RARE, mage.cards.j.JaceBeleren.class)); + cards.add(new SetCardInfo("Jace, Memory Adept", 73, Rarity.MYTHIC, mage.cards.j.JaceMemoryAdept.class)); + cards.add(new SetCardInfo("Jace, Telepath Unbound", 995, Rarity.SPECIAL, mage.cards.j.JaceTelepathUnbound.class)); + cards.add(new SetCardInfo("Jace, the Living Guildpact", 100, Rarity.MYTHIC, mage.cards.j.JaceTheLivingGuildpact.class)); + cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 995, Rarity.SPECIAL, mage.cards.j.JaceVrynsProdigy.class)); + cards.add(new SetCardInfo("Jaya Ballard, Task Mage", 18, Rarity.RARE, mage.cards.j.JayaBallardTaskMage.class)); + cards.add(new SetCardInfo("Karametra's Acolyte", 78, Rarity.UNCOMMON, mage.cards.k.KarametrasAcolyte.class)); + cards.add(new SetCardInfo("Knight Exemplar", 46, Rarity.RARE, mage.cards.k.KnightExemplar.class)); + cards.add(new SetCardInfo("Kor Skyfisher", 25, Rarity.COMMON, mage.cards.k.KorSkyfisher.class)); + cards.add(new SetCardInfo("Kothophed, Soul Hoarder", 127, Rarity.SPECIAL, mage.cards.k.KothophedSoulHoarder.class)); + cards.add(new SetCardInfo("Kytheon, Hero of Akros", 994, Rarity.SPECIAL, mage.cards.k.KytheonHeroOfAkros.class)); + cards.add(new SetCardInfo("Lightning Hounds", 10, Rarity.SPECIAL, mage.cards.l.LightningHounds.class)); + cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 996, Rarity.SPECIAL, mage.cards.l.LilianaDefiantNecromancer.class)); + cards.add(new SetCardInfo("Liliana, Heretical Healer", 996, Rarity.SPECIAL, mage.cards.l.LilianaHereticalHealer.class)); + cards.add(new SetCardInfo("Liliana of the Dark Realms", 74, Rarity.MYTHIC, mage.cards.l.LilianaOfTheDarkRealms.class)); + cards.add(new SetCardInfo("Liliana Vess", 30, Rarity.RARE, mage.cards.l.LilianaVess.class)); + cards.add(new SetCardInfo("Liliana Vess", 101, Rarity.MYTHIC, mage.cards.l.LilianaVess.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Magister of Worth", 86, Rarity.SPECIAL, mage.cards.m.MagisterOfWorth.class)); + cards.add(new SetCardInfo("Mana Crypt", 6, Rarity.RARE, mage.cards.m.ManaCrypt.class)); + cards.add(new SetCardInfo("Markov Dreadknight", 151, Rarity.RARE, mage.cards.m.MarkovDreadknight.class)); + cards.add(new SetCardInfo("Memoricide", 29, Rarity.RARE, mage.cards.m.Memoricide.class)); + cards.add(new SetCardInfo("Merfolk Mesmerist", 45, Rarity.COMMON, mage.cards.m.MerfolkMesmerist.class)); + cards.add(new SetCardInfo("Mirran Crusader", 32, Rarity.RARE, mage.cards.m.MirranCrusader.class)); + cards.add(new SetCardInfo("Munda's Vanguard", 143, Rarity.RARE, mage.cards.m.MundasVanguard.class)); + cards.add(new SetCardInfo("Necromaster Dragon", 114, Rarity.SPECIAL, mage.cards.n.NecromasterDragon.class)); + cards.add(new SetCardInfo("Nephalia Moondrakes", 150, Rarity.RARE, mage.cards.n.NephaliaMoondrakes.class)); + cards.add(new SetCardInfo("Niblis of Frost", 158, Rarity.RARE, mage.cards.n.NiblisOfFrost.class)); + cards.add(new SetCardInfo("Nightveil Specter", 61, Rarity.RARE, mage.cards.n.NightveilSpecter.class)); + cards.add(new SetCardInfo("Nissa Revane", 27, Rarity.MYTHIC, mage.cards.n.NissaRevane.class)); + cards.add(new SetCardInfo("Nissa, Sage Animist", 998, Rarity.SPECIAL, mage.cards.n.NissaSageAnimist.class)); + cards.add(new SetCardInfo("Nissa, Vastwood Seer", 998, Rarity.SPECIAL, mage.cards.n.NissaVastwoodSeer.class)); + cards.add(new SetCardInfo("Nissa, Worldwaker", 103, Rarity.MYTHIC, mage.cards.n.NissaWorldwaker.class)); + cards.add(new SetCardInfo("Noosegraf Mob", 159, Rarity.RARE, mage.cards.n.NoosegrafMob.class)); + cards.add(new SetCardInfo("Ogre Arsonist", 63, Rarity.SPECIAL, mage.cards.o.OgreArsonist.class)); + cards.add(new SetCardInfo("Ogre Battledriver", 69, Rarity.RARE, mage.cards.o.OgreBattledriver.class)); + cards.add(new SetCardInfo("Ojutai's Command", 106, Rarity.SPECIAL, mage.cards.o.OjutaisCommand.class)); + cards.add(new SetCardInfo("Oran-Rief Hydra", 140, Rarity.SPECIAL, mage.cards.o.OranRiefHydra.class)); + cards.add(new SetCardInfo("Phyrexian Rager", 14, Rarity.COMMON, mage.cards.p.PhyrexianRager.class)); + cards.add(new SetCardInfo("Pia and Kiran Nalaar", 128, Rarity.SPECIAL, mage.cards.p.PiaAndKiranNalaar.class)); + cards.add(new SetCardInfo("Primordial Hydra", 49, Rarity.MYTHIC, mage.cards.p.PrimordialHydra.class)); + cards.add(new SetCardInfo("Pristine Skywise", 113, Rarity.SPECIAL, mage.cards.p.PristineSkywise.class)); + cards.add(new SetCardInfo("Rakshasa Vizier", 96, Rarity.RARE, mage.cards.r.RakshasaVizier.class)); + cards.add(new SetCardInfo("Ratchet Bomb", 67, Rarity.RARE, mage.cards.r.RatchetBomb.class)); + cards.add(new SetCardInfo("Rattleclaw Mystic", 92, Rarity.RARE, mage.cards.r.RattleclawMystic.class)); + cards.add(new SetCardInfo("Ravenous Bloodseeker", 155, Rarity.UNCOMMON, mage.cards.r.RavenousBloodseeker.class)); + cards.add(new SetCardInfo("Relic Seeker", 123, Rarity.RARE, mage.cards.r.RelicSeeker.class)); + cards.add(new SetCardInfo("Render Silent", 66, Rarity.RARE, mage.cards.r.RenderSilent.class)); + cards.add(new SetCardInfo("Retaliator Griffin", 24, Rarity.RARE, mage.cards.r.RetaliatorGriffin.class)); + cards.add(new SetCardInfo("Ruinous Path", 135, Rarity.SPECIAL, mage.cards.r.RuinousPath.class)); + cards.add(new SetCardInfo("Sage-Eye Avengers", 108, Rarity.SPECIAL, mage.cards.s.SageEyeAvengers.class)); + cards.add(new SetCardInfo("Sage of the Inward Eye", 97, Rarity.RARE, mage.cards.s.SageOfTheInwardEye.class)); + cards.add(new SetCardInfo("Sanctifier of Souls", 157, Rarity.RARE, mage.cards.s.SanctifierOfSouls.class)); + cards.add(new SetCardInfo("Sandsteppe Citadel", 134, Rarity.SPECIAL, mage.cards.s.SandsteppeCitadel.class)); + cards.add(new SetCardInfo("Scavenging Ooze", 70, Rarity.RARE, mage.cards.s.ScavengingOoze.class)); + cards.add(new SetCardInfo("Scrap Trawler", 164, Rarity.RARE, mage.cards.s.ScrapTrawler.class)); + cards.add(new SetCardInfo("Scythe Leopard", 141, Rarity.SPECIAL, mage.cards.s.ScytheLeopard.class)); + cards.add(new SetCardInfo("Seeker of the Way", 130, Rarity.SPECIAL, mage.cards.s.SeekerOfTheWay.class)); + cards.add(new SetCardInfo("Serra Avatar", 48, Rarity.MYTHIC, mage.cards.s.SerraAvatar.class)); + cards.add(new SetCardInfo("Shamanic Revelation", 105, Rarity.SPECIAL, mage.cards.s.ShamanicRevelation.class)); + cards.add(new SetCardInfo("Siege Rhino", 133, Rarity.SPECIAL, mage.cards.s.SiegeRhino.class)); + cards.add(new SetCardInfo("Silverblade Paladin", 44, Rarity.RARE, mage.cards.s.SilverbladePaladin.class)); + cards.add(new SetCardInfo("Silver Drake", 13, Rarity.SPECIAL, mage.cards.s.SilverDrake.class)); + cards.add(new SetCardInfo("Skyship Stalker", 162, Rarity.RARE, mage.cards.s.SkyshipStalker.class)); + cards.add(new SetCardInfo("Soul of Ravnica", 87, Rarity.MYTHIC, mage.cards.s.SoulOfRavnica.class)); + cards.add(new SetCardInfo("Soul of Zendikar", 88, Rarity.MYTHIC, mage.cards.s.SoulOfZendikar.class)); + cards.add(new SetCardInfo("Soul Swallower", 153, Rarity.RARE, mage.cards.s.SoulSwallower.class)); + cards.add(new SetCardInfo("Spined Wurm", 11, Rarity.SPECIAL, mage.cards.s.SpinedWurm.class)); + cards.add(new SetCardInfo("Standstill", 57, Rarity.UNCOMMON, mage.cards.s.Standstill.class)); + cards.add(new SetCardInfo("Stealer of Secrets", 89, Rarity.COMMON, mage.cards.s.StealerOfSecrets.class)); + cards.add(new SetCardInfo("Steward of Valeron", 21, Rarity.COMMON, mage.cards.s.StewardOfValeron.class)); + cards.add(new SetCardInfo("Sultai Charm", 117, Rarity.SPECIAL, mage.cards.s.SultaiCharm.class)); + cards.add(new SetCardInfo("Sunblast Angel", 47, Rarity.RARE, mage.cards.s.SunblastAngel.class)); + cards.add(new SetCardInfo("Supreme Verdict", 56, Rarity.RARE, mage.cards.s.SupremeVerdict.class)); + cards.add(new SetCardInfo("Surgical Extraction", 33, Rarity.RARE, mage.cards.s.SurgicalExtraction.class)); + cards.add(new SetCardInfo("Sylvan Caryatid", 77, Rarity.RARE, mage.cards.s.SylvanCaryatid.class)); + cards.add(new SetCardInfo("Temur War Shaman", 111, Rarity.SPECIAL, mage.cards.t.TemurWarShaman.class)); + cards.add(new SetCardInfo("Terastodon", 52, Rarity.RARE, mage.cards.t.Terastodon.class)); + cards.add(new SetCardInfo("Thalia, Heretic Cathar", 156, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class)); + cards.add(new SetCardInfo("Treasure Hunt", 38, Rarity.COMMON, mage.cards.t.TreasureHunt.class)); + cards.add(new SetCardInfo("Turnabout", 60, Rarity.UNCOMMON, mage.cards.t.Turnabout.class)); + cards.add(new SetCardInfo("Tyrant of Valakut", 146, Rarity.RARE, mage.cards.t.TyrantOfValakut.class)); + cards.add(new SetCardInfo("Ulvenwald Observer", 161, Rarity.RARE, mage.cards.u.UlvenwaldObserver.class)); + cards.add(new SetCardInfo("Valorous Stance", 131, Rarity.SPECIAL, mage.cards.v.ValorousStance.class)); + cards.add(new SetCardInfo("Vampire Nocturnus", 50, Rarity.MYTHIC, mage.cards.v.VampireNocturnus.class)); + cards.add(new SetCardInfo("Voidmage Husher", 62, Rarity.SPECIAL, mage.cards.v.VoidmageHusher.class)); + cards.add(new SetCardInfo("Warmonger", 12, Rarity.SPECIAL, mage.cards.w.Warmonger.class)); + cards.add(new SetCardInfo("Wash Out", 82, Rarity.UNCOMMON, mage.cards.w.WashOut.class)); + cards.add(new SetCardInfo("Windseeker Centaur", 7, Rarity.SPECIAL, mage.cards.w.WindseekerCentaur.class)); + cards.add(new SetCardInfo("Xathrid Necromancer", 91, Rarity.SPECIAL, mage.cards.x.XathridNecromancer.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java index 58894b294e4..cbde16664ef 100644 --- a/Mage.Sets/src/mage/sets/MercadianMasques.java +++ b/Mage.Sets/src/mage/sets/MercadianMasques.java @@ -1,323 +1,324 @@ -/* - * 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.cards.CardGraphicInfo; -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author North - */ -public class MercadianMasques extends ExpansionSet { - - private static final MercadianMasques instance = new MercadianMasques(); - - public static MercadianMasques getInstance() { - return instance; - } - - private MercadianMasques() { - super("Mercadian Masques", "MMQ", ExpansionSet.buildDate(1999, 8, 25), SetType.EXPANSION); - this.blockName = "Masques"; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Afterlife", 1, Rarity.UNCOMMON, mage.cards.a.Afterlife.class)); - cards.add(new SetCardInfo("Alabaster Wall", 2, Rarity.COMMON, mage.cards.a.AlabasterWall.class)); - cards.add(new SetCardInfo("Alley Grifters", 115, Rarity.COMMON, mage.cards.a.AlleyGrifters.class)); - cards.add(new SetCardInfo("Ancestral Mask", 229, Rarity.COMMON, mage.cards.a.AncestralMask.class)); - cards.add(new SetCardInfo("Armistice", 3, Rarity.RARE, mage.cards.a.Armistice.class)); - cards.add(new SetCardInfo("Arms Dealer", 172, Rarity.UNCOMMON, mage.cards.a.ArmsDealer.class)); - cards.add(new SetCardInfo("Arrest", 4, Rarity.UNCOMMON, mage.cards.a.Arrest.class)); - cards.add(new SetCardInfo("Ballista Squad", 5, Rarity.UNCOMMON, mage.cards.b.BallistaSquad.class)); - cards.add(new SetCardInfo("Balloon Peddler", 59, Rarity.COMMON, mage.cards.b.BalloonPeddler.class)); - cards.add(new SetCardInfo("Battle Rampart", 173, Rarity.COMMON, mage.cards.b.BattleRampart.class)); - cards.add(new SetCardInfo("Battle Squadron", 174, Rarity.RARE, mage.cards.b.BattleSquadron.class)); - cards.add(new SetCardInfo("Black Market", 116, Rarity.RARE, mage.cards.b.BlackMarket.class)); - cards.add(new SetCardInfo("Blaster Mage", 175, Rarity.COMMON, mage.cards.b.BlasterMage.class)); - cards.add(new SetCardInfo("Blockade Runner", 60, Rarity.COMMON, mage.cards.b.BlockadeRunner.class)); - cards.add(new SetCardInfo("Bog Smugglers", 117, Rarity.COMMON, mage.cards.b.BogSmugglers.class)); - cards.add(new SetCardInfo("Bog Witch", 118, Rarity.COMMON, mage.cards.b.BogWitch.class)); - cards.add(new SetCardInfo("Brainstorm", 61, Rarity.COMMON, mage.cards.b.Brainstorm.class)); - cards.add(new SetCardInfo("Bribery", 62, Rarity.RARE, mage.cards.b.Bribery.class)); - cards.add(new SetCardInfo("Buoyancy", 63, Rarity.COMMON, mage.cards.b.Buoyancy.class)); - cards.add(new SetCardInfo("Cackling Witch", 119, Rarity.UNCOMMON, mage.cards.c.CacklingWitch.class)); - cards.add(new SetCardInfo("Cateran Brute", 120, Rarity.COMMON, mage.cards.c.CateranBrute.class)); - cards.add(new SetCardInfo("Cateran Enforcer", 121, Rarity.UNCOMMON, mage.cards.c.CateranEnforcer.class)); - cards.add(new SetCardInfo("Cateran Kidnappers", 122, Rarity.UNCOMMON, mage.cards.c.CateranKidnappers.class)); - cards.add(new SetCardInfo("Cateran Overlord", 123, Rarity.RARE, mage.cards.c.CateranOverlord.class)); - cards.add(new SetCardInfo("Cateran Persuader", 124, Rarity.COMMON, mage.cards.c.CateranPersuader.class)); - cards.add(new SetCardInfo("Cateran Slaver", 125, Rarity.RARE, mage.cards.c.CateranSlaver.class)); - cards.add(new SetCardInfo("Cateran Summons", 126, Rarity.UNCOMMON, mage.cards.c.CateranSummons.class)); - cards.add(new SetCardInfo("Caustic Wasps", 234, Rarity.UNCOMMON, mage.cards.c.CausticWasps.class)); - cards.add(new SetCardInfo("Cave-In", 180, Rarity.RARE, mage.cards.c.CaveIn.class)); - cards.add(new SetCardInfo("Cavern Crawler", 181, Rarity.COMMON, mage.cards.c.CavernCrawler.class)); - cards.add(new SetCardInfo("Cave Sense", 179, Rarity.COMMON, mage.cards.c.CaveSense.class)); - cards.add(new SetCardInfo("Chambered Nautilus", 64, Rarity.UNCOMMON, mage.cards.c.ChamberedNautilus.class)); - cards.add(new SetCardInfo("Cho-Arrim Alchemist", 8, Rarity.RARE, mage.cards.c.ChoArrimAlchemist.class)); - cards.add(new SetCardInfo("Cho-Arrim Bruiser", 9, Rarity.RARE, mage.cards.c.ChoArrimBruiser.class)); - cards.add(new SetCardInfo("Cho-Arrim Legate", 10, Rarity.UNCOMMON, mage.cards.c.ChoArrimLegate.class)); - cards.add(new SetCardInfo("Cho-Manno, Revolutionary", 11, Rarity.RARE, mage.cards.c.ChoMannoRevolutionary.class)); - cards.add(new SetCardInfo("Cho-Manno's Blessing", 12, Rarity.COMMON, mage.cards.c.ChoMannosBlessing.class)); - cards.add(new SetCardInfo("Cinder Elemental", 183, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class)); - cards.add(new SetCardInfo("Close Quarters", 184, Rarity.UNCOMMON, mage.cards.c.CloseQuarters.class)); - cards.add(new SetCardInfo("Cloud Sprite", 67, Rarity.COMMON, mage.cards.c.CloudSprite.class)); - cards.add(new SetCardInfo("Coastal Piracy", 68, Rarity.UNCOMMON, mage.cards.c.CoastalPiracy.class)); - cards.add(new SetCardInfo("Collective Unconscious", 236, Rarity.RARE, mage.cards.c.CollectiveUnconscious.class)); - cards.add(new SetCardInfo("Conspiracy", 127, Rarity.RARE, mage.cards.c.Conspiracy.class)); - cards.add(new SetCardInfo("Corrupt Official", 128, Rarity.RARE, mage.cards.c.CorruptOfficial.class)); - cards.add(new SetCardInfo("Counterspell", 69, Rarity.COMMON, mage.cards.c.Counterspell.class)); - cards.add(new SetCardInfo("Cowardice", 70, Rarity.RARE, mage.cards.c.Cowardice.class)); - cards.add(new SetCardInfo("Crackdown", 15, Rarity.RARE, mage.cards.c.Crackdown.class)); - cards.add(new SetCardInfo("Crash", 186, Rarity.COMMON, mage.cards.c.Crash.class)); - cards.add(new SetCardInfo("Crenellated Wall", 290, Rarity.UNCOMMON, mage.cards.c.CrenellatedWall.class)); - cards.add(new SetCardInfo("Crossbow Infantry", 16, Rarity.COMMON, mage.cards.c.CrossbowInfantry.class)); - cards.add(new SetCardInfo("Crumbling Sanctuary", 292, Rarity.RARE, mage.cards.c.CrumblingSanctuary.class)); - cards.add(new SetCardInfo("Dark Ritual", 129, Rarity.COMMON, mage.cards.d.DarkRitual.class)); - cards.add(new SetCardInfo("Darting Merfolk", 72, Rarity.COMMON, mage.cards.d.DartingMerfolk.class)); - cards.add(new SetCardInfo("Dawnstrider", 237, Rarity.RARE, mage.cards.d.Dawnstrider.class)); - cards.add(new SetCardInfo("Deadly Insect", 238, Rarity.COMMON, mage.cards.d.DeadlyInsect.class)); - cards.add(new SetCardInfo("Deathgazer", 130, Rarity.UNCOMMON, mage.cards.d.Deathgazer.class)); - cards.add(new SetCardInfo("Deepwood Drummer", 239, Rarity.COMMON, mage.cards.d.DeepwoodDrummer.class)); - cards.add(new SetCardInfo("Deepwood Ghoul", 131, Rarity.COMMON, mage.cards.d.DeepwoodGhoul.class)); - cards.add(new SetCardInfo("Deepwood Legate", 132, Rarity.UNCOMMON, mage.cards.d.DeepwoodLegate.class)); - cards.add(new SetCardInfo("Deepwood Tantiv", 241, Rarity.UNCOMMON, mage.cards.d.DeepwoodTantiv.class)); - cards.add(new SetCardInfo("Deepwood Wolverine", 242, Rarity.COMMON, mage.cards.d.DeepwoodWolverine.class)); - cards.add(new SetCardInfo("Dehydration", 73, Rarity.COMMON, mage.cards.d.Dehydration.class)); - cards.add(new SetCardInfo("Desert Twister", 243, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class)); - cards.add(new SetCardInfo("Devout Witness", 17, Rarity.COMMON, mage.cards.d.DevoutWitness.class)); - cards.add(new SetCardInfo("Diplomatic Escort", 74, Rarity.UNCOMMON, mage.cards.d.DiplomaticEscort.class)); - cards.add(new SetCardInfo("Diplomatic Immunity", 75, Rarity.COMMON, mage.cards.d.DiplomaticImmunity.class)); - cards.add(new SetCardInfo("Disenchant", 18, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Distorting Lens", 293, Rarity.RARE, mage.cards.d.DistortingLens.class)); - cards.add(new SetCardInfo("Drake Hatchling", 76, Rarity.COMMON, mage.cards.d.DrakeHatchling.class)); - cards.add(new SetCardInfo("Dust Bowl", 316, Rarity.RARE, mage.cards.d.DustBowl.class)); - cards.add(new SetCardInfo("Embargo", 77, Rarity.RARE, mage.cards.e.Embargo.class)); - cards.add(new SetCardInfo("Energy Flux", 78, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class)); - cards.add(new SetCardInfo("Eye of Ramos", 294, Rarity.RARE, mage.cards.e.EyeOfRamos.class)); - cards.add(new SetCardInfo("False Demise", 80, Rarity.UNCOMMON, mage.cards.f.FalseDemise.class)); - cards.add(new SetCardInfo("Flailing Manticore", 187, Rarity.RARE, mage.cards.f.FlailingManticore.class)); - cards.add(new SetCardInfo("Flailing Ogre", 188, Rarity.UNCOMMON, mage.cards.f.FlailingOgre.class)); - cards.add(new SetCardInfo("Flailing Soldier", 189, Rarity.COMMON, mage.cards.f.FlailingSoldier.class)); - cards.add(new SetCardInfo("Food Chain", 246, Rarity.RARE, mage.cards.f.FoodChain.class)); - cards.add(new SetCardInfo("Forced March", 136, Rarity.RARE, mage.cards.f.ForcedMarch.class)); - cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Foster", 247, Rarity.RARE, mage.cards.f.Foster.class)); - cards.add(new SetCardInfo("Fountain of Cho", 317, Rarity.UNCOMMON, mage.cards.f.FountainOfCho.class)); - cards.add(new SetCardInfo("Fountain Watch", 19, Rarity.RARE, mage.cards.f.FountainWatch.class)); - cards.add(new SetCardInfo("Fresh Volunteers", 20, Rarity.COMMON, mage.cards.f.FreshVolunteers.class)); - cards.add(new SetCardInfo("Furious Assault", 191, Rarity.COMMON, mage.cards.f.FuriousAssault.class)); - cards.add(new SetCardInfo("Gerrard's Irregulars", 192, Rarity.COMMON, mage.cards.g.GerrardsIrregulars.class)); - cards.add(new SetCardInfo("Ghoul's Feast", 137, Rarity.UNCOMMON, mage.cards.g.GhoulsFeast.class)); - cards.add(new SetCardInfo("Giant Caterpillar", 249, Rarity.COMMON, mage.cards.g.GiantCaterpillar.class)); - cards.add(new SetCardInfo("Groundskeeper", 250, Rarity.UNCOMMON, mage.cards.g.Groundskeeper.class)); - cards.add(new SetCardInfo("Gush", 82, Rarity.COMMON, mage.cards.g.Gush.class)); - cards.add(new SetCardInfo("Hammer Mage", 193, Rarity.UNCOMMON, mage.cards.h.HammerMage.class)); - cards.add(new SetCardInfo("Haunted Crossroads", 138, Rarity.UNCOMMON, mage.cards.h.HauntedCrossroads.class)); - cards.add(new SetCardInfo("Heart of Ramos", 296, Rarity.RARE, mage.cards.h.HeartOfRamos.class)); - cards.add(new SetCardInfo("Henge Guardian", 297, Rarity.UNCOMMON, mage.cards.h.HengeGuardian.class)); - cards.add(new SetCardInfo("Henge of Ramos", 318, Rarity.UNCOMMON, mage.cards.h.HengeOfRamos.class)); - cards.add(new SetCardInfo("Hickory Woodlot", 319, Rarity.COMMON, mage.cards.h.HickoryWoodlot.class)); - cards.add(new SetCardInfo("High Market", 320, Rarity.RARE, mage.cards.h.HighMarket.class)); - cards.add(new SetCardInfo("High Seas", 83, Rarity.UNCOMMON, mage.cards.h.HighSeas.class)); - cards.add(new SetCardInfo("Highway Robber", 139, Rarity.COMMON, mage.cards.h.HighwayRobber.class)); - cards.add(new SetCardInfo("Hoodwink", 84, Rarity.COMMON, mage.cards.h.Hoodwink.class)); - cards.add(new SetCardInfo("Horned Troll", 251, Rarity.COMMON, mage.cards.h.HornedTroll.class)); - cards.add(new SetCardInfo("Horn of Plenty", 298, Rarity.RARE, mage.cards.h.HornOfPlenty.class)); - cards.add(new SetCardInfo("Horn of Ramos", 299, Rarity.RARE, mage.cards.h.HornOfRamos.class)); - cards.add(new SetCardInfo("Howling Wolf", 252, Rarity.COMMON, mage.cards.h.HowlingWolf.class)); - cards.add(new SetCardInfo("Hunted Wumpus", 253, Rarity.UNCOMMON, mage.cards.h.HuntedWumpus.class)); - cards.add(new SetCardInfo("Ignoble Soldier", 22, Rarity.UNCOMMON, mage.cards.i.IgnobleSoldier.class)); - cards.add(new SetCardInfo("Instigator", 140, Rarity.RARE, mage.cards.i.Instigator.class)); - cards.add(new SetCardInfo("Intimidation", 142, Rarity.UNCOMMON, mage.cards.i.Intimidation.class)); - cards.add(new SetCardInfo("Invigorate", 254, Rarity.COMMON, mage.cards.i.Invigorate.class)); - cards.add(new SetCardInfo("Iron Lance", 300, Rarity.UNCOMMON, mage.cards.i.IronLance.class)); - cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Ivory Mask", 24, Rarity.RARE, mage.cards.i.IvoryMask.class)); - cards.add(new SetCardInfo("Jhovall Queen", 25, Rarity.RARE, mage.cards.j.JhovallQueen.class)); - cards.add(new SetCardInfo("Jhovall Rider", 26, Rarity.UNCOMMON, mage.cards.j.JhovallRider.class)); - cards.add(new SetCardInfo("Kris Mage", 195, Rarity.COMMON, mage.cards.k.KrisMage.class)); - cards.add(new SetCardInfo("Kyren Glider", 196, Rarity.COMMON, mage.cards.k.KyrenGlider.class)); - cards.add(new SetCardInfo("Kyren Legate", 197, Rarity.UNCOMMON, mage.cards.k.KyrenLegate.class)); - cards.add(new SetCardInfo("Kyren Sniper", 199, Rarity.COMMON, mage.cards.k.KyrenSniper.class)); - cards.add(new SetCardInfo("Kyren Toy", 303, Rarity.RARE, mage.cards.k.KyrenToy.class)); - cards.add(new SetCardInfo("Land Grant", 255, Rarity.COMMON, mage.cards.l.LandGrant.class)); - cards.add(new SetCardInfo("Larceny", 143, Rarity.UNCOMMON, mage.cards.l.Larceny.class)); - cards.add(new SetCardInfo("Last Breath", 27, Rarity.UNCOMMON, mage.cards.l.LastBreath.class)); - cards.add(new SetCardInfo("Lava Runner", 200, Rarity.RARE, mage.cards.l.LavaRunner.class)); - cards.add(new SetCardInfo("Lightning Hounds", 201, Rarity.COMMON, mage.cards.l.LightningHounds.class)); - cards.add(new SetCardInfo("Lithophage", 202, Rarity.RARE, mage.cards.l.Lithophage.class)); - cards.add(new SetCardInfo("Lumbering Satyr", 257, Rarity.UNCOMMON, mage.cards.l.LumberingSatyr.class)); - cards.add(new SetCardInfo("Lunge", 203, Rarity.COMMON, mage.cards.l.Lunge.class)); - cards.add(new SetCardInfo("Lure", 258, Rarity.UNCOMMON, mage.cards.l.Lure.class)); - cards.add(new SetCardInfo("Maggot Therapy", 145, Rarity.COMMON, mage.cards.m.MaggotTherapy.class)); - cards.add(new SetCardInfo("Magistrate's Scepter", 304, Rarity.RARE, mage.cards.m.MagistratesScepter.class)); - cards.add(new SetCardInfo("Magistrate's Veto", 204, Rarity.UNCOMMON, mage.cards.m.MagistratesVeto.class)); - cards.add(new SetCardInfo("Mercadian Bazaar", 321, Rarity.UNCOMMON, mage.cards.m.MercadianBazaar.class)); - cards.add(new SetCardInfo("Midnight Ritual", 146, Rarity.RARE, mage.cards.m.MidnightRitual.class)); - cards.add(new SetCardInfo("Misdirection", 87, Rarity.RARE, mage.cards.m.Misdirection.class)); - cards.add(new SetCardInfo("Misshapen Fiend", 147, Rarity.COMMON, mage.cards.m.MisshapenFiend.class)); - cards.add(new SetCardInfo("Misstep", 88, Rarity.COMMON, mage.cards.m.Misstep.class)); - cards.add(new SetCardInfo("Molting Harpy", 148, Rarity.UNCOMMON, mage.cards.m.MoltingHarpy.class)); - cards.add(new SetCardInfo("Moment of Silence", 28, Rarity.COMMON, mage.cards.m.MomentOfSilence.class)); - cards.add(new SetCardInfo("Monkey Cage", 307, Rarity.RARE, mage.cards.m.MonkeyCage.class)); - cards.add(new SetCardInfo("Moonlit Wake", 29, Rarity.UNCOMMON, mage.cards.m.MoonlitWake.class)); - cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Muzzle", 30, Rarity.COMMON, mage.cards.m.Muzzle.class)); - cards.add(new SetCardInfo("Natural Affinity", 260, Rarity.RARE, mage.cards.n.NaturalAffinity.class)); - cards.add(new SetCardInfo("Nether Spirit", 149, Rarity.RARE, mage.cards.n.NetherSpirit.class)); - cards.add(new SetCardInfo("Nightwind Glider", 31, Rarity.COMMON, mage.cards.n.NightwindGlider.class)); - cards.add(new SetCardInfo("Noble Purpose", 32, Rarity.UNCOMMON, mage.cards.n.NoblePurpose.class)); - cards.add(new SetCardInfo("Notorious Assassin", 150, Rarity.RARE, mage.cards.n.NotoriousAssassin.class)); - cards.add(new SetCardInfo("Ogre Taskmaster", 206, Rarity.UNCOMMON, mage.cards.o.OgreTaskmaster.class)); - cards.add(new SetCardInfo("Overtaker", 89, Rarity.RARE, mage.cards.o.Overtaker.class)); - cards.add(new SetCardInfo("Pangosaur", 261, Rarity.RARE, mage.cards.p.Pangosaur.class)); - cards.add(new SetCardInfo("Peat Bog", 322, Rarity.COMMON, mage.cards.p.PeatBog.class)); - cards.add(new SetCardInfo("Pious Warrior", 34, Rarity.COMMON, mage.cards.p.PiousWarrior.class)); - cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Power Matrix", 309, Rarity.RARE, mage.cards.p.PowerMatrix.class)); - cards.add(new SetCardInfo("Primeval Shambler", 152, Rarity.UNCOMMON, mage.cards.p.PrimevalShambler.class)); - cards.add(new SetCardInfo("Pulverize", 207, Rarity.RARE, mage.cards.p.Pulverize.class)); - cards.add(new SetCardInfo("Puppet's Verdict", 208, Rarity.RARE, mage.cards.p.PuppetsVerdict.class)); - cards.add(new SetCardInfo("Quagmire Lamprey", 154, Rarity.UNCOMMON, mage.cards.q.QuagmireLamprey.class)); - cards.add(new SetCardInfo("Rain of Tears", 155, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); - cards.add(new SetCardInfo("Ramosian Captain", 35, Rarity.UNCOMMON, mage.cards.r.RamosianCaptain.class)); - cards.add(new SetCardInfo("Ramosian Commander", 36, Rarity.UNCOMMON, mage.cards.r.RamosianCommander.class)); - cards.add(new SetCardInfo("Ramosian Lieutenant", 37, Rarity.COMMON, mage.cards.r.RamosianLieutenant.class)); - cards.add(new SetCardInfo("Ramosian Rally", 38, Rarity.COMMON, mage.cards.r.RamosianRally.class)); - cards.add(new SetCardInfo("Ramosian Sergeant", 39, Rarity.COMMON, mage.cards.r.RamosianSergeant.class)); - cards.add(new SetCardInfo("Ramosian Sky Marshal", 40, Rarity.RARE, mage.cards.r.RamosianSkyMarshal.class)); - cards.add(new SetCardInfo("Rampart Crawler", 156, Rarity.COMMON, mage.cards.r.RampartCrawler.class)); - cards.add(new SetCardInfo("Rappelling Scouts", 41, Rarity.RARE, mage.cards.r.RappellingScouts.class)); - cards.add(new SetCardInfo("Remote Farm", 323, Rarity.COMMON, mage.cards.r.RemoteFarm.class)); - cards.add(new SetCardInfo("Revive", 262, Rarity.UNCOMMON, mage.cards.r.Revive.class)); - cards.add(new SetCardInfo("Righteous Aura", 45, Rarity.UNCOMMON, mage.cards.r.RighteousAura.class)); - cards.add(new SetCardInfo("Rishadan Airship", 91, Rarity.COMMON, mage.cards.r.RishadanAirship.class)); - cards.add(new SetCardInfo("Rishadan Brigand", 92, Rarity.RARE, mage.cards.r.RishadanBrigand.class)); - cards.add(new SetCardInfo("Rishadan Cutpurse", 93, Rarity.COMMON, mage.cards.r.RishadanCutpurse.class)); - cards.add(new SetCardInfo("Rishadan Footpad", 94, Rarity.UNCOMMON, mage.cards.r.RishadanFootpad.class)); - cards.add(new SetCardInfo("Rishadan Port", 324, Rarity.RARE, mage.cards.r.RishadanPort.class)); - cards.add(new SetCardInfo("Rock Badger", 210, Rarity.UNCOMMON, mage.cards.r.RockBadger.class)); - cards.add(new SetCardInfo("Rushwood Dryad", 263, Rarity.COMMON, mage.cards.r.RushwoodDryad.class)); - cards.add(new SetCardInfo("Rushwood Elemental", 264, Rarity.RARE, mage.cards.r.RushwoodElemental.class)); - cards.add(new SetCardInfo("Rushwood Grove", 325, Rarity.UNCOMMON, mage.cards.r.RushwoodGrove.class)); - cards.add(new SetCardInfo("Rushwood Herbalist", 265, Rarity.COMMON, mage.cards.r.RushwoodHerbalist.class)); - cards.add(new SetCardInfo("Rushwood Legate", 266, Rarity.UNCOMMON, mage.cards.r.RushwoodLegate.class)); - cards.add(new SetCardInfo("Saber Ants", 267, Rarity.UNCOMMON, mage.cards.s.SaberAnts.class)); - cards.add(new SetCardInfo("Sacred Prey", 268, Rarity.COMMON, mage.cards.s.SacredPrey.class)); - cards.add(new SetCardInfo("Sand Squid", 96, Rarity.RARE, mage.cards.s.SandSquid.class)); - cards.add(new SetCardInfo("Sandstone Needle", 326, Rarity.COMMON, mage.cards.s.SandstoneNeedle.class)); - cards.add(new SetCardInfo("Saprazzan Cove", 327, Rarity.UNCOMMON, mage.cards.s.SaprazzanCove.class)); - cards.add(new SetCardInfo("Saprazzan Heir", 99, Rarity.RARE, mage.cards.s.SaprazzanHeir.class)); - cards.add(new SetCardInfo("Saprazzan Legate", 100, Rarity.UNCOMMON, mage.cards.s.SaprazzanLegate.class)); - cards.add(new SetCardInfo("Saprazzan Raider", 102, Rarity.COMMON, mage.cards.s.SaprazzanRaider.class)); - cards.add(new SetCardInfo("Saprazzan Skerry", 328, Rarity.COMMON, mage.cards.s.SaprazzanSkerry.class)); - cards.add(new SetCardInfo("Seismic Mage", 211, Rarity.RARE, mage.cards.s.SeismicMage.class)); - cards.add(new SetCardInfo("Sever Soul", 159, Rarity.COMMON, mage.cards.s.SeverSoul.class)); - cards.add(new SetCardInfo("Shock Troops", 212, Rarity.COMMON, mage.cards.s.ShockTroops.class)); - cards.add(new SetCardInfo("Silverglade Elemental", 269, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class)); - cards.add(new SetCardInfo("Silverglade Pathfinder", 270, Rarity.UNCOMMON, mage.cards.s.SilvergladePathfinder.class)); - cards.add(new SetCardInfo("Sizzle", 213, Rarity.COMMON, mage.cards.s.Sizzle.class)); - cards.add(new SetCardInfo("Skulking Fugitive", 161, Rarity.COMMON, mage.cards.s.SkulkingFugitive.class)); - cards.add(new SetCardInfo("Skull of Ramos", 312, Rarity.RARE, mage.cards.s.SkullOfRamos.class)); - cards.add(new SetCardInfo("Snake Pit", 271, Rarity.UNCOMMON, mage.cards.s.SnakePit.class)); - cards.add(new SetCardInfo("Snorting Gahr", 272, Rarity.COMMON, mage.cards.s.SnortingGahr.class)); - cards.add(new SetCardInfo("Snuff Out", 162, Rarity.COMMON, mage.cards.s.SnuffOut.class)); - cards.add(new SetCardInfo("Soothing Balm", 48, Rarity.COMMON, mage.cards.s.SoothingBalm.class)); - cards.add(new SetCardInfo("Soothsaying", 104, Rarity.UNCOMMON, mage.cards.s.Soothsaying.class)); - cards.add(new SetCardInfo("Soul Channeling", 163, Rarity.COMMON, mage.cards.s.SoulChanneling.class)); - cards.add(new SetCardInfo("Specter's Wail", 164, Rarity.COMMON, mage.cards.s.SpectersWail.class)); - cards.add(new SetCardInfo("Spidersilk Armor", 273, Rarity.COMMON, mage.cards.s.SpidersilkArmor.class)); - cards.add(new SetCardInfo("Spontaneous Generation", 274, Rarity.RARE, mage.cards.s.SpontaneousGeneration.class)); - cards.add(new SetCardInfo("Squall", 275, Rarity.COMMON, mage.cards.s.Squall.class)); - cards.add(new SetCardInfo("Squallmonger", 276, Rarity.UNCOMMON, mage.cards.s.Squallmonger.class)); - cards.add(new SetCardInfo("Squee, Goblin Nabob", 214, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class)); - cards.add(new SetCardInfo("Squeeze", 105, Rarity.RARE, mage.cards.s.Squeeze.class)); - cards.add(new SetCardInfo("Statecraft", 106, Rarity.RARE, mage.cards.s.Statecraft.class)); - cards.add(new SetCardInfo("Steadfast Guard", 50, Rarity.COMMON, mage.cards.s.SteadfastGuard.class)); - cards.add(new SetCardInfo("Stinging Barrier", 107, Rarity.COMMON, mage.cards.s.StingingBarrier.class)); - cards.add(new SetCardInfo("Stone Rain", 215, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Story Circle", 51, Rarity.UNCOMMON, mage.cards.s.StoryCircle.class)); - cards.add(new SetCardInfo("Strongarm Thug", 165, Rarity.COMMON, mage.cards.s.StrongarmThug.class)); - cards.add(new SetCardInfo("Subterranean Hangar", 329, Rarity.UNCOMMON, mage.cards.s.SubterraneanHangar.class)); - cards.add(new SetCardInfo("Sustenance", 278, Rarity.UNCOMMON, mage.cards.s.Sustenance.class)); - cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); - cards.add(new SetCardInfo("Task Force", 52, Rarity.COMMON, mage.cards.t.TaskForce.class)); - cards.add(new SetCardInfo("Tectonic Break", 216, Rarity.RARE, mage.cards.t.TectonicBreak.class)); - cards.add(new SetCardInfo("Territorial Dispute", 217, Rarity.RARE, mage.cards.t.TerritorialDispute.class)); - cards.add(new SetCardInfo("Thermal Glider", 53, Rarity.COMMON, mage.cards.t.ThermalGlider.class)); - cards.add(new SetCardInfo("Thieves' Auction", 218, Rarity.RARE, mage.cards.t.ThievesAuction.class)); - cards.add(new SetCardInfo("Thrashing Wumpus", 166, Rarity.RARE, mage.cards.t.ThrashingWumpus.class)); - cards.add(new SetCardInfo("Thwart", 108, Rarity.UNCOMMON, mage.cards.t.Thwart.class)); - cards.add(new SetCardInfo("Tidal Bore", 109, Rarity.COMMON, mage.cards.t.TidalBore.class)); - cards.add(new SetCardInfo("Tidal Kraken", 110, Rarity.RARE, mage.cards.t.TidalKraken.class)); - cards.add(new SetCardInfo("Tiger Claws", 279, Rarity.COMMON, mage.cards.t.TigerClaws.class)); - cards.add(new SetCardInfo("Tonic Peddler", 54, Rarity.UNCOMMON, mage.cards.t.TonicPeddler.class)); - cards.add(new SetCardInfo("Tooth of Ramos", 313, Rarity.RARE, mage.cards.t.ToothOfRamos.class)); - cards.add(new SetCardInfo("Tower of the Magistrate", 330, Rarity.RARE, mage.cards.t.TowerOfTheMagistrate.class)); - cards.add(new SetCardInfo("Trade Routes", 112, Rarity.RARE, mage.cards.t.TradeRoutes.class)); - cards.add(new SetCardInfo("Tranquility", 280, Rarity.COMMON, mage.cards.t.Tranquility.class)); - cards.add(new SetCardInfo("Tremor", 220, Rarity.COMMON, mage.cards.t.Tremor.class)); - cards.add(new SetCardInfo("Two-Headed Dragon", 221, Rarity.RARE, mage.cards.t.TwoHeadedDragon.class)); - cards.add(new SetCardInfo("Undertaker", 167, Rarity.COMMON, mage.cards.u.Undertaker.class)); - cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class)); - cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class)); - cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class)); - cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class)); - cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class)); - cards.add(new SetCardInfo("Vine Trellis", 285, Rarity.COMMON, mage.cards.v.VineTrellis.class)); - cards.add(new SetCardInfo("War Cadence", 224, Rarity.UNCOMMON, mage.cards.w.WarCadence.class)); - cards.add(new SetCardInfo("War Tax", 113, Rarity.UNCOMMON, mage.cards.w.WarTax.class)); - cards.add(new SetCardInfo("Warmonger", 225, Rarity.UNCOMMON, mage.cards.w.Warmonger.class)); - cards.add(new SetCardInfo("Waterfront Bouncer", 114, Rarity.COMMON, mage.cards.w.WaterfrontBouncer.class)); - cards.add(new SetCardInfo("Wave of Reckoning", 56, Rarity.RARE, mage.cards.w.WaveOfReckoning.class)); - cards.add(new SetCardInfo("Wild Jhovall", 227, Rarity.COMMON, mage.cards.w.WildJhovall.class)); - cards.add(new SetCardInfo("Word of Blasting", 228, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.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.cards.CardGraphicInfo; +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author North + */ +public class MercadianMasques extends ExpansionSet { + + private static final MercadianMasques instance = new MercadianMasques(); + + public static MercadianMasques getInstance() { + return instance; + } + + private MercadianMasques() { + super("Mercadian Masques", "MMQ", ExpansionSet.buildDate(1999, 8, 25), SetType.EXPANSION); + this.blockName = "Masques"; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Afterlife", 1, Rarity.UNCOMMON, mage.cards.a.Afterlife.class)); + cards.add(new SetCardInfo("Alabaster Wall", 2, Rarity.COMMON, mage.cards.a.AlabasterWall.class)); + cards.add(new SetCardInfo("Alley Grifters", 115, Rarity.COMMON, mage.cards.a.AlleyGrifters.class)); + cards.add(new SetCardInfo("Ancestral Mask", 229, Rarity.COMMON, mage.cards.a.AncestralMask.class)); + cards.add(new SetCardInfo("Armistice", 3, Rarity.RARE, mage.cards.a.Armistice.class)); + cards.add(new SetCardInfo("Arms Dealer", 172, Rarity.UNCOMMON, mage.cards.a.ArmsDealer.class)); + cards.add(new SetCardInfo("Arrest", 4, Rarity.UNCOMMON, mage.cards.a.Arrest.class)); + cards.add(new SetCardInfo("Ballista Squad", 5, Rarity.UNCOMMON, mage.cards.b.BallistaSquad.class)); + cards.add(new SetCardInfo("Balloon Peddler", 59, Rarity.COMMON, mage.cards.b.BalloonPeddler.class)); + cards.add(new SetCardInfo("Battle Rampart", 173, Rarity.COMMON, mage.cards.b.BattleRampart.class)); + cards.add(new SetCardInfo("Battle Squadron", 174, Rarity.RARE, mage.cards.b.BattleSquadron.class)); + cards.add(new SetCardInfo("Black Market", 116, Rarity.RARE, mage.cards.b.BlackMarket.class)); + cards.add(new SetCardInfo("Blaster Mage", 175, Rarity.COMMON, mage.cards.b.BlasterMage.class)); + cards.add(new SetCardInfo("Blockade Runner", 60, Rarity.COMMON, mage.cards.b.BlockadeRunner.class)); + cards.add(new SetCardInfo("Bog Smugglers", 117, Rarity.COMMON, mage.cards.b.BogSmugglers.class)); + cards.add(new SetCardInfo("Bog Witch", 118, Rarity.COMMON, mage.cards.b.BogWitch.class)); + cards.add(new SetCardInfo("Brainstorm", 61, Rarity.COMMON, mage.cards.b.Brainstorm.class)); + cards.add(new SetCardInfo("Bribery", 62, Rarity.RARE, mage.cards.b.Bribery.class)); + cards.add(new SetCardInfo("Buoyancy", 63, Rarity.COMMON, mage.cards.b.Buoyancy.class)); + cards.add(new SetCardInfo("Cackling Witch", 119, Rarity.UNCOMMON, mage.cards.c.CacklingWitch.class)); + cards.add(new SetCardInfo("Cateran Brute", 120, Rarity.COMMON, mage.cards.c.CateranBrute.class)); + cards.add(new SetCardInfo("Cateran Enforcer", 121, Rarity.UNCOMMON, mage.cards.c.CateranEnforcer.class)); + cards.add(new SetCardInfo("Cateran Kidnappers", 122, Rarity.UNCOMMON, mage.cards.c.CateranKidnappers.class)); + cards.add(new SetCardInfo("Cateran Overlord", 123, Rarity.RARE, mage.cards.c.CateranOverlord.class)); + cards.add(new SetCardInfo("Cateran Persuader", 124, Rarity.COMMON, mage.cards.c.CateranPersuader.class)); + cards.add(new SetCardInfo("Cateran Slaver", 125, Rarity.RARE, mage.cards.c.CateranSlaver.class)); + cards.add(new SetCardInfo("Cateran Summons", 126, Rarity.UNCOMMON, mage.cards.c.CateranSummons.class)); + cards.add(new SetCardInfo("Caustic Wasps", 234, Rarity.UNCOMMON, mage.cards.c.CausticWasps.class)); + cards.add(new SetCardInfo("Cave-In", 180, Rarity.RARE, mage.cards.c.CaveIn.class)); + cards.add(new SetCardInfo("Cavern Crawler", 181, Rarity.COMMON, mage.cards.c.CavernCrawler.class)); + cards.add(new SetCardInfo("Cave Sense", 179, Rarity.COMMON, mage.cards.c.CaveSense.class)); + cards.add(new SetCardInfo("Chambered Nautilus", 64, Rarity.UNCOMMON, mage.cards.c.ChamberedNautilus.class)); + cards.add(new SetCardInfo("Charisma", 66, Rarity.RARE, mage.cards.c.Charisma.class)); + cards.add(new SetCardInfo("Cho-Arrim Alchemist", 8, Rarity.RARE, mage.cards.c.ChoArrimAlchemist.class)); + cards.add(new SetCardInfo("Cho-Arrim Bruiser", 9, Rarity.RARE, mage.cards.c.ChoArrimBruiser.class)); + cards.add(new SetCardInfo("Cho-Arrim Legate", 10, Rarity.UNCOMMON, mage.cards.c.ChoArrimLegate.class)); + cards.add(new SetCardInfo("Cho-Manno, Revolutionary", 11, Rarity.RARE, mage.cards.c.ChoMannoRevolutionary.class)); + cards.add(new SetCardInfo("Cho-Manno's Blessing", 12, Rarity.COMMON, mage.cards.c.ChoMannosBlessing.class)); + cards.add(new SetCardInfo("Cinder Elemental", 183, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class)); + cards.add(new SetCardInfo("Close Quarters", 184, Rarity.UNCOMMON, mage.cards.c.CloseQuarters.class)); + cards.add(new SetCardInfo("Cloud Sprite", 67, Rarity.COMMON, mage.cards.c.CloudSprite.class)); + cards.add(new SetCardInfo("Coastal Piracy", 68, Rarity.UNCOMMON, mage.cards.c.CoastalPiracy.class)); + cards.add(new SetCardInfo("Collective Unconscious", 236, Rarity.RARE, mage.cards.c.CollectiveUnconscious.class)); + cards.add(new SetCardInfo("Conspiracy", 127, Rarity.RARE, mage.cards.c.Conspiracy.class)); + cards.add(new SetCardInfo("Corrupt Official", 128, Rarity.RARE, mage.cards.c.CorruptOfficial.class)); + cards.add(new SetCardInfo("Counterspell", 69, Rarity.COMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Cowardice", 70, Rarity.RARE, mage.cards.c.Cowardice.class)); + cards.add(new SetCardInfo("Crackdown", 15, Rarity.RARE, mage.cards.c.Crackdown.class)); + cards.add(new SetCardInfo("Crash", 186, Rarity.COMMON, mage.cards.c.Crash.class)); + cards.add(new SetCardInfo("Crenellated Wall", 290, Rarity.UNCOMMON, mage.cards.c.CrenellatedWall.class)); + cards.add(new SetCardInfo("Crossbow Infantry", 16, Rarity.COMMON, mage.cards.c.CrossbowInfantry.class)); + cards.add(new SetCardInfo("Crumbling Sanctuary", 292, Rarity.RARE, mage.cards.c.CrumblingSanctuary.class)); + cards.add(new SetCardInfo("Dark Ritual", 129, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Darting Merfolk", 72, Rarity.COMMON, mage.cards.d.DartingMerfolk.class)); + cards.add(new SetCardInfo("Dawnstrider", 237, Rarity.RARE, mage.cards.d.Dawnstrider.class)); + cards.add(new SetCardInfo("Deadly Insect", 238, Rarity.COMMON, mage.cards.d.DeadlyInsect.class)); + cards.add(new SetCardInfo("Deathgazer", 130, Rarity.UNCOMMON, mage.cards.d.Deathgazer.class)); + cards.add(new SetCardInfo("Deepwood Drummer", 239, Rarity.COMMON, mage.cards.d.DeepwoodDrummer.class)); + cards.add(new SetCardInfo("Deepwood Ghoul", 131, Rarity.COMMON, mage.cards.d.DeepwoodGhoul.class)); + cards.add(new SetCardInfo("Deepwood Legate", 132, Rarity.UNCOMMON, mage.cards.d.DeepwoodLegate.class)); + cards.add(new SetCardInfo("Deepwood Tantiv", 241, Rarity.UNCOMMON, mage.cards.d.DeepwoodTantiv.class)); + cards.add(new SetCardInfo("Deepwood Wolverine", 242, Rarity.COMMON, mage.cards.d.DeepwoodWolverine.class)); + cards.add(new SetCardInfo("Dehydration", 73, Rarity.COMMON, mage.cards.d.Dehydration.class)); + cards.add(new SetCardInfo("Desert Twister", 243, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class)); + cards.add(new SetCardInfo("Devout Witness", 17, Rarity.COMMON, mage.cards.d.DevoutWitness.class)); + cards.add(new SetCardInfo("Diplomatic Escort", 74, Rarity.UNCOMMON, mage.cards.d.DiplomaticEscort.class)); + cards.add(new SetCardInfo("Diplomatic Immunity", 75, Rarity.COMMON, mage.cards.d.DiplomaticImmunity.class)); + cards.add(new SetCardInfo("Disenchant", 18, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Distorting Lens", 293, Rarity.RARE, mage.cards.d.DistortingLens.class)); + cards.add(new SetCardInfo("Drake Hatchling", 76, Rarity.COMMON, mage.cards.d.DrakeHatchling.class)); + cards.add(new SetCardInfo("Dust Bowl", 316, Rarity.RARE, mage.cards.d.DustBowl.class)); + cards.add(new SetCardInfo("Embargo", 77, Rarity.RARE, mage.cards.e.Embargo.class)); + cards.add(new SetCardInfo("Energy Flux", 78, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class)); + cards.add(new SetCardInfo("Eye of Ramos", 294, Rarity.RARE, mage.cards.e.EyeOfRamos.class)); + cards.add(new SetCardInfo("False Demise", 80, Rarity.UNCOMMON, mage.cards.f.FalseDemise.class)); + cards.add(new SetCardInfo("Flailing Manticore", 187, Rarity.RARE, mage.cards.f.FlailingManticore.class)); + cards.add(new SetCardInfo("Flailing Ogre", 188, Rarity.UNCOMMON, mage.cards.f.FlailingOgre.class)); + cards.add(new SetCardInfo("Flailing Soldier", 189, Rarity.COMMON, mage.cards.f.FlailingSoldier.class)); + cards.add(new SetCardInfo("Food Chain", 246, Rarity.RARE, mage.cards.f.FoodChain.class)); + cards.add(new SetCardInfo("Forced March", 136, Rarity.RARE, mage.cards.f.ForcedMarch.class)); + cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Foster", 247, Rarity.RARE, mage.cards.f.Foster.class)); + cards.add(new SetCardInfo("Fountain of Cho", 317, Rarity.UNCOMMON, mage.cards.f.FountainOfCho.class)); + cards.add(new SetCardInfo("Fountain Watch", 19, Rarity.RARE, mage.cards.f.FountainWatch.class)); + cards.add(new SetCardInfo("Fresh Volunteers", 20, Rarity.COMMON, mage.cards.f.FreshVolunteers.class)); + cards.add(new SetCardInfo("Furious Assault", 191, Rarity.COMMON, mage.cards.f.FuriousAssault.class)); + cards.add(new SetCardInfo("Gerrard's Irregulars", 192, Rarity.COMMON, mage.cards.g.GerrardsIrregulars.class)); + cards.add(new SetCardInfo("Ghoul's Feast", 137, Rarity.UNCOMMON, mage.cards.g.GhoulsFeast.class)); + cards.add(new SetCardInfo("Giant Caterpillar", 249, Rarity.COMMON, mage.cards.g.GiantCaterpillar.class)); + cards.add(new SetCardInfo("Groundskeeper", 250, Rarity.UNCOMMON, mage.cards.g.Groundskeeper.class)); + cards.add(new SetCardInfo("Gush", 82, Rarity.COMMON, mage.cards.g.Gush.class)); + cards.add(new SetCardInfo("Hammer Mage", 193, Rarity.UNCOMMON, mage.cards.h.HammerMage.class)); + cards.add(new SetCardInfo("Haunted Crossroads", 138, Rarity.UNCOMMON, mage.cards.h.HauntedCrossroads.class)); + cards.add(new SetCardInfo("Heart of Ramos", 296, Rarity.RARE, mage.cards.h.HeartOfRamos.class)); + cards.add(new SetCardInfo("Henge Guardian", 297, Rarity.UNCOMMON, mage.cards.h.HengeGuardian.class)); + cards.add(new SetCardInfo("Henge of Ramos", 318, Rarity.UNCOMMON, mage.cards.h.HengeOfRamos.class)); + cards.add(new SetCardInfo("Hickory Woodlot", 319, Rarity.COMMON, mage.cards.h.HickoryWoodlot.class)); + cards.add(new SetCardInfo("High Market", 320, Rarity.RARE, mage.cards.h.HighMarket.class)); + cards.add(new SetCardInfo("High Seas", 83, Rarity.UNCOMMON, mage.cards.h.HighSeas.class)); + cards.add(new SetCardInfo("Highway Robber", 139, Rarity.COMMON, mage.cards.h.HighwayRobber.class)); + cards.add(new SetCardInfo("Hoodwink", 84, Rarity.COMMON, mage.cards.h.Hoodwink.class)); + cards.add(new SetCardInfo("Horned Troll", 251, Rarity.COMMON, mage.cards.h.HornedTroll.class)); + cards.add(new SetCardInfo("Horn of Plenty", 298, Rarity.RARE, mage.cards.h.HornOfPlenty.class)); + cards.add(new SetCardInfo("Horn of Ramos", 299, Rarity.RARE, mage.cards.h.HornOfRamos.class)); + cards.add(new SetCardInfo("Howling Wolf", 252, Rarity.COMMON, mage.cards.h.HowlingWolf.class)); + cards.add(new SetCardInfo("Hunted Wumpus", 253, Rarity.UNCOMMON, mage.cards.h.HuntedWumpus.class)); + cards.add(new SetCardInfo("Ignoble Soldier", 22, Rarity.UNCOMMON, mage.cards.i.IgnobleSoldier.class)); + cards.add(new SetCardInfo("Instigator", 140, Rarity.RARE, mage.cards.i.Instigator.class)); + cards.add(new SetCardInfo("Intimidation", 142, Rarity.UNCOMMON, mage.cards.i.Intimidation.class)); + cards.add(new SetCardInfo("Invigorate", 254, Rarity.COMMON, mage.cards.i.Invigorate.class)); + cards.add(new SetCardInfo("Iron Lance", 300, Rarity.UNCOMMON, mage.cards.i.IronLance.class)); + cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Ivory Mask", 24, Rarity.RARE, mage.cards.i.IvoryMask.class)); + cards.add(new SetCardInfo("Jhovall Queen", 25, Rarity.RARE, mage.cards.j.JhovallQueen.class)); + cards.add(new SetCardInfo("Jhovall Rider", 26, Rarity.UNCOMMON, mage.cards.j.JhovallRider.class)); + cards.add(new SetCardInfo("Kris Mage", 195, Rarity.COMMON, mage.cards.k.KrisMage.class)); + cards.add(new SetCardInfo("Kyren Glider", 196, Rarity.COMMON, mage.cards.k.KyrenGlider.class)); + cards.add(new SetCardInfo("Kyren Legate", 197, Rarity.UNCOMMON, mage.cards.k.KyrenLegate.class)); + cards.add(new SetCardInfo("Kyren Sniper", 199, Rarity.COMMON, mage.cards.k.KyrenSniper.class)); + cards.add(new SetCardInfo("Kyren Toy", 303, Rarity.RARE, mage.cards.k.KyrenToy.class)); + cards.add(new SetCardInfo("Land Grant", 255, Rarity.COMMON, mage.cards.l.LandGrant.class)); + cards.add(new SetCardInfo("Larceny", 143, Rarity.UNCOMMON, mage.cards.l.Larceny.class)); + cards.add(new SetCardInfo("Last Breath", 27, Rarity.UNCOMMON, mage.cards.l.LastBreath.class)); + cards.add(new SetCardInfo("Lava Runner", 200, Rarity.RARE, mage.cards.l.LavaRunner.class)); + cards.add(new SetCardInfo("Lightning Hounds", 201, Rarity.COMMON, mage.cards.l.LightningHounds.class)); + cards.add(new SetCardInfo("Lithophage", 202, Rarity.RARE, mage.cards.l.Lithophage.class)); + cards.add(new SetCardInfo("Lumbering Satyr", 257, Rarity.UNCOMMON, mage.cards.l.LumberingSatyr.class)); + cards.add(new SetCardInfo("Lunge", 203, Rarity.COMMON, mage.cards.l.Lunge.class)); + cards.add(new SetCardInfo("Lure", 258, Rarity.UNCOMMON, mage.cards.l.Lure.class)); + cards.add(new SetCardInfo("Maggot Therapy", 145, Rarity.COMMON, mage.cards.m.MaggotTherapy.class)); + cards.add(new SetCardInfo("Magistrate's Scepter", 304, Rarity.RARE, mage.cards.m.MagistratesScepter.class)); + cards.add(new SetCardInfo("Magistrate's Veto", 204, Rarity.UNCOMMON, mage.cards.m.MagistratesVeto.class)); + cards.add(new SetCardInfo("Mercadian Bazaar", 321, Rarity.UNCOMMON, mage.cards.m.MercadianBazaar.class)); + cards.add(new SetCardInfo("Midnight Ritual", 146, Rarity.RARE, mage.cards.m.MidnightRitual.class)); + cards.add(new SetCardInfo("Misdirection", 87, Rarity.RARE, mage.cards.m.Misdirection.class)); + cards.add(new SetCardInfo("Misshapen Fiend", 147, Rarity.COMMON, mage.cards.m.MisshapenFiend.class)); + cards.add(new SetCardInfo("Misstep", 88, Rarity.COMMON, mage.cards.m.Misstep.class)); + cards.add(new SetCardInfo("Molting Harpy", 148, Rarity.UNCOMMON, mage.cards.m.MoltingHarpy.class)); + cards.add(new SetCardInfo("Moment of Silence", 28, Rarity.COMMON, mage.cards.m.MomentOfSilence.class)); + cards.add(new SetCardInfo("Monkey Cage", 307, Rarity.RARE, mage.cards.m.MonkeyCage.class)); + cards.add(new SetCardInfo("Moonlit Wake", 29, Rarity.UNCOMMON, mage.cards.m.MoonlitWake.class)); + cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Muzzle", 30, Rarity.COMMON, mage.cards.m.Muzzle.class)); + cards.add(new SetCardInfo("Natural Affinity", 260, Rarity.RARE, mage.cards.n.NaturalAffinity.class)); + cards.add(new SetCardInfo("Nether Spirit", 149, Rarity.RARE, mage.cards.n.NetherSpirit.class)); + cards.add(new SetCardInfo("Nightwind Glider", 31, Rarity.COMMON, mage.cards.n.NightwindGlider.class)); + cards.add(new SetCardInfo("Noble Purpose", 32, Rarity.UNCOMMON, mage.cards.n.NoblePurpose.class)); + cards.add(new SetCardInfo("Notorious Assassin", 150, Rarity.RARE, mage.cards.n.NotoriousAssassin.class)); + cards.add(new SetCardInfo("Ogre Taskmaster", 206, Rarity.UNCOMMON, mage.cards.o.OgreTaskmaster.class)); + cards.add(new SetCardInfo("Overtaker", 89, Rarity.RARE, mage.cards.o.Overtaker.class)); + cards.add(new SetCardInfo("Pangosaur", 261, Rarity.RARE, mage.cards.p.Pangosaur.class)); + cards.add(new SetCardInfo("Peat Bog", 322, Rarity.COMMON, mage.cards.p.PeatBog.class)); + cards.add(new SetCardInfo("Pious Warrior", 34, Rarity.COMMON, mage.cards.p.PiousWarrior.class)); + cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Power Matrix", 309, Rarity.RARE, mage.cards.p.PowerMatrix.class)); + cards.add(new SetCardInfo("Primeval Shambler", 152, Rarity.UNCOMMON, mage.cards.p.PrimevalShambler.class)); + cards.add(new SetCardInfo("Pulverize", 207, Rarity.RARE, mage.cards.p.Pulverize.class)); + cards.add(new SetCardInfo("Puppet's Verdict", 208, Rarity.RARE, mage.cards.p.PuppetsVerdict.class)); + cards.add(new SetCardInfo("Quagmire Lamprey", 154, Rarity.UNCOMMON, mage.cards.q.QuagmireLamprey.class)); + cards.add(new SetCardInfo("Rain of Tears", 155, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); + cards.add(new SetCardInfo("Ramosian Captain", 35, Rarity.UNCOMMON, mage.cards.r.RamosianCaptain.class)); + cards.add(new SetCardInfo("Ramosian Commander", 36, Rarity.UNCOMMON, mage.cards.r.RamosianCommander.class)); + cards.add(new SetCardInfo("Ramosian Lieutenant", 37, Rarity.COMMON, mage.cards.r.RamosianLieutenant.class)); + cards.add(new SetCardInfo("Ramosian Rally", 38, Rarity.COMMON, mage.cards.r.RamosianRally.class)); + cards.add(new SetCardInfo("Ramosian Sergeant", 39, Rarity.COMMON, mage.cards.r.RamosianSergeant.class)); + cards.add(new SetCardInfo("Ramosian Sky Marshal", 40, Rarity.RARE, mage.cards.r.RamosianSkyMarshal.class)); + cards.add(new SetCardInfo("Rampart Crawler", 156, Rarity.COMMON, mage.cards.r.RampartCrawler.class)); + cards.add(new SetCardInfo("Rappelling Scouts", 41, Rarity.RARE, mage.cards.r.RappellingScouts.class)); + cards.add(new SetCardInfo("Remote Farm", 323, Rarity.COMMON, mage.cards.r.RemoteFarm.class)); + cards.add(new SetCardInfo("Revive", 262, Rarity.UNCOMMON, mage.cards.r.Revive.class)); + cards.add(new SetCardInfo("Righteous Aura", 45, Rarity.UNCOMMON, mage.cards.r.RighteousAura.class)); + cards.add(new SetCardInfo("Rishadan Airship", 91, Rarity.COMMON, mage.cards.r.RishadanAirship.class)); + cards.add(new SetCardInfo("Rishadan Brigand", 92, Rarity.RARE, mage.cards.r.RishadanBrigand.class)); + cards.add(new SetCardInfo("Rishadan Cutpurse", 93, Rarity.COMMON, mage.cards.r.RishadanCutpurse.class)); + cards.add(new SetCardInfo("Rishadan Footpad", 94, Rarity.UNCOMMON, mage.cards.r.RishadanFootpad.class)); + cards.add(new SetCardInfo("Rishadan Port", 324, Rarity.RARE, mage.cards.r.RishadanPort.class)); + cards.add(new SetCardInfo("Rock Badger", 210, Rarity.UNCOMMON, mage.cards.r.RockBadger.class)); + cards.add(new SetCardInfo("Rushwood Dryad", 263, Rarity.COMMON, mage.cards.r.RushwoodDryad.class)); + cards.add(new SetCardInfo("Rushwood Elemental", 264, Rarity.RARE, mage.cards.r.RushwoodElemental.class)); + cards.add(new SetCardInfo("Rushwood Grove", 325, Rarity.UNCOMMON, mage.cards.r.RushwoodGrove.class)); + cards.add(new SetCardInfo("Rushwood Herbalist", 265, Rarity.COMMON, mage.cards.r.RushwoodHerbalist.class)); + cards.add(new SetCardInfo("Rushwood Legate", 266, Rarity.UNCOMMON, mage.cards.r.RushwoodLegate.class)); + cards.add(new SetCardInfo("Saber Ants", 267, Rarity.UNCOMMON, mage.cards.s.SaberAnts.class)); + cards.add(new SetCardInfo("Sacred Prey", 268, Rarity.COMMON, mage.cards.s.SacredPrey.class)); + cards.add(new SetCardInfo("Sand Squid", 96, Rarity.RARE, mage.cards.s.SandSquid.class)); + cards.add(new SetCardInfo("Sandstone Needle", 326, Rarity.COMMON, mage.cards.s.SandstoneNeedle.class)); + cards.add(new SetCardInfo("Saprazzan Cove", 327, Rarity.UNCOMMON, mage.cards.s.SaprazzanCove.class)); + cards.add(new SetCardInfo("Saprazzan Heir", 99, Rarity.RARE, mage.cards.s.SaprazzanHeir.class)); + cards.add(new SetCardInfo("Saprazzan Legate", 100, Rarity.UNCOMMON, mage.cards.s.SaprazzanLegate.class)); + cards.add(new SetCardInfo("Saprazzan Raider", 102, Rarity.COMMON, mage.cards.s.SaprazzanRaider.class)); + cards.add(new SetCardInfo("Saprazzan Skerry", 328, Rarity.COMMON, mage.cards.s.SaprazzanSkerry.class)); + cards.add(new SetCardInfo("Seismic Mage", 211, Rarity.RARE, mage.cards.s.SeismicMage.class)); + cards.add(new SetCardInfo("Sever Soul", 159, Rarity.COMMON, mage.cards.s.SeverSoul.class)); + cards.add(new SetCardInfo("Shock Troops", 212, Rarity.COMMON, mage.cards.s.ShockTroops.class)); + cards.add(new SetCardInfo("Silverglade Elemental", 269, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class)); + cards.add(new SetCardInfo("Silverglade Pathfinder", 270, Rarity.UNCOMMON, mage.cards.s.SilvergladePathfinder.class)); + cards.add(new SetCardInfo("Sizzle", 213, Rarity.COMMON, mage.cards.s.Sizzle.class)); + cards.add(new SetCardInfo("Skulking Fugitive", 161, Rarity.COMMON, mage.cards.s.SkulkingFugitive.class)); + cards.add(new SetCardInfo("Skull of Ramos", 312, Rarity.RARE, mage.cards.s.SkullOfRamos.class)); + cards.add(new SetCardInfo("Snake Pit", 271, Rarity.UNCOMMON, mage.cards.s.SnakePit.class)); + cards.add(new SetCardInfo("Snorting Gahr", 272, Rarity.COMMON, mage.cards.s.SnortingGahr.class)); + cards.add(new SetCardInfo("Snuff Out", 162, Rarity.COMMON, mage.cards.s.SnuffOut.class)); + cards.add(new SetCardInfo("Soothing Balm", 48, Rarity.COMMON, mage.cards.s.SoothingBalm.class)); + cards.add(new SetCardInfo("Soothsaying", 104, Rarity.UNCOMMON, mage.cards.s.Soothsaying.class)); + cards.add(new SetCardInfo("Soul Channeling", 163, Rarity.COMMON, mage.cards.s.SoulChanneling.class)); + cards.add(new SetCardInfo("Specter's Wail", 164, Rarity.COMMON, mage.cards.s.SpectersWail.class)); + cards.add(new SetCardInfo("Spidersilk Armor", 273, Rarity.COMMON, mage.cards.s.SpidersilkArmor.class)); + cards.add(new SetCardInfo("Spontaneous Generation", 274, Rarity.RARE, mage.cards.s.SpontaneousGeneration.class)); + cards.add(new SetCardInfo("Squall", 275, Rarity.COMMON, mage.cards.s.Squall.class)); + cards.add(new SetCardInfo("Squallmonger", 276, Rarity.UNCOMMON, mage.cards.s.Squallmonger.class)); + cards.add(new SetCardInfo("Squee, Goblin Nabob", 214, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class)); + cards.add(new SetCardInfo("Squeeze", 105, Rarity.RARE, mage.cards.s.Squeeze.class)); + cards.add(new SetCardInfo("Statecraft", 106, Rarity.RARE, mage.cards.s.Statecraft.class)); + cards.add(new SetCardInfo("Steadfast Guard", 50, Rarity.COMMON, mage.cards.s.SteadfastGuard.class)); + cards.add(new SetCardInfo("Stinging Barrier", 107, Rarity.COMMON, mage.cards.s.StingingBarrier.class)); + cards.add(new SetCardInfo("Stone Rain", 215, Rarity.COMMON, mage.cards.s.StoneRain.class)); + cards.add(new SetCardInfo("Story Circle", 51, Rarity.UNCOMMON, mage.cards.s.StoryCircle.class)); + cards.add(new SetCardInfo("Strongarm Thug", 165, Rarity.COMMON, mage.cards.s.StrongarmThug.class)); + cards.add(new SetCardInfo("Subterranean Hangar", 329, Rarity.UNCOMMON, mage.cards.s.SubterraneanHangar.class)); + cards.add(new SetCardInfo("Sustenance", 278, Rarity.UNCOMMON, mage.cards.s.Sustenance.class)); + cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(null, true))); + cards.add(new SetCardInfo("Task Force", 52, Rarity.COMMON, mage.cards.t.TaskForce.class)); + cards.add(new SetCardInfo("Tectonic Break", 216, Rarity.RARE, mage.cards.t.TectonicBreak.class)); + cards.add(new SetCardInfo("Territorial Dispute", 217, Rarity.RARE, mage.cards.t.TerritorialDispute.class)); + cards.add(new SetCardInfo("Thermal Glider", 53, Rarity.COMMON, mage.cards.t.ThermalGlider.class)); + cards.add(new SetCardInfo("Thieves' Auction", 218, Rarity.RARE, mage.cards.t.ThievesAuction.class)); + cards.add(new SetCardInfo("Thrashing Wumpus", 166, Rarity.RARE, mage.cards.t.ThrashingWumpus.class)); + cards.add(new SetCardInfo("Thwart", 108, Rarity.UNCOMMON, mage.cards.t.Thwart.class)); + cards.add(new SetCardInfo("Tidal Bore", 109, Rarity.COMMON, mage.cards.t.TidalBore.class)); + cards.add(new SetCardInfo("Tidal Kraken", 110, Rarity.RARE, mage.cards.t.TidalKraken.class)); + cards.add(new SetCardInfo("Tiger Claws", 279, Rarity.COMMON, mage.cards.t.TigerClaws.class)); + cards.add(new SetCardInfo("Tonic Peddler", 54, Rarity.UNCOMMON, mage.cards.t.TonicPeddler.class)); + cards.add(new SetCardInfo("Tooth of Ramos", 313, Rarity.RARE, mage.cards.t.ToothOfRamos.class)); + cards.add(new SetCardInfo("Tower of the Magistrate", 330, Rarity.RARE, mage.cards.t.TowerOfTheMagistrate.class)); + cards.add(new SetCardInfo("Trade Routes", 112, Rarity.RARE, mage.cards.t.TradeRoutes.class)); + cards.add(new SetCardInfo("Tranquility", 280, Rarity.COMMON, mage.cards.t.Tranquility.class)); + cards.add(new SetCardInfo("Tremor", 220, Rarity.COMMON, mage.cards.t.Tremor.class)); + cards.add(new SetCardInfo("Two-Headed Dragon", 221, Rarity.RARE, mage.cards.t.TwoHeadedDragon.class)); + cards.add(new SetCardInfo("Undertaker", 167, Rarity.COMMON, mage.cards.u.Undertaker.class)); + cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class)); + cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class)); + cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class)); + cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class)); + cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class)); + cards.add(new SetCardInfo("Vine Trellis", 285, Rarity.COMMON, mage.cards.v.VineTrellis.class)); + cards.add(new SetCardInfo("War Cadence", 224, Rarity.UNCOMMON, mage.cards.w.WarCadence.class)); + cards.add(new SetCardInfo("War Tax", 113, Rarity.UNCOMMON, mage.cards.w.WarTax.class)); + cards.add(new SetCardInfo("Warmonger", 225, Rarity.UNCOMMON, mage.cards.w.Warmonger.class)); + cards.add(new SetCardInfo("Waterfront Bouncer", 114, Rarity.COMMON, mage.cards.w.WaterfrontBouncer.class)); + cards.add(new SetCardInfo("Wave of Reckoning", 56, Rarity.RARE, mage.cards.w.WaveOfReckoning.class)); + cards.add(new SetCardInfo("Wild Jhovall", 227, Rarity.COMMON, mage.cards.w.WildJhovall.class)); + cards.add(new SetCardInfo("Word of Blasting", 228, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index 4afdc932c61..b546cde03e9 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -169,6 +169,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 302, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true))); cards.add(new SetCardInfo("Myr Adapter", 210, Rarity.COMMON, mage.cards.m.MyrAdapter.class)); cards.add(new SetCardInfo("Myr Enforcer", 211, Rarity.COMMON, mage.cards.m.MyrEnforcer.class)); + cards.add(new SetCardInfo("Myr Incubator", 212, Rarity.RARE, mage.cards.m.MyrIncubator.class)); cards.add(new SetCardInfo("Myr Mindservant", 213, Rarity.UNCOMMON, mage.cards.m.MyrMindservant.class)); cards.add(new SetCardInfo("Myr Retriever", 215, Rarity.UNCOMMON, mage.cards.m.MyrRetriever.class)); cards.add(new SetCardInfo("Necrogen Mists", 69, Rarity.RARE, mage.cards.n.NecrogenMists.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java index 7d0cc9d1047..06737b84159 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java @@ -27,7 +27,6 @@ */ package org.mage.test.cards.abilities.keywords; -import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.permanent.Permanent; @@ -109,7 +108,7 @@ public class BestowTest extends CardTestPlayerBase { // because Boon Satyr is no creature on the battlefield, evolve may not trigger assertPermanentCount(playerA, "Boon Satyr", 1); Permanent boonSatyr = getPermanent("Boon Satyr", playerA); - Assert.assertTrue("Boon Satyr may not be a creature", !boonSatyr.getCardType().contains(CardType.CREATURE)); + Assert.assertTrue("Boon Satyr may not be a creature", !boonSatyr.isCreature()); assertPermanentCount(playerA, "Silent Artisan", 1); assertPermanentCount(playerA, "Experiment One", 1); assertPowerToughness(playerA, "Experiment One", 1, 1); @@ -145,8 +144,8 @@ public class BestowTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Hopeful Eidolon", 1, 1); Permanent hopefulEidolon = getPermanent("Hopeful Eidolon", playerA); - Assert.assertTrue("Hopeful Eidolon has to be a creature but is not", hopefulEidolon.getCardType().contains(CardType.CREATURE)); - Assert.assertTrue("Hopeful Eidolon has to be an enchantment but is not", hopefulEidolon.getCardType().contains(CardType.ENCHANTMENT)); + Assert.assertTrue("Hopeful Eidolon has to be a creature but is not", hopefulEidolon.isCreature()); + Assert.assertTrue("Hopeful Eidolon has to be an enchantment but is not", hopefulEidolon.isEnchantment()); } @@ -360,7 +359,7 @@ public class BestowTest extends CardTestPlayerBase { assertPowerToughness(playerB, "Nighthowler", 2, 2); Permanent nighthowler = getPermanent("Nighthowler", playerB); - Assert.assertEquals("Nighthowler has to be a creature", true, nighthowler.getCardType().contains(CardType.CREATURE)); + Assert.assertEquals("Nighthowler has to be a creature", true, nighthowler.isCreature()); } @Test diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/FlashbackTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/FlashbackTest.java index 92db2b6c7f9..54e9d836173 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/FlashbackTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/FlashbackTest.java @@ -427,14 +427,14 @@ public class FlashbackTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback"); // Flashback blitz - setChoice(playerA, "X=2"); + setChoice(playerA, "X=1"); addTarget(playerA, mountain); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); assertExileCount(playerA, fCatBlitz, 1); - assertGraveyardCount(playerA, mountain, 2); - assertPermanentCount(playerA, "Elemental Cat", 2); + assertPermanentCount(playerA, "Elemental Cat", 1); + assertGraveyardCount(playerA, mountain, 1); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SoulBurnTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SoulBurnTest.java new file mode 100644 index 00000000000..29140f0313e --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/SoulBurnTest.java @@ -0,0 +1,179 @@ +package org.mage.test.cards.abilities.oneshot.damage; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author Johnny E. Hastings + */ +public class SoulBurnTest extends CardTestPlayerBase { + + @Test + public void testDamageOpponentAllBlackMana() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", playerB); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertLife(playerA, 22); + assertLife(playerB, 18); + } + + @Test + public void testDamageOpponentOneBlackFourRedMana() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", playerB); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertLife(playerA, 20); + assertLife(playerB, 18); + } + + @Test + public void testDamageOpponentAllKindsOfMana() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", playerB); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertLife(playerA, 21); + assertLife(playerB, 17); + } + + @Test + public void testDamageSelfAllSwamps() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", playerA); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertLife(playerA, 20); + assertLife(playerB, 20); + } + + @Test + public void testDamageSelfWithSwampsAndMountains() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", playerA); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertLife(playerA, 18); + assertLife(playerB, 20); + } + + @Test + public void testDamageSmallCreatureAllSwamps() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + addCard(Zone.BATTLEFIELD, playerB, "Bog Imp"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", "Bog Imp"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertPermanentCount(playerB, "Bog Imp", 0); + assertLife(playerA, 21); + assertLife(playerB, 20); + } + + @Test + public void testDamageSmallCreatureSwampsAndMountains() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + addCard(Zone.BATTLEFIELD, playerB, "Bog Imp"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", "Bog Imp"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertPermanentCount(playerB, "Bog Imp", 0); + assertLife(playerA, 20); + assertLife(playerB, 20); + } + + @Test + public void testDamageBigCreatureAllSwamps() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", "Craw Wurm"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertPermanentCount(playerB, "Craw Wurm", 1); + assertLife(playerA, 22); + assertLife(playerB, 20); + } + + @Test + public void testDamageBigCreatureSwampsAndMountains() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + addCard(Zone.HAND, playerA, "Soul Burn"); + + addCard(Zone.BATTLEFIELD, playerB, "Craw Wurm"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Burn", "Craw Wurm"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertPermanentCount(playerB, "Craw Wurm", 1); + assertLife(playerA, 21); + assertLife(playerB, 20); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java index 22427aa16c8..1a0462e4ace 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/EndTurnEffectTest.java @@ -55,6 +55,9 @@ public class EndTurnEffectTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Sphinx's Tutelage"); // Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. If it's your turn, end the turn. + // (Exile all spells and abilities on the stack, including this card. + // Discard down to your maximum hand size. Damage wears off, and + // "this turn" and "until end of turn" effects end.) addCard(Zone.HAND, playerA, "Day's Undoing"); //Sorcery {2}{U} castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Day's Undoing"); @@ -67,8 +70,42 @@ public class EndTurnEffectTest extends CardTestPlayerBase { assertHandCount(playerA, 7); assertHandCount(playerB, 7); - assertGraveyardCount(playerB, 0); // because the trigegrs of Sphinx's Tutelage cease to exist + assertGraveyardCount(playerB, 0); // because the triggers of Sphinx's Tutelage cease to exist } + @Test + public void testSpellSplitCard() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 6); + + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + + // End the turn. + // (Exile all spells and abilities on the stack, including this card. + // Discard down to your maximum hand size. Damage wears off, and + // "this turn" and "until end of turn" effects end.) + addCard(Zone.HAND, playerA, "Time Stop"); //Instant {4}{U}{U} + + addCard(Zone.BATTLEFIELD, playerB, "Island", 2); + // Fire + // Fire deals 2 damage divided as you choose among one or two target creatures and/or players. + // Ice + // Tap target permanent. Draw a card. + addCard(Zone.HAND, playerB, "Fire // Ice"); // Instant {1}{R} // {1}{U} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Ice", "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Time Stop", NO_TARGET, "Ice"); + + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertHandCount(playerB, "Fire // Ice", 0); + assertExileCount(playerA, "Time Stop", 1); + assertExileCount(playerB, "Fire // Ice", 1); + assertTapped("Silvercoat Lion", false); + assertHandCount(playerA, 0); + assertHandCount(playerB, 0); + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/BattlefieldTriggeredAbilitiesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/BattlefieldTriggeredAbilitiesTest.java index d9340ed3756..7544e1de022 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/BattlefieldTriggeredAbilitiesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/BattlefieldTriggeredAbilitiesTest.java @@ -1,6 +1,5 @@ package org.mage.test.cards.control; -import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.permanent.Permanent; @@ -47,7 +46,7 @@ public class BattlefieldTriggeredAbilitiesTest extends CardTestPlayerBase { int playerACount = 0; int playerBCount = 0; for (Permanent p : currentGame.getBattlefield().getAllActivePermanents()) { - if (p.getCardType().contains(CardType.LAND)) { + if (p.isLand()) { if (p.getControllerId().equals(playerB.getId())) { playerBCount++; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java index 258f9ef0bfd..fe8749ad39f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/ProgenitorMimicTest.java @@ -1,6 +1,5 @@ package org.mage.test.cards.copy; -import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.filter.Filter; @@ -42,7 +41,7 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { int nonTokens = 0; for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) { if (permanent.getControllerId().equals(playerB.getId())) { - if (permanent.getCardType().contains(CardType.CREATURE)) { + if (permanent.isCreature()) { if (permanent instanceof PermanentToken) { tokens++; } else { @@ -122,7 +121,7 @@ public class ProgenitorMimicTest extends CardTestPlayerBase { int nonTokens = 0; for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) { if (permanent.getControllerId().equals(playerB.getId())) { - if (permanent.getCardType().contains(CardType.CREATURE)) { + if (permanent.isCreature()) { if (permanent instanceof PermanentToken) { tokens++; } else { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java index ce3903687bb..2c7a35b08c2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/NykthosShrineToNyxTest.java @@ -51,13 +51,13 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { // Green mana doesn't empty from your mana pool as steps and phases end. // Omnath, Locus of Mana gets +1/+1 for each green mana in your mana pool. addCard(Zone.BATTLEFIELD, playerA, "Omnath, Locus of Mana", 1); - + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); - + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); execute(); - + Assert.assertEquals("message", 6, playerA.getManaPool().getGreen()); // 6 green mana assertPowerToughness(playerA, "Omnath, Locus of Mana", 7, 7); } @@ -78,7 +78,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.","Nykthos, Shrine to Nyx"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); @@ -87,12 +87,12 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { execute(); Assert.assertEquals("amount of green mana", 10, playerA.getManaPool().getGreen()); // 6G - 2G = 4G + 6G = 10G - assertPowerToughness(playerA, "Omnath, Locus of Mana", 11,11); + assertPowerToughness(playerA, "Omnath, Locus of Mana", 11, 11); } + /* Use Nykthos together with Kruphix, God of Horizons to save mana as colorless mana - */ - + */ @Test public void testDoubleUseWithKruphix() { addCard(Zone.BATTLEFIELD, playerA, "Island", 2); // to use Nykthos @@ -109,7 +109,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); - activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.","Nykthos, Shrine to Nyx"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Untap another target permanent.", "Nykthos, Shrine to Nyx"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); @@ -117,8 +117,8 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - Assert.assertEquals("amount of colorless mana", 10, playerA.getManaPool().getColorless()); // 6 - 2 (2.Activation) = 4 + 6 = 10 colorless mana - assertPowerToughness(playerA, "Kruphix, God of Horizons", 4,7); + Assert.assertEquals("amount of colorless mana", 10, playerA.getManaPool().getColorless()); // 6 - 2 (2.Activation) = 4 + 6 = 10 colorless mana + assertPowerToughness(playerA, "Kruphix, God of Horizons", 4, 7); } @Test @@ -145,7 +145,7 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { activateManaAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); setChoice(playerA, "Green"); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -153,4 +153,70 @@ public class NykthosShrineToNyxTest extends CardTestPlayerBase { Assert.assertEquals("amount of green mana", 5, playerA.getManaPool().getGreen()); // 6 green mana assertPowerToughness(playerA, "Omnath, Locus of Mana", 6, 6); } + + @Test + public void testNykthosDevotionAccurate() { + + /* + Nykthos, Shrine to Nyx + Legendary Land + {T}: Add {1} to your mana pool. + {2}, {T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color. + */ + String nykthos = "Nykthos, Shrine to Nyx"; + + /* + Stronghold Assassin {1}{B}{B} + Creature — Zombie Assassin 2/1 + {T}, Sacrifice a creature: Destroy target nonblack creature. + */ + String sAssassin = "Stronghold Assassin"; + + /* + Graf Harvest {B} + Enchantment + Zombies you control have menace. (They can't be blocked except by two or more creatures.) + {3}{B}, Exile a creature card from your graveyard: Create a 2/2 black Zombie creature token. + */ + String gHarvest = "Graf Harvest"; + + /* + Erebos, God of the Dead {3}{B} + Legendary Enchantment Creature — God 5/7 + Indestructible + As long as your devotion to black is less than five, Erebos isn't a creature. + Your opponents can't gain life. + {1}{B}, Pay 2 life: Draw a card. + */ + String erebos = "Erebos, God of the Dead"; + + /* + Phyrexian Obliterator {B}{B}{B}{B} + Creature — Horror + Trample + Whenever a source deals damage to Phyrexian Obliterator, that source's controller sacrifices that many permanents. + */ + String pObliterator = "Phyrexian Obliterator"; + + addCard(Zone.BATTLEFIELD, playerA, nykthos); + addCard(Zone.BATTLEFIELD, playerA, sAssassin); + addCard(Zone.BATTLEFIELD, playerA, gHarvest); + addCard(Zone.BATTLEFIELD, playerA, erebos); + addCard(Zone.BATTLEFIELD, playerA, "Wastes", 2); // two colorless to pay for nykthos + addCard(Zone.HAND, playerA, pObliterator); // just for something to cast for 4 black mana + + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2},{T}: Choose a color. Add to your mana pool an amount of mana of that color equal to your devotion to that color."); + setChoice(playerA, "Black"); // should produce 4 black mana + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pObliterator); // costs exactly 4 black mana should be castable + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertTappedCount("Wastes", true, 2); + assertTapped(nykthos, true); + // Assert.assertEquals("amount of black mana", 4, playerA.getManaPool().getBlack()); // should be 4 black mana + assertHandCount(playerA, pObliterator, 0); + assertPermanentCount(playerA, pObliterator, 1); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SpendManaAsThoughItWereManaOfAnyColorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SpendManaAsThoughItWereManaOfAnyColorTest.java index 0743a0962e6..6673dc09721 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/SpendManaAsThoughItWereManaOfAnyColorTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/SpendManaAsThoughItWereManaOfAnyColorTest.java @@ -29,6 +29,7 @@ package org.mage.test.cards.mana; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -69,4 +70,63 @@ public class SpendManaAsThoughItWereManaOfAnyColorTest extends CardTestPlayerBas } + /** + * Celestial Dawn does not allow spending of off-color mana for any purpose. + * Had a Black Market down, was trying to cast Darksteel Forge, could not + * spend the black mana on the forge. + */ + @Test + public void testCelestialDawn() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); + // Lands you control are Plains. + // Nonland cards you own that aren't on the battlefield, spells you control, and nonland permanents you control are white. + // You may spend white mana as though it were mana of any color. + // You may spend other mana only as though it were colorless mana. + addCard(Zone.BATTLEFIELD, playerA, "Celestial Dawn", 1); + + // Whenever a creature dies, put a charge counter on Black Market. + // At the beginning of your precombat main phase, add {B} to your mana pool for each charge counter on Black Market. + addCard(Zone.BATTLEFIELD, playerA, "Black Market", 1); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + + // Artifacts you control are indestructible. + addCard(Zone.HAND, playerA, "Darksteel Forge", 1); // Artifact {9} + + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + + castSpell(1, PhaseStep.UPKEEP, playerB, "Lightning Bolt", "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Darksteel Forge"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertCounterCount("Black Market", CounterType.CHARGE, 1); + + assertPermanentCount(playerA, "Darksteel Forge", 1); + + } + + @Test + public void testCelestialDawnAny() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + // Lands you control are Plains. + // Nonland cards you own that aren't on the battlefield, spells you control, and nonland permanents you control are white. + // You may spend white mana as though it were mana of any color. + // You may spend other mana only as though it were colorless mana. + addCard(Zone.BATTLEFIELD, playerA, "Celestial Dawn", 1); + + addCard(Zone.HAND, playerA, "Vedalken Mastermind", 1); // Creature {U}{U} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vedalken Mastermind"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Vedalken Mastermind", 1); + + } } 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 index 2555155884a..50fc886cf52 100644 --- 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 @@ -95,4 +95,48 @@ public class DamageEffectsTest extends CardTestPlayerBase { assertLife(playerA, 32); } + + @Test + public void vexingDevilFurnaceRathRedirectToPlaneswalker() { + + /* + Vexing Devil {R} + Creature — Devil + When Vexing Devil enters the battlefield, any opponent may have it deal 4 damage to him or her. If a player does, sacrifice Vexing Devil. + */ + String vDevil = "Vexing Devil"; + + /* + Nissa, Worldwaker {3}{G}{G} + Planeswalker — Nissa + +1: Target land you control becomes a 4/4 Elemental creature with trample. It's still a land. + +1: Untap up to four target Forests. + −7: Search your library for any number of basic land cards, put them onto the battlefield, then shuffle your library. Those lands become 4/4 Elemental creatures with trample. They're still lands. + */ + String nissa = "Nissa, Worldwaker"; + + /* + Furnace of Rath {1}{R}{R}{R} + Enchantment + If a source would deal damage to a creature or player, it deals double that damage to that creature or player instead. + */ + addCard(Zone.BATTLEFIELD, playerB, "Furnace of Rath"); + addCard(Zone.HAND, playerB, vDevil); + addCard(Zone.HAND, playerA, nissa); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 5); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nissa); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, vDevil); + setChoice(playerA, "Yes"); // deal 8 damage to playerA and sac vexing devil (8 due to furnace) + setChoice(playerB, "Yes"); // redirect to planeswalker + addTarget(playerB, nissa); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, vDevil, 1); + assertLife(playerA, 20); + assertGraveyardCount(playerA, nissa, 1); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DrawEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DrawEffectsTest.java index 58548cfc8e9..59a07848015 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DrawEffectsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/DrawEffectsTest.java @@ -52,7 +52,7 @@ public class DrawEffectsTest extends CardTestPlayerBase { setStopAt(2, PhaseStep.PRECOMBAT_MAIN); execute(); - Assert.assertEquals("Player B has to have 4 cards in hand", 8, playerB.getHand().size()); + Assert.assertEquals("Player B has to have 8 cards in hand", 8, playerB.getHand().size()); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/HardenedScaleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/HardenedScaleTest.java new file mode 100644 index 00000000000..fe4424442c6 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/entersBattlefield/HardenedScaleTest.java @@ -0,0 +1,142 @@ +/* + * 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.entersBattlefield; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class HardenedScaleTest extends CardTestPlayerBase { + + /* + Reported bug: Hangarback interaciton with Hardened Scales and Metallic Mimic on board is incorrect. + */ + @Test + public void hangarBackHardenedScalesMetallicMimicTest() { + + /* + Hangarback Walker {X}{X} + Artifact Creature — Construct 0/0 + Hangarback Walker enters the battlefield with X +1/+1 counters on it. + When Hangarback Walker dies, create a 1/1 colorless Thopter artifact creature token with flying for each +1/+1 counter on Hangarback Walker. + {1}, {T}: Put a +1/+1 counter on Hangarback Walker. + */ + String hWalker = "Hangarback Walker"; + + /* + Hardened Scales {G} + Enchantment + If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead. + */ + String hScales = "Hardened Scales"; + + /* + Metallic Mimic {2} + Artifact Creature — Shapeshifter 2/1 + As Metallic Mimic enters the battlefield, choose a creature type. + Metallic Mimic is the chosen type in addition to its other types. + Each other creature you control of the chosen type enters the battlefield with an additional +1/+1 counter on it. + */ + String mMimic = "Metallic Mimic"; + + addCard(Zone.BATTLEFIELD, playerA, hScales); + addCard(Zone.HAND, playerA, mMimic); + addCard(Zone.HAND, playerA, hWalker); + addCard(Zone.BATTLEFIELD, playerA, "Wastes", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mMimic); + setChoice(playerA, "Construct"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hWalker); + setChoice(playerA, "X=1"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, mMimic, 1); + assertPermanentCount(playerA, hWalker, 1); + assertCounterCount(playerA, hWalker, CounterType.P1P1, 3); + assertPowerToughness(playerA, hWalker, 3, 3); + } + + @Test + public void testWithVigorMortis() { + + /* + Vigor Mortis {2}{B}{B} + Sorcery + Return target creature card from your graveyard to the battlefield. If {G} was spent to cast Vigor Mortis, + that creature enters the battlefield with an additional +1/+1 counter on it. + */ + String vMortis = "Vigor Mortis"; + + /* + Hardened Scales {G} + Enchantment + If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead. + */ + String hScales = "Hardened Scales"; + + /* + Metallic Mimic {2} + Artifact Creature — Shapeshifter 2/1 + As Metallic Mimic enters the battlefield, choose a creature type. + Metallic Mimic is the chosen type in addition to its other types. + Each other creature you control of the chosen type enters the battlefield with an additional +1/+1 counter on it. + */ + String mMimic = "Metallic Mimic"; + + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, hScales); + addCard(Zone.HAND, playerA, mMimic); + addCard(Zone.HAND, playerA, vMortis); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mMimic); + setChoice(playerA, "Cat"); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, vMortis, "Silvercoat Lion"); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, mMimic, 1); + + assertPermanentCount(playerA, "Silvercoat Lion", 1); + assertCounterCount(playerA, "Silvercoat Lion", CounterType.P1P1, 3); + assertPowerToughness(playerA, "Silvercoat Lion", 5, 5); // Hardened Scales is only once applied to EntersTheBattlefield event + assertGraveyardCount(playerA, vMortis, 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java index 3949a11ee01..f5b8e3b1410 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java @@ -40,17 +40,18 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { /** * Theres a Chalice of the Void with 1 counter in play under my control. - * Then I cast second chalice with x=1. For spells on the stack the cmc is the base CMC + X value * {X} in casting costs on top right of card. - * So cmc should be 2 in this case, it shouldnt be countered. + * Then I cast second chalice with x=1. For spells on the stack the cmc is + * the base CMC + X value * {X} in casting costs on top right of card. So + * cmc should be 2 in this case, it shouldnt be countered. * http://boardgames.stackexchange.com/questions/7327/what-is-the-converted-mana-cost-of-a-spell-with-x-when-cast-with-the-miracle-m */ - @Test public void testX1CountsFor2CMC() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + // Chalice of the Void enters the battlefield with X charge counters on it. + // Whenever a player casts a spell with converted mana cost equal to the number of charge counters on Chalice of the Void, counter that spell. addCard(Zone.HAND, playerA, "Chalice of the Void", 2); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); setChoice(playerA, "X=1"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); @@ -62,10 +63,10 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Chalice of the Void", 2); } - + /* If X=1 the cmc of Chalice on the stack is 2. So it can't be countered by Mental Misstep - */ + */ @Test public void testCantBeCounteredByMentalMisstep() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); @@ -94,6 +95,8 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); addCard(Zone.HAND, playerA, "Chalice of the Void", 1); + // Conflagrate deals X damage divided as you choose among any number of target creatures and/or players. + // Flashback-{R}{R}, Discard X cards. addCard(Zone.GRAVEYARD, playerB, "Conflagrate", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); addCard(Zone.HAND, playerB, "Mountain", 1); @@ -101,7 +104,6 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); setChoice(playerA, "X=1"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flashback {R}{R}"); setChoice(playerB, "X=1"); addTarget(playerB, playerA); @@ -109,13 +111,12 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); - assertLife(playerA, 19); - assertLife(playerB, 20); - assertExileCount(playerB, "Conflagrate", 1); //TODO: Apparently there are two mountains in the graveyard at the end of the test now. - //assertGraveyardCount(playerB, "Mountain", 1); + assertGraveyardCount(playerB, "Mountain", 1); + assertLife(playerA, 19); + assertLife(playerB, 20); } - + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/HeliodGodOfTheSun.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/HeliodGodOfTheSun.java index b4af708cb2d..a6abc84f1c1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/HeliodGodOfTheSun.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/HeliodGodOfTheSun.java @@ -4,7 +4,6 @@ */ package org.mage.test.cards.single.ths; -import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.permanent.Permanent; @@ -47,7 +46,7 @@ public class HeliodGodOfTheSun extends CardTestPlayerBase { assertPermanentCount(playerA, "Hold the Gates", 1); Permanent heliodGodOfTheSun = getPermanent("Heliod, God of the Sun", playerA); - Assert.assertTrue(heliodGodOfTheSun.getCardType().contains(CardType.CREATURE)); + Assert.assertTrue(heliodGodOfTheSun.isCreature()); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EntersTheBattlefieldTriggerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EntersTheBattlefieldTriggerTest.java index 6ab63a3331e..4a5409b5547 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EntersTheBattlefieldTriggerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/EntersTheBattlefieldTriggerTest.java @@ -312,14 +312,14 @@ public class EntersTheBattlefieldTriggerTest extends CardTestPlayerBase { /* * playerA's Carnivorous Plant will get -1/-1 from Noxious Ghoul -> 3/4 * playerB's Carnivorous Plant will get -1/-1 from Noxious Ghoul -> 3/4 - */ + */ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Clone"); setChoice(playerA, "Noxious Ghoul"); /* * playerA's Carnivorous Plant will get -1/-1 from Clone -> 2/3 * playerB's Carnivorous Plant will get -1/-1 from Clone -> 2/3 - */ + */ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Ego Erasure", "targetPlayer=PlayerA", "Whenever"); /* * playerA' Noxious Ghoul will get -2/0 -> 1/3 @@ -328,7 +328,7 @@ public class EntersTheBattlefieldTriggerTest extends CardTestPlayerBase { * playerA' Noxious Ghoul will get -1/-1 from itself -> -1/1 * playerA's Carnivorous Plant will get -1/-1 from Noxious Ghoul -> -1/2 * playerB's Carnivorous Plant will get -1/-1 from Noxious Ghoul -> 1/2 - */ + */ setStopAt(1, PhaseStep.END_TURN); execute(); @@ -341,21 +341,22 @@ public class EntersTheBattlefieldTriggerTest extends CardTestPlayerBase { assertPowerToughness(playerB, "Carnivorous Plant", 1, 2); assertPowerToughness(playerA, "Carnivorous Plant", -1, 2); } - + @Test public void testHearthcageGiant() { // {6}{R}{R} Creature — Giant Warrior //When Hearthcage Giant enters the battlefield, put two 3/1 red Elemental Shaman creature tokens onto the battlefield. //Sacrifice an Elemental: Target Giant creature gets +3/+1 until end of turn. - addCard(Zone.HAND,playerA,"Hearthcage Giant"); + addCard(Zone.HAND, playerA, "Hearthcage Giant"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); - + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hearthcage Giant"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - + assertPermanentCount(playerA, "Hearthcage Giant", 1); assertPermanentCount(playerA, "Elemental Shaman", 2); assertPowerToughness(playerA, "Elemental Shaman", 3, 1); } + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/step/EndStepTriggerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/step/EndStepTriggerTest.java index c2d1359615f..3aa461c4553 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/step/EndStepTriggerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/step/EndStepTriggerTest.java @@ -70,4 +70,44 @@ public class EndStepTriggerTest extends CardTestPlayerBase { assertCounterCount("Bloodchief Ascension", CounterType.QUEST, 2); } + + /** + * Hey, I don't know how to submit bugs but in a game I played today I + * sacrificed Child of Alara by casting Bound at the end step of my previous + * opponent's turn, then chose Child as one of the cards to return to my + * hand. My graveyard was empty so that was the only card I chose. Child + * returned to my hand but it did NOT trigger for some reason. Nothing was + * destroyed + */ + @Test + public void testSacrificeChildOfAlara() { + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); //Creature + + // Trample + // When Child of Alara dies, destroy all nonland permanents. They can't be regenerated. + addCard(Zone.BATTLEFIELD, playerB, "Icy Manipulator", 1); //Creature + addCard(Zone.BATTLEFIELD, playerB, "Child of Alara", 1); //Creature + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 4); + // Bound + // Sacrifice a creature. Return up to X cards from your graveyard to your hand, where X is the number of colors that creature was. Exile this card. + // Determined + // Other spells you control can't be countered by spells or abilities this turn. + // Draw a card. + addCard(Zone.HAND, playerB, "Bound // Determined"); // Instant {3}{B}{G} // {G}{U} + + castSpell(1, PhaseStep.END_TURN, playerB, "Bound"); + addTarget(playerB, "Child of Alara"); + setChoice(playerB, "Child of Alara"); + + setStopAt(2, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertExileCount(playerB, "Bound // Determined", 1); + + assertHandCount(playerB, "Child of Alara", 1); + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerB, "Icy Manipulator", 1); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java new file mode 100644 index 00000000000..4c9ffeefc61 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java @@ -0,0 +1,37 @@ +package org.mage.test.cards.watchers; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * Created by IGOUDT on 30-3-2017. + */ +public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { + private final String kira = "Kira, Great Glass-Spinner"; + private final String shock = "Shock"; + + @Test + public void counterFirst(){ + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + addCard(Zone.BATTLEFIELD, playerA, "Ugin, the Spirit Dragon"); // starts with 7 Loyality counters + + addCard(Zone.BATTLEFIELD, playerA, kira); + addCard(Zone.HAND, playerA, shock); + addCard(Zone.HAND, playerA, shock); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {source} deals 3 damage to target creature or player.", kira); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + + execute(); + + Permanent _kira = getPermanent(kira, playerA.getId()); + Assert.assertNotNull(_kira); + + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java index e047c2737df..824efa60ba0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadCallbackClient.java @@ -35,58 +35,55 @@ public class LoadCallbackClient implements CallbackClient { log.info(callback.getMethod()); callback.setData(CompressUtil.decompress(callback.getData())); switch (callback.getMethod()) { - case "startGame": - { - TableClientMessage message = (TableClientMessage) callback.getData(); - gameId = message.getGameId(); - playerId = message.getPlayerId(); - session.joinGame(message.getGameId()); - startControlThread(); - break; - } - case "gameInform": - { - GameClientMessage message = (GameClientMessage) callback.getData(); - log.info("Inform: " + message.getMessage()); - gameView = message.getGameView(); - break; - } - case "gameInit": + case START_GAME: { + TableClientMessage message = (TableClientMessage) callback.getData(); + gameId = message.getGameId(); + playerId = message.getPlayerId(); + session.joinGame(message.getGameId()); + startControlThread(); break; - case "gameTarget": - { - GameClientMessage message = (GameClientMessage) callback.getData(); - log.info("Target: " + message.getMessage()); - switch (message.getMessage()) { - case "Select a starting player": - session.sendPlayerUUID(gameId, playerId); - break; - case "Select a card to discard": - log.info("hand size: " + gameView.getHand().size()); - SimpleCardView card = gameView.getHand().values().iterator().next(); - session.sendPlayerUUID(gameId, card.getId()); - break; - } - break; + } + case GAME_INFORM: { + GameClientMessage message = (GameClientMessage) callback.getData(); + log.info("Inform: " + message.getMessage()); + gameView = message.getGameView(); + break; + } + case GAME_INIT: + break; + case GAME_TARGET: { + GameClientMessage message = (GameClientMessage) callback.getData(); + log.info("Target: " + message.getMessage()); + switch (message.getMessage()) { + case "Select a starting player": + session.sendPlayerUUID(gameId, playerId); + break; + case "Select a card to discard": + log.info("hand size: " + gameView.getHand().size()); + SimpleCardView card = gameView.getHand().values().iterator().next(); + session.sendPlayerUUID(gameId, card.getId()); + break; } - case "gameAsk": - { - GameClientMessage message = (GameClientMessage) callback.getData(); - log.info("Ask: " + message.getMessage()); - if (message.getMessage().equals("Do you want to take a mulligan?")) { - session.sendPlayerBoolean(gameId, false); - } break; + break; + } + case GAME_ASK: { + GameClientMessage message = (GameClientMessage) callback.getData(); + log.info("Ask: " + message.getMessage()); + if (message.getMessage().equals("Do you want to take a mulligan?")) { + session.sendPlayerBoolean(gameId, false); } - case "gameSelect": - { - GameClientMessage message = (GameClientMessage) callback.getData(); - log.info("Select: " + message.getMessage()); - if (LoadPhaseManager.getInstance().isSkip(message.getGameView(), message.getMessage(), playerId)) { - log.info("Skipped: " + message.getMessage()); - session.sendPlayerBoolean(gameId, false); - } break; + break; + } + case GAME_SELECT: { + GameClientMessage message = (GameClientMessage) callback.getData(); + log.info("Select: " + message.getMessage()); + if (LoadPhaseManager.getInstance().isSkip(message.getGameView(), message.getMessage(), playerId)) { + log.info("Skipped: " + message.getMessage()); + session.sendPlayerBoolean(gameId, false); } - case "gameOver": + break; + } + case GAME_OVER: log.info("Game over"); gameOver = true; break; diff --git a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java index 09a96fe0073..ce2f5670eeb 100644 --- a/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/load/LoadTest.java @@ -12,6 +12,7 @@ import mage.constants.MultiplayerAttackOption; import mage.constants.RangeOfInfluence; import mage.game.match.MatchOptions; import mage.player.ai.ComputerPlayer; +import mage.players.PlayerType; import mage.remote.Connection; import mage.remote.Session; import mage.remote.SessionImpl; @@ -105,7 +106,7 @@ public class LoadTest { TableView table = session.createTable(roomId, options); - if (!session.joinTable(roomId, table.getTableId(), TEST_USER_NAME + i, "Human", 1, deckList,"")) { + if (!session.joinTable(roomId, table.getTableId(), TEST_USER_NAME + i, PlayerType.HUMAN, 1, deckList,"")) { log.error("Error while joining table"); Assert.fail("Error while joining table"); return; @@ -119,7 +120,7 @@ public class LoadTest { UUID roomId2 = session2.getMainRoomId(); // connect to the table with the same deck - if (!session2.joinTable(roomId2, table.getTableId(), TEST_USER_NAME_2 + i, "Human", 1, deckList,"")) { + if (!session2.joinTable(roomId2, table.getTableId(), TEST_USER_NAME_2 + i, PlayerType.HUMAN, 1, deckList,"")) { log.error("Error while joining table"); Assert.fail("Error while joining table"); return; @@ -177,7 +178,7 @@ public class LoadTest { TableView table = session.createTable(roomId, options); - if (!session.joinTable(roomId, table.getTableId(), TEST_USER_NAME + i, "Human", 1, deckList,"")) { + if (!session.joinTable(roomId, table.getTableId(), TEST_USER_NAME + i, PlayerType.HUMAN, 1, deckList,"")) { log.error("Error while joining table"); Assert.fail("Error while joining table"); return true; @@ -193,7 +194,7 @@ public class LoadTest { UUID roomId2 = session2.getMainRoomId(); // connect to the table with the same deck - if (!session2.joinTable(roomId2, table.getTableId(), TEST_USER_NAME_2 + i, "Human", 1, deckList,"")) { + if (!session2.joinTable(roomId2, table.getTableId(), TEST_USER_NAME_2 + i, PlayerType.HUMAN, 1, deckList,"")) { log.error("Error while joining table"); Assert.fail("Error while joining table"); return true; @@ -266,8 +267,8 @@ public class LoadTest { private MatchOptions createGameOptions(GameTypeView gameTypeView, Session session) { MatchOptions options = new MatchOptions("Test game", gameTypeView.getName(), false, 2); - options.getPlayerTypes().add("Human"); - options.getPlayerTypes().add("Human"); + options.getPlayerTypes().add(PlayerType.HUMAN); + options.getPlayerTypes().add(PlayerType.HUMAN); options.setDeckType(session.getDeckTypes()[0]); options.setLimited(false); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java index 59802a09c85..1f6c29416c9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java @@ -12,6 +12,7 @@ import mage.game.GameOptions; import mage.game.TwoPlayerDuel; import mage.player.ai.ComputerPlayer; import mage.players.Player; +import mage.players.PlayerType; import org.junit.Ignore; import org.junit.Test; import org.mage.test.serverside.base.MageTestBase; @@ -34,7 +35,7 @@ public class PlayGameTest extends MageTestBase { public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException { Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, 0, 20); - Player computerA = createPlayer("ComputerA", "Computer - minimax hybrid"); + Player computerA = createPlayer("ComputerA", PlayerType.COMPUTER_MINIMAX_HYBRID); // Player playerA = createPlayer("ComputerA", "Computer - mad"); // Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck")); Deck deck = generateRandomDeck(); @@ -45,7 +46,7 @@ public class PlayGameTest extends MageTestBase { game.addPlayer(computerA, deck); game.loadCards(deck.getCards(), computerA.getId()); - Player computerB = createPlayer("ComputerB", "Computer - minimax hybrid"); + Player computerB = createPlayer("ComputerB", PlayerType.COMPUTER_MINIMAX_HYBRID); // Player playerB = createPlayer("ComputerB", "Computer - mad"); // Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck")); Deck deck2 = generateRandomDeck(); 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 82d77721301..4c94e70c85c 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 @@ -11,6 +11,7 @@ import mage.game.match.MatchType; import mage.game.permanent.PermanentCard; import mage.game.tournament.TournamentType; import mage.players.Player; +import mage.players.PlayerType; import mage.server.game.GameFactory; import mage.server.game.PlayerFactory; import mage.server.tournament.TournamentFactory; @@ -103,13 +104,13 @@ public abstract class MageTestBase { deleteSavedGames(); ConfigSettings config = ConfigSettings.instance; for (GamePlugin plugin : config.getGameTypes()) { - GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); + GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); } for (GamePlugin plugin : config.getTournamentTypes()) { - TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin)); + TournamentFactory.instance.addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin)); } for (Plugin plugin : config.getPlayerTypes()) { - PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin)); + PlayerFactory.instance.addPlayerType(plugin.getName(), loadPlugin(plugin)); } // for (Plugin plugin : config.getDeckTypes()) { // DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin)); @@ -289,8 +290,8 @@ public abstract class MageTestBase { } } - protected Player createPlayer(String name, String playerType) { - Optional playerOptional = PlayerFactory.getInstance().createPlayer(playerType, name, RangeOfInfluence.ALL, 5); + protected Player createPlayer(String name, PlayerType playerType) { + Optional playerOptional = PlayerFactory.instance.createPlayer(playerType, name, RangeOfInfluence.ALL, 5); return playerOptional.orElseThrow(() -> new NullPointerException("PlayerFactory error - player is not created")); } diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java index 17f987cde70..1b8b73da2b8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/MageTestPlayerBase.java @@ -98,7 +98,7 @@ public abstract class MageTestPlayerBase { deleteSavedGames(); ConfigSettings config = ConfigSettings.instance; for (GamePlugin plugin : config.getGameTypes()) { - GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); + GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); } Copier.setLoader(classLoader); } diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/TournamentStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/TournamentStub.java index da331935d10..018ef657079 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/TournamentStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/TournamentStub.java @@ -27,10 +27,6 @@ */ package org.mage.test.stub; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.UUID; import mage.cards.ExpansionSet; import mage.cards.decks.Deck; import mage.game.draft.Draft; @@ -38,12 +34,14 @@ import mage.game.events.Listener; import mage.game.events.PlayerQueryEvent; import mage.game.events.TableEvent; import mage.game.result.ResultProtos; -import mage.game.tournament.Round; -import mage.game.tournament.Tournament; -import mage.game.tournament.TournamentOptions; -import mage.game.tournament.TournamentPlayer; -import mage.game.tournament.TournamentType; +import mage.game.tournament.*; import mage.players.Player; +import mage.players.PlayerType; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.UUID; /** * @@ -59,7 +57,7 @@ public class TournamentStub implements Tournament { } @Override - public void addPlayer(Player player, String playerType) { + public void addPlayer(Player player, PlayerType playerType) { } diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java index c41811d4f8c..7ec8ec053c0 100644 --- a/Mage/src/main/java/mage/MageObject.java +++ b/Mage/src/main/java/mage/MageObject.java @@ -4,6 +4,8 @@ import mage.abilities.Abilities; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.keyword.ChangelingAbility; +import mage.cards.Card; import mage.cards.FrameStyle; import mage.constants.CardType; import mage.constants.SuperType; @@ -132,4 +134,52 @@ public interface MageObject extends MageItem, Serializable { default boolean isWorld() { return getSuperType().contains(SuperType.WORLD); } + + + /** + * Checks whether two cards share card types. + * + * + * @param otherCard + * @return + */ + default boolean shareTypes(Card otherCard) { + + if (otherCard == null) { + throw new IllegalArgumentException("Params can't be null"); + } + + for (CardType type : getCardType()) { + if (otherCard.getCardType().contains(type)) { + return true; + } + } + + return false; + } + + + default boolean shareSubtypes(Card otherCard, Game game) { + + if (otherCard == null) { + throw new IllegalArgumentException("Params can't be null"); + } + + if (this.isCreature() && otherCard.isCreature()) { + if (this.getAbilities().contains(ChangelingAbility.getInstance()) + || this.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE) + || otherCard.getAbilities().contains(ChangelingAbility.getInstance()) + || otherCard.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { + return true; + } + } + for (String subtype : this.getSubtype(game)) { + if (otherCard.getSubtype(game).contains(subtype)) { + return true; + } + } + + return false; + } + } diff --git a/Mage/src/main/java/mage/abilities/Abilities.java b/Mage/src/main/java/mage/abilities/Abilities.java index d6d007f3c00..2e4c629a2cc 100644 --- a/Mage/src/main/java/mage/abilities/Abilities.java +++ b/Mage/src/main/java/mage/abilities/Abilities.java @@ -29,6 +29,7 @@ package mage.abilities; import java.io.Serializable; import java.util.List; +import java.util.Optional; import java.util.UUID; import mage.abilities.keyword.ProtectionAbility; import mage.abilities.mana.ActivatedManaAbilityImpl; @@ -245,7 +246,7 @@ public interface Abilities extends List, Serializable { * @param abilityId * @return */ - T get(UUID abilityId); + Optional get(UUID abilityId); /** * TODO The usage of this method seems redundant to that of diff --git a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java index 8c9cd7348e4..3e54960d5b3 100644 --- a/Mage/src/main/java/mage/abilities/AbilitiesImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilitiesImpl.java @@ -27,13 +27,6 @@ */ package mage.abilities; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; - import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.keyword.ProtectionAbility; @@ -44,6 +37,8 @@ import mage.game.Game; import mage.util.ThreadLocalStringBuilder; import org.apache.log4j.Logger; +import java.util.*; + /** * @param * @author BetaSteward_at_googlemail.com @@ -277,12 +272,7 @@ public class AbilitiesImpl extends ArrayList implements Ab @Override public boolean containsRule(T ability) { - for (T test : this) { - if (ability.getRule().equals(test.getRule())) { - return true; - } - } - return false; + return stream().anyMatch(rule -> rule.getRule().equals(ability.getRule())); } @Override @@ -301,32 +291,16 @@ public class AbilitiesImpl extends ArrayList implements Ab @Override public boolean containsKey(UUID abilityId) { - for (T ability : this) { - if (ability.getId().equals(abilityId)) { - return true; - } - } - return false; + return stream().anyMatch(ability -> ability.getId().equals(abilityId)); } @Override public boolean containsClass(Class classObject) { - for (T ability : this) { - if (ability.getClass().equals(classObject)) { - return true; - } - } - return false; + return stream().anyMatch(ability -> ability.getClass().equals(classObject)); } - @Override - public T get(UUID abilityId) { - for (T ability : this) { - if (ability.getId().equals(abilityId)) { - return ability; - } - } - return null; + public Optional get(UUID abilityId) { + return stream().filter(ability -> ability.getId().equals(abilityId)).findFirst(); } @Override diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index cc30fc971fe..1f3365e3c68 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -27,6 +27,10 @@ */ package mage.abilities; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; import mage.MageObject; import mage.MageObjectReference; import mage.Mana; @@ -59,11 +63,6 @@ import mage.util.ThreadLocalStringBuilder; import mage.watchers.Watcher; import org.apache.log4j.Logger; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; - /** * @author BetaSteward_at_googlemail.com */ @@ -489,7 +488,7 @@ public abstract class AbilityImpl implements Ability { protected String handleOtherXCosts(Game game, Player controller) { StringBuilder announceString = new StringBuilder(); for (VariableCost variableCost : this.costs.getVariableCosts()) { - if (!(variableCost instanceof VariableManaCost)) { + if (!(variableCost instanceof VariableManaCost) && !((Cost) variableCost).isPaid()) { int xValue = variableCost.announceXValue(this, game); Cost fixedCost = variableCost.getFixedCostsFromAnnouncedValue(xValue); if (fixedCost != null) { @@ -506,19 +505,20 @@ public abstract class AbilityImpl implements Ability { } /** - * 601.2b - * If a cost that will be paid as the spell is being cast includes Phyrexian mana symbols, - * the player announces whether he or she intends to pay 2 life or the corresponding colored mana cost for each of those symbols. + * 601.2b If a cost that will be paid as the spell is being cast includes + * Phyrexian mana symbols, the player announces whether he or she intends to + * pay 2 life or the corresponding colored mana cost for each of those + * symbols. */ private void handlePhyrexianManaCosts(Game game, UUID sourceId, Player controller) { Iterator costIterator = manaCostsToPay.iterator(); - while(costIterator.hasNext()) { + while (costIterator.hasNext()) { ManaCost cost = costIterator.next(); - if(cost instanceof PhyrexianManaCost) { - PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost)cost; + if (cost instanceof PhyrexianManaCost) { + PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost) cost; PayLifeCost payLifeCost = new PayLifeCost(2); - if(payLifeCost.canPay(this, sourceId, controller.getId(), game) && - controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + '?', this, game)) { + if (payLifeCost.canPay(this, sourceId, controller.getId(), game) + && controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + '?', this, game)) { costIterator.remove(); costs.add(payLifeCost); } @@ -558,7 +558,11 @@ public abstract class AbilityImpl implements Ability { } else { String manaSymbol = null; if (variableManaCost.getFilter().isBlack()) { - manaSymbol = "B"; + if (variableManaCost.getFilter().isRed()) { + manaSymbol = "B/R"; + } else { + manaSymbol = "B"; + } } else if (variableManaCost.getFilter().isRed()) { manaSymbol = "R"; } else if (variableManaCost.getFilter().isBlue()) { diff --git a/Mage/src/main/java/mage/abilities/DelayedTriggeredAbilities.java b/Mage/src/main/java/mage/abilities/DelayedTriggeredAbilities.java index f98551cb414..12402295a52 100644 --- a/Mage/src/main/java/mage/abilities/DelayedTriggeredAbilities.java +++ b/Mage/src/main/java/mage/abilities/DelayedTriggeredAbilities.java @@ -28,20 +28,21 @@ package mage.abilities; -import java.util.Iterator; import mage.constants.Duration; import mage.game.Game; import mage.game.events.GameEvent; +import java.util.Iterator; + /** - * * @author BetaSteward_at_googlemail.com */ - public class DelayedTriggeredAbilities extends AbilitiesImpl { +public class DelayedTriggeredAbilities extends AbilitiesImpl { - public DelayedTriggeredAbilities() {} + public DelayedTriggeredAbilities() { + } - public DelayedTriggeredAbilities(final DelayedTriggeredAbilities abilities) { + public DelayedTriggeredAbilities(final DelayedTriggeredAbilities abilities) { super(abilities); } @@ -52,9 +53,9 @@ import mage.game.events.GameEvent; public void checkTriggers(GameEvent event, Game game) { if (this.size() > 0) { - for (Iterator it = this.iterator();it.hasNext();) { + for (Iterator it = this.iterator(); it.hasNext(); ) { DelayedTriggeredAbility ability = it.next(); - if (ability.getDuration()== Duration.Custom){ + if (ability.getDuration() == Duration.Custom) { if (ability.isInactive(game)) { it.remove(); continue; diff --git a/Mage/src/main/java/mage/abilities/abilityword/KinshipAbility.java b/Mage/src/main/java/mage/abilities/abilityword/KinshipAbility.java index ccf9cffce79..3bc8a61082b 100644 --- a/Mage/src/main/java/mage/abilities/abilityword/KinshipAbility.java +++ b/Mage/src/main/java/mage/abilities/abilityword/KinshipAbility.java @@ -45,7 +45,6 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; /** * @@ -126,7 +125,7 @@ class KinshipBaseEffect extends OneShotEffect { if (card != null) { Cards cards = new CardsImpl(card); controller.lookAtCards(sourcePermanent.getName(), cards, game); - if (CardUtil.shareSubtypes(sourcePermanent, card, game)) { + if (sourcePermanent.shareSubtypes(card, game)) { if (controller.chooseUse(outcome,new StringBuilder("Kinship - Reveal ").append(card.getLogName()).append('?').toString(), source, game)) { controller.revealCards(sourcePermanent.getName(), cards, game); for (Effect effect: kinshipEffects) { diff --git a/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java b/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java index 6a770fae8ee..83a785a8fa8 100644 --- a/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java @@ -29,7 +29,9 @@ package mage.abilities.costs; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.keyword.FlashbackAbility; import mage.game.Game; +import mage.game.stack.StackObject; import mage.players.Player; import mage.target.Target; import mage.target.Targets; @@ -131,13 +133,15 @@ public abstract class VariableCostImpl implements Cost, VariableCost { @Override public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; /* not used */ + return true; + /* not used */ } @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - return true; /* not used */ + return true; + /* not used */ } @@ -165,7 +169,9 @@ public abstract class VariableCostImpl implements Cost, VariableCost { public int announceXValue(Ability source, Game game) { int xValue = 0; Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { + StackObject stackObject = game.getStack().getStackObject(source.getId()); + if (controller != null + && (source instanceof FlashbackAbility || stackObject != null)) { xValue = controller.announceXCost(getMinValue(source, game), getMaxValue(source, game), "Announce the number of " + actionText, game, source, this); } diff --git a/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java index 51c084654bb..e41df6c899c 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import mage.abilities.Ability; @@ -40,7 +39,6 @@ import mage.target.common.TargetCardInHand; * * @author LevelX2 */ - public class DiscardXTargetCost extends VariableCostImpl { protected FilterCard filter; @@ -50,9 +48,8 @@ public class DiscardXTargetCost extends VariableCostImpl { } public DiscardXTargetCost(FilterCard filter, boolean additionalCostText) { - super(new StringBuilder(filter.getMessage()).append(" to discard").toString()); - this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, discard ":"Discard ") - .append(xText).append(' ').append(filter.getMessage()).toString(); + super(filter.getMessage() + " to discard"); + this.text = (additionalCostText ? "As an additional cost to cast {source}, discard " : "Discard ") + xText + ' ' + filter.getMessage(); this.filter = filter; } diff --git a/Mage/src/main/java/mage/abilities/effects/AsThoughManaEffect.java b/Mage/src/main/java/mage/abilities/effects/AsThoughManaEffect.java index ef062750352..60d067116e8 100644 --- a/Mage/src/main/java/mage/abilities/effects/AsThoughManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/AsThoughManaEffect.java @@ -40,6 +40,15 @@ import mage.players.ManaPoolItem; public interface AsThoughManaEffect extends AsThoughEffect { // return a mana type that can be used to pay a mana cost instead of the normally needed mana type + /** + * + * @param manaType type of mana with which the player wants to pay the cost + * @param mana mana pool item to pay from the cost + * @param affectedControllerId + * @param source + * @param game + * @return + */ ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game); } diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index 4f42e779237..e732999149c 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -27,6 +27,9 @@ */ package mage.abilities.effects; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; import mage.MageObject; import mage.abilities.*; import mage.abilities.keyword.SpliceOntoArcaneAbility; @@ -49,10 +52,6 @@ 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 */ @@ -691,8 +690,7 @@ 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); } } @@ -702,10 +700,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) { @@ -752,7 +750,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()); @@ -933,7 +931,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()); diff --git a/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java index ef78e432bb8..923bc5f22bf 100644 --- a/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/EntersBattlefieldEffect.java @@ -148,6 +148,7 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { if (spell != null) { effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); } + effect.setValue("appliedEffects", event.getAppliedEffects()); effect.apply(game, source); } // } diff --git a/Mage/src/main/java/mage/abilities/effects/common/EndTurnEffect.java b/Mage/src/main/java/mage/abilities/effects/common/EndTurnEffect.java index 5cb9237e914..5e5fb0b9389 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/EndTurnEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/EndTurnEffect.java @@ -48,7 +48,7 @@ public class EndTurnEffect extends OneShotEffect { if (!game.isSimulation()) { game.informPlayers("The current turn ends"); } - return game.endTurn(); + return game.endTurn(source); } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java b/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java index 78f14bc36aa..d326d359d2a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java @@ -27,6 +27,8 @@ */ package mage.abilities.effects.common; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.EntersBattlefieldEffect; @@ -75,7 +77,8 @@ public class EntersBattlefieldWithXCountersEffect extends OneShotEffect { if (amount > 0) { Counter counterToAdd = counter.copy(); counterToAdd.add(amount - counter.getCount()); - permanent.addCounters(counterToAdd, source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); + permanent.addCounters(counterToAdd, source, game, appliedEffects); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 3233d7a286a..1f28040a739 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -27,6 +27,8 @@ */ package mage.abilities.effects.common.counter; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; @@ -103,7 +105,8 @@ public class AddCountersSourceEffect extends OneShotEffect { countersToAdd--; } newCounter.add(countersToAdd); - card.addCounters(newCounter, source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); + card.addCounters(newCounter, source, game, appliedEffects); if (informPlayers && !game.isSimulation()) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { @@ -128,7 +131,8 @@ public class AddCountersSourceEffect extends OneShotEffect { } newCounter.add(countersToAdd); int before = permanent.getCounters(game).getCount(newCounter.getName()); - permanent.addCounters(newCounter, source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); + permanent.addCounters(newCounter, source, game, appliedEffects); // if used from a replacement effect, the basic event determines if an effect was already applied to an event if (informPlayers && !game.isSimulation()) { int amountAdded = permanent.getCounters(game).getCount(newCounter.getName()) - before; Player player = game.getPlayer(source.getControllerId()); @@ -150,12 +154,10 @@ public class AddCountersSourceEffect extends OneShotEffect { sb.append("put "); if (counter.getCount() > 1) { sb.append(CardUtil.numberToText(counter.getCount())).append(' '); + } else if (amount.toString().equals("X") && amount.getMessage().isEmpty()) { + sb.append("X "); } else { - if (amount.toString().equals("X") && amount.getMessage().isEmpty()) { - sb.append("X "); - } else { - sb.append("a "); - } + sb.append("a "); } sb.append(counter.getName().toLowerCase()).append(" counter on {this}"); if (!amount.getMessage().isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/keyword/BloodthirstAbility.java b/Mage/src/main/java/mage/abilities/keyword/BloodthirstAbility.java index b57e67959e4..93941494bab 100644 --- a/Mage/src/main/java/mage/abilities/keyword/BloodthirstAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/BloodthirstAbility.java @@ -1,5 +1,7 @@ package mage.abilities.keyword; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; @@ -71,7 +73,8 @@ class BloodthirstEffect extends OneShotEffect { if (watcher != null && watcher.conditionMet()) { Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + permanent.addCounters(CounterType.P1P1.createInstance(amount), source, game, appliedEffects); } } return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java new file mode 100644 index 00000000000..ed87289b545 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.keyword; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileSourceFromGraveCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.token.EmptyToken; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class EmbalmAbility extends ActivatedAbilityImpl { + + private String rule; + + public EmbalmAbility(Cost cost, Card card) { + super(Zone.GRAVEYARD, new EmbalmEffect(), cost); + addCost(new ExileSourceFromGraveCost()); + this.rule = setRule(cost, card); + this.timing = TimingRule.SORCERY; + setRule(cost, card); + } + + public EmbalmAbility(final EmbalmAbility ability) { + super(ability); + this.rule = ability.rule; + } + + @Override + public EmbalmAbility copy() { + return new EmbalmAbility(this); + } + + @Override + public String getRule() { + return rule; + } + + private String setRule(Cost cost, Card card) { + StringBuilder sb = new StringBuilder("Embalm ").append(cost.getText()); + sb.append(" (").append(cost.getText()); + sb.append(", Exile this card from your graveyard: Create a token that's a copy of it, except it's a white Zombie "); + for (String subtype : card.getSubtype(null)) { + sb.append(subtype).append(" "); + } + sb.append(" with no mana cost. Embalm only as a sorcery.)"); + return sb.toString(); + } +} + +class EmbalmEffect extends OneShotEffect { + + public EmbalmEffect() { + super(Outcome.PutCreatureInPlay); + } + + public EmbalmEffect(final EmbalmEffect effect) { + super(effect); + } + + @Override + public EmbalmEffect copy() { + return new EmbalmEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && card != null) { + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.WHITE); + if (!token.getSubtype(game).contains("Zombie")) { + token.getSubtype(game).add(0, "Zombie"); + } + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); + return true; + } + + return false; + } + +} diff --git a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java index 8547d850e9d..d8df61ca873 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java @@ -1,7 +1,6 @@ package mage.abilities.keyword; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; @@ -14,7 +13,6 @@ import mage.target.targetpointer.FixedTarget; /** - * * @author Plopman */ @@ -38,16 +36,12 @@ public class FlankingAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getTargetId().equals(this.getSourceId())) { Permanent permanent = game.getPermanent(event.getSourceId()); - if(permanent != null) - { - boolean hasFlankingAbility = false; - for(Ability ability : permanent.getAbilities()){ - if(ability instanceof FlankingAbility){ - hasFlankingAbility = true; - } - } - - if(!hasFlankingAbility){ + if (permanent != null) { + boolean hasFlankingAbility = + permanent.getAbilities().stream().anyMatch(ability -> ability instanceof FlankingAbility); + + + if (!hasFlankingAbility) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getSourceId())); } @@ -68,5 +62,5 @@ public class FlankingAbility extends TriggeredAbilityImpl { return new FlankingAbility(this); } - + } diff --git a/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java b/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java index dad2df5a918..67ea7227535 100644 --- a/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/KickerAbility.java @@ -27,20 +27,10 @@ */ package mage.abilities.keyword; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.Costs; -import mage.abilities.costs.CostsImpl; -import mage.abilities.costs.OptionalAdditionalCost; -import mage.abilities.costs.OptionalAdditionalCostImpl; -import mage.abilities.costs.OptionalAdditionalSourceCosts; +import mage.abilities.costs.*; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -51,8 +41,9 @@ import mage.constants.Zone; import mage.game.Game; import mage.players.Player; +import java.util.*; + /** - * * 20121001 702.31. Kicker 702.31a Kicker is a static ability that functions * while the spell with kicker is on the stack. "Kicker [cost]" means "You may * pay an additional [cost] as you cast this spell." Paying a spell's kicker @@ -80,7 +71,6 @@ import mage.players.Player; * 601.2c. * * @author LevelX2 - * */ public class KickerAbility extends StaticAbility implements OptionalAdditionalSourceCosts { @@ -159,10 +149,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo public int getKickedCounter(Game game, Ability source) { String key = getActivationKey(source, "", game); - if (activations.containsKey(key)) { - return activations.get(key); - } - return 0; + return activations.getOrDefault(key, 0); } public boolean isKicked(Game game, Ability source, String costText) { @@ -227,10 +214,10 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo && player.chooseUse(Outcome.Benefit, "Pay " + times + kickerCost.getText(false) + " ?", ability, game)) { this.activateKicker(kickerCost, ability, game); if (kickerCost instanceof Costs) { - for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext();) { + for (Iterator itKickerCost = ((Costs) kickerCost).iterator(); itKickerCost.hasNext(); ) { Object kickerCostObject = itKickerCost.next(); if ((kickerCostObject instanceof Costs) || (kickerCostObject instanceof CostsImpl)) { - for (@SuppressWarnings("unchecked") Iterator itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext();) { + for (@SuppressWarnings("unchecked") Iterator itDetails = ((Costs) kickerCostObject).iterator(); itDetails.hasNext(); ) { addKickerCostsToAbility(itDetails.next(), ability, game); } } else { diff --git a/Mage/src/main/java/mage/abilities/keyword/ModularAbility.java b/Mage/src/main/java/mage/abilities/keyword/ModularAbility.java index bb155c232bf..250992d472d 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ModularAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ModularAbility.java @@ -1,5 +1,7 @@ package mage.abilities.keyword; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.StaticAbility; import mage.abilities.common.DiesTriggeredAbility; @@ -159,7 +161,8 @@ class ModularDistributeCounterEffect extends OneShotEffect { if (sourcePermanent != null && targetArtifact != null && player != null) { int numberOfCounters = sourcePermanent.getCounters(game).getCount(CounterType.P1P1); if (numberOfCounters > 0) { - targetArtifact.addCounters(CounterType.P1P1.createInstance(numberOfCounters), source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + targetArtifact.addCounters(CounterType.P1P1.createInstance(numberOfCounters), source, game, appliedEffects); } return true; } diff --git a/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java b/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java index 806f71a3099..aebf6928c8b 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java @@ -10,6 +10,8 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import java.util.Optional; + /** * Split Second * @@ -66,8 +68,8 @@ class SplitSecondEffect extends ContinuousRuleModifyingEffectImpl { return true; } if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { - Ability ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability != null && !(ability instanceof ActivatedManaAbilityImpl)) { + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability != null && !(ability.get() instanceof ActivatedManaAbilityImpl)) { return true; } } diff --git a/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java b/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java index 3aa9182d2f3..7a61d06c41a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java @@ -27,13 +27,14 @@ */ package mage.abilities.keyword; +import java.util.ArrayList; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.SunburstCount; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; -import mage.constants.CardType; import mage.constants.Outcome; import mage.counters.Counter; import mage.counters.CounterType; @@ -97,8 +98,8 @@ class SunburstEffect extends OneShotEffect { counter = CounterType.CHARGE.createInstance(amount.calculate(game, source, this)); } if (counter != null) { - - permanent.addCounters(counter, source, game); + ArrayList appliedEffects = (ArrayList) this.getValue("appliedEffects"); // the basic event is the EntersBattlefieldEvent, so use already applied replacement effects from that event + permanent.addCounters(counter, source, game, appliedEffects); if (!game.isSimulation()) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { diff --git a/Mage/src/main/java/mage/abilities/keyword/UnleashAbility.java b/Mage/src/main/java/mage/abilities/keyword/UnleashAbility.java index 6cdc697f129..77bad121883 100644 --- a/Mage/src/main/java/mage/abilities/keyword/UnleashAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/UnleashAbility.java @@ -105,7 +105,7 @@ class UnleashReplacementEffect extends ReplacementEffectImpl { if (!game.isSimulation()) { game.informPlayers(controller.getLogName() + " unleashes " + creature.getName()); } - creature.addCounters(CounterType.P1P1.createInstance(), source, game); + creature.addCounters(CounterType.P1P1.createInstance(), source, game, event.getAppliedEffects()); } } return false; diff --git a/Mage/src/main/java/mage/actions/MageDrawAction.java b/Mage/src/main/java/mage/actions/MageDrawAction.java index ba7922b590f..619cd9da753 100644 --- a/Mage/src/main/java/mage/actions/MageDrawAction.java +++ b/Mage/src/main/java/mage/actions/MageDrawAction.java @@ -76,7 +76,7 @@ public class MageDrawAction extends MageAction { */ protected int drawCard(Game game) { GameEvent event = GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, player.getId(), player.getId()); - event.setAppliedEffects(appliedEffects); + event.addAppliedEffects(appliedEffects); if (!game.replaceEvent(event)) { Card card = player.getLibrary().removeFromTop(game); if (card != null) { diff --git a/Mage/src/main/java/mage/cards/CardsImpl.java b/Mage/src/main/java/mage/cards/CardsImpl.java index 49e0622ccd1..dfe5f117df0 100644 --- a/Mage/src/main/java/mage/cards/CardsImpl.java +++ b/Mage/src/main/java/mage/cards/CardsImpl.java @@ -27,24 +27,16 @@ */ package mage.cards; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; import mage.filter.FilterCard; import mage.game.Game; import mage.util.RandomUtil; import mage.util.ThreadLocalStringBuilder; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + /** - * * @author BetaSteward_at_googlemail.com */ public class CardsImpl extends LinkedHashSet implements Cards, Serializable { @@ -118,24 +110,13 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public int count(FilterCard filter, Game game) { - int result = 0; - for (UUID cardId : this) { - if (filter.match(game.getCard(cardId), game)) { - result++; - } - } - return result; + return (int) stream().filter(cardId -> filter.match(game.getCard(cardId), game)).count(); } @Override public int count(FilterCard filter, UUID playerId, Game game) { - int result = 0; - for (UUID card : this) { - if (filter.match(game.getCard(card), playerId, game)) { - result++; - } - } - return result; + return (int) this.stream().filter(card -> filter.match(game.getCard(card), playerId, game)).count(); + } @Override @@ -143,13 +124,8 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl if (sourceId == null) { return count(filter, playerId, game); } - int result = 0; - for (UUID card : this) { - if (filter.match(game.getCard(card), sourceId, playerId, game)) { - result++; - } - } - return result; + return (int) this.stream().filter(card -> filter.match(game.getCard(card), sourceId, playerId, game)).count(); + } @Override @@ -169,20 +145,13 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl @Override public Set getCards(FilterCard filter, Game game) { - Set cards = new LinkedHashSet<>(); - for (UUID card : this) { - boolean match = filter.match(game.getCard(card), game); - if (match) { - cards.add(game.getCard(card)); - } - } - return cards; + return stream().map(game::getCard).filter(card -> filter.match(card, game)).collect(Collectors.toSet()); } @Override public Set getCards(Game game) { Set cards = new LinkedHashSet<>(); - for (Iterator it = this.iterator(); it.hasNext();) { // Changed to iterator because of ConcurrentModificationException + for (Iterator it = this.iterator(); it.hasNext(); ) { // Changed to iterator because of ConcurrentModificationException UUID cardId = it.next(); Card card = game.getCard(cardId); diff --git a/Mage/src/main/java/mage/cards/ExpansionSet.java b/Mage/src/main/java/mage/cards/ExpansionSet.java index a16ab16f41c..04931d7ee83 100644 --- a/Mage/src/main/java/mage/cards/ExpansionSet.java +++ b/Mage/src/main/java/mage/cards/ExpansionSet.java @@ -36,6 +36,7 @@ import mage.util.RandomUtil; import java.io.Serializable; import java.util.*; +import java.util.stream.Collectors; /** * @author BetaSteward_at_googlemail.com @@ -160,13 +161,7 @@ public abstract class ExpansionSet implements Serializable { } public List findCardInfoByClass(Class clazz) { - ArrayList result = new ArrayList<>(); - for (SetCardInfo info : cards) { - if (info.getCardClass().equals(clazz)) { - result.add(info); - } - } - return result; + return cards.stream().filter(info -> info.getCardClass().equals(clazz)).collect(Collectors.toList()); } public List create15CardBooster() { diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index 33897e6a21f..915d1452580 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -41,6 +41,7 @@ public enum CounterType { BLAZE("blaze"), BOUNTY("bounty"), BRIBERY("bribery"), + BRICK("brick"), CARRION("carrion"), CHARGE("charge"), CORPSE("corpse"), diff --git a/Mage/src/main/java/mage/counters/Counters.java b/Mage/src/main/java/mage/counters/Counters.java index 93667bcb350..d946b49669a 100644 --- a/Mage/src/main/java/mage/counters/Counters.java +++ b/Mage/src/main/java/mage/counters/Counters.java @@ -28,10 +28,10 @@ package mage.counters; import java.io.Serializable; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * @author BetaSteward_at_googlemail.com @@ -122,12 +122,9 @@ public class Counters extends HashMap implements Serializable { } public List getBoostCounters() { - List boosters = new ArrayList<>(); - for (Counter counter : this.values()) { - if (counter instanceof BoostCounter) { - boosters.add((BoostCounter) counter); - } - } - return boosters; + return values().stream(). + filter(counter -> counter instanceof BoostCounter). + map(counter -> (BoostCounter) counter). + collect(Collectors.toList()); } } diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java index e813e7becdd..87040399b57 100644 --- a/Mage/src/main/java/mage/game/Game.java +++ b/Mage/src/main/java/mage/game/Game.java @@ -28,13 +28,7 @@ package mage.game; import java.io.Serializable; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import mage.MageItem; import mage.MageObject; import mage.abilities.Ability; @@ -50,11 +44,7 @@ import mage.cards.Cards; import mage.cards.MeldCard; import mage.cards.decks.Deck; import mage.choices.Choice; -import mage.constants.Duration; -import mage.constants.MultiplayerAttackOption; -import mage.constants.PlayerAction; -import mage.constants.RangeOfInfluence; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.Counters; import mage.game.combat.Combat; import mage.game.command.Commander; @@ -128,7 +118,7 @@ public interface Game extends MageItem, Serializable { Card getCard(UUID cardId); - Ability getAbility(UUID abilityId, UUID sourceId); + Optional getAbility(UUID abilityId, UUID sourceId); void setZone(UUID objectId, Zone zone); @@ -402,7 +392,7 @@ public interface Game extends MageItem, Serializable { void playPriority(UUID activePlayerId, boolean resuming); - boolean endTurn(); + boolean endTurn(Ability source); int doAction(MageAction action); diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index 9db038eb1fb..0fd3405f605 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -27,6 +27,10 @@ */ package mage.game; +import java.io.IOException; +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; import mage.MageException; import mage.MageObject; import mage.abilities.*; @@ -92,11 +96,6 @@ import mage.watchers.Watchers; import mage.watchers.common.*; import org.apache.log4j.Logger; -import java.io.IOException; -import java.io.Serializable; -import java.util.*; -import java.util.Map.Entry; - public abstract class GameImpl implements Game, Serializable { private static final int ROLLBACK_TURNS_MAX = 4; @@ -503,12 +502,12 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public Ability getAbility(UUID abilityId, UUID sourceId) { + public Optional getAbility(UUID abilityId, UUID sourceId) { MageObject object = getObject(sourceId); if (object != null) { return object.getAbilities().get(abilityId); } - return null; + return Optional.empty(); } // @Override @@ -2336,10 +2335,10 @@ public abstract class GameImpl implements Game, Serializable { } } - Iterator it = gameCards.entrySet().iterator(); + Iterator> it = gameCards.entrySet().iterator(); while (it.hasNext()) { - Entry entry = (Entry) it.next(); + Entry entry = it.next(); Card card = entry.getValue(); if (card.getOwnerId().equals(playerId)) { it.remove(); @@ -2672,8 +2671,8 @@ public abstract class GameImpl implements Game, Serializable { } @Override - public boolean endTurn() { - getTurn().endTurn(this, getActivePlayerId()); + public boolean endTurn(Ability source) { + getTurn().endTurn(this, getActivePlayerId(), source); return true; } diff --git a/Mage/src/main/java/mage/game/Seat.java b/Mage/src/main/java/mage/game/Seat.java index f9a3325ac23..1bb28514bc1 100644 --- a/Mage/src/main/java/mage/game/Seat.java +++ b/Mage/src/main/java/mage/game/Seat.java @@ -27,8 +27,10 @@ */ package mage.game; -import java.io.Serializable; import mage.players.Player; +import mage.players.PlayerType; + +import java.io.Serializable; /** * @@ -37,18 +39,18 @@ import mage.players.Player; public class Seat implements Serializable { // private static final Logger logger = Logger.getLogger(Seat.class); - private String playerType; + private PlayerType playerType; private Player player; - public Seat(String playerType) { + public Seat(PlayerType playerType) { this.playerType = playerType; } - public String getPlayerType() { + public PlayerType getPlayerType() { return playerType; } - public void setPlayerType(String playerType) { + public void setPlayerType(PlayerType playerType) { this.playerType = playerType; } diff --git a/Mage/src/main/java/mage/game/Table.java b/Mage/src/main/java/mage/game/Table.java index 7850809ec37..70b639e0c44 100644 --- a/Mage/src/main/java/mage/game/Table.java +++ b/Mage/src/main/java/mage/game/Table.java @@ -27,13 +27,6 @@ */ 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; import mage.game.events.Listener; @@ -43,9 +36,12 @@ import mage.game.match.Match; import mage.game.result.ResultProtos.TableProto; import mage.game.tournament.Tournament; import mage.players.Player; +import mage.players.PlayerType; + +import java.io.Serializable; +import java.util.*; /** - * * @author BetaSteward_at_googlemail.com */ public class Table implements Serializable { @@ -74,21 +70,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, Set bannedUsernames) { + 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, Set bannedUsernames) { + 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, Set bannedUsernames) { + 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(); @@ -102,10 +98,10 @@ public class Table implements Serializable { this.bannedUsernames = new HashSet<>(bannedUsernames); } - private void createSeats(List playerTypes) { + private void createSeats(List playerTypes) { int i = 0; seats = new Seat[numSeats]; - for (String playerType : playerTypes) { + for (PlayerType playerType : playerTypes) { seats[i] = new Seat(playerType); i++; } @@ -145,7 +141,6 @@ public class Table implements Serializable { /** * All activities of the table end (only replay of games (if active) and * display tournament results) - * */ public void closeTable() { if (getState() != TableState.WAITING && getState() != TableState.READY_TO_START) { @@ -156,7 +151,6 @@ public class Table implements Serializable { /** * Complete remove of the table, release all objects - * */ public void cleanUp() { if (match != null) { @@ -211,9 +205,9 @@ public class Table implements Serializable { return numSeats; } - public Seat getNextAvailableSeat(String playerType) { + public Seat getNextAvailableSeat(PlayerType playerType) { for (int i = 0; i < numSeats; i++) { - if (seats[i].getPlayer() == null && seats[i].getPlayerType().equals(playerType)) { + if (seats[i].getPlayer() == null && seats[i].getPlayerType() == (playerType)) { return seats[i]; } } diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java index e267302b3dc..ae95ae00be7 100644 --- a/Mage/src/main/java/mage/game/command/Commander.java +++ b/Mage/src/main/java/mage/game/command/Commander.java @@ -27,10 +27,6 @@ */ package mage.game.command; -import java.util.EnumSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; import mage.abilities.Abilities; @@ -48,18 +44,22 @@ import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.util.GameLog; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; + public class Commander implements CommandObject { private final Card sourceObject; - private final Abilities abilites = new AbilitiesImpl<>(); + private final Abilities abilities = new AbilitiesImpl<>(); public Commander(Card card) { this.sourceObject = card; - abilites.add(new CastCommanderAbility(card)); + abilities.add(new CastCommanderAbility(card)); for (Ability ability : card.getAbilities()) { if (!(ability instanceof SpellAbility)) { Ability newAbility = ability.copy(); - abilites.add(newAbility); + abilities.add(newAbility); } } } @@ -134,7 +134,7 @@ public class Commander implements CommandObject { @Override public Abilities getAbilities() { - return abilites; + return abilities; } @Override diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java index 997cfa291d4..599fb8efcff 100644 --- a/Mage/src/main/java/mage/game/command/Emblem.java +++ b/Mage/src/main/java/mage/game/command/Emblem.java @@ -27,8 +27,6 @@ */ package mage.game.command; -import java.util.*; - import mage.MageInt; import mage.MageObject; import mage.ObjectColor; @@ -46,6 +44,11 @@ import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.util.GameLog; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; + /** * @author nantuko */ @@ -92,7 +95,7 @@ public class Emblem implements CommandObject { this.sourceObject = sourceObject; if (sourceObject instanceof Card) { if (name.isEmpty()) { - name = ((Card) sourceObject).getSubtype(null).toString(); + name = sourceObject.getSubtype(null).toString(); } if (expansionSetCodeForImage.isEmpty()) { expansionSetCodeForImage = ((Card) sourceObject).getExpansionSetCode(); diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index a554d276558..c7e29e123f9 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -166,7 +166,7 @@ public class GameEvent implements Serializable { mana the mana added */ MANA_ADDED, - /* MANA_PAYED + /* MANA_PAID targetId id if the ability the mana was paid for (not the sourceId) sourceId sourceId of the mana source playerId controller of the ability the mana was paid for @@ -174,7 +174,7 @@ public class GameEvent implements Serializable { flag indicates a special condition data originalId of the mana producing ability */ - MANA_PAYED, + MANA_PAID, LOSES, LOST, WINS, TARGET, TARGETED, /* TARGETS_VALID @@ -451,12 +451,19 @@ public class GameEvent implements Serializable { return type == EventType.CUSTOM_EVENT && this.customEventType.equals(customEventType); } - public void setAppliedEffects(ArrayList appliedEffects) { - if (this.appliedEffects == null) { - this.appliedEffects = new ArrayList<>(); - } + public void addAppliedEffects(ArrayList appliedEffects) { if (appliedEffects != null) { this.appliedEffects.addAll(appliedEffects); } } + + public void setAppliedEffects(ArrayList appliedEffects) { + if (appliedEffects != null) { + if (this.appliedEffects.isEmpty()) { + this.appliedEffects = appliedEffects; // Use object refecence to handle that an replacement effect can only be once applied to an event + } else { + this.appliedEffects.addAll(appliedEffects); + } + } + } } diff --git a/Mage/src/main/java/mage/game/match/MatchOptions.java b/Mage/src/main/java/mage/game/match/MatchOptions.java index 3b581aef1ba..5b1f4a6df9d 100644 --- a/Mage/src/main/java/mage/game/match/MatchOptions.java +++ b/Mage/src/main/java/mage/game/match/MatchOptions.java @@ -28,16 +28,18 @@ 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; import mage.constants.SkillLevel; import mage.game.result.ResultProtos; +import mage.players.PlayerType; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * @@ -53,7 +55,7 @@ public class MatchOptions implements Serializable { protected String gameType; protected String deckType; protected boolean limited; - protected List playerTypes = new ArrayList<>(); + protected List playerTypes = new ArrayList<>(); protected boolean multiPlayer; protected int numSeats; protected String password; @@ -154,7 +156,7 @@ public class MatchOptions implements Serializable { this.deckType = deckType; } - public List getPlayerTypes() { + public List getPlayerTypes() { return playerTypes; } diff --git a/Mage/src/main/java/mage/game/permanent/Battlefield.java b/Mage/src/main/java/mage/game/permanent/Battlefield.java index a58b5b71ff6..6ca92d1d063 100644 --- a/Mage/src/main/java/mage/game/permanent/Battlefield.java +++ b/Mage/src/main/java/mage/game/permanent/Battlefield.java @@ -103,22 +103,20 @@ public class Battlefield implements Serializable { * @return count */ public int count(FilterPermanent filter, UUID sourceId, UUID sourcePlayerId, Game game) { - int count; if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { - count = (int) field.values() + return (int) field.values() .stream() .filter(permanent -> filter.match(permanent, sourceId, sourcePlayerId, game) && permanent.isPhasedIn()) .count(); } else { Set range = game.getPlayer(sourcePlayerId).getInRange(); - count = (int) field.values() + return (int) field.values() .stream() .filter(permanent -> range.contains(permanent.getControllerId()) && filter.match(permanent, sourceId, sourcePlayerId, game) && permanent.isPhasedIn()).count(); } - return count; } /** @@ -319,20 +317,18 @@ public class Battlefield implements Serializable { * @see Permanent */ public List getActivePermanents(FilterPermanent filter, UUID sourcePlayerId, UUID sourceId, Game game) { - List active = new ArrayList<>(); if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { - active = field.values() + return field.values() .stream() .filter(perm -> perm.isPhasedIn() && filter.match(perm, sourceId, sourcePlayerId, game)) .collect(Collectors.toList()); } else { Set range = game.getPlayer(sourcePlayerId).getInRange(); - active = field.values() + return field.values() .stream() .filter(perm -> perm.isPhasedIn() && range.contains(perm.getControllerId()) && filter.match(perm, sourceId, sourcePlayerId, game)).collect(Collectors.toList()); } - return active; } /** diff --git a/Mage/src/main/java/mage/game/permanent/token/AngelToken.java b/Mage/src/main/java/mage/game/permanent/token/AngelToken.java index 21b3ce59354..318d8c066b1 100644 --- a/Mage/src/main/java/mage/game/permanent/token/AngelToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/AngelToken.java @@ -12,7 +12,7 @@ public class AngelToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CFX", "GTC", "ISD", "M14", "ORI", "SOI", "ZEN", "C15")); + tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CFX", "GTC", "ISD", "M14", "ORI", "SOI", "ZEN", "C15", "MM3")); } public AngelToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/BeastToken.java b/Mage/src/main/java/mage/game/permanent/token/BeastToken.java index a2803df9f7e..939abf5b50c 100644 --- a/Mage/src/main/java/mage/game/permanent/token/BeastToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/BeastToken.java @@ -42,7 +42,7 @@ public class BeastToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("C14", "LRW", "M15", "M14", "DDL", "M13", "M12", "DD3GVL", "NPH", "M11", "M10", "EVE")); + tokenImageSets.addAll(Arrays.asList("C14", "LRW", "M15", "M14", "DDL", "M13", "M12", "DD3GVL", "NPH", "M11", "M10", "EVE", "MM3")); } public BeastToken() { @@ -71,7 +71,7 @@ public class BeastToken extends Token { if (getOriginalExpansionSetCode().equals("M15")) { this.setTokenType(2); } - if (getOriginalExpansionSetCode().equals("DD3GVL") || getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD")) { + if (getOriginalExpansionSetCode().equals("DD3GVL") || getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD") || getOriginalExpansionSetCode().equals("MM3")) { this.setTokenType(1); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/BeastToken2.java b/Mage/src/main/java/mage/game/permanent/token/BeastToken2.java index ef82f2ace07..186e6c11281 100644 --- a/Mage/src/main/java/mage/game/permanent/token/BeastToken2.java +++ b/Mage/src/main/java/mage/game/permanent/token/BeastToken2.java @@ -42,7 +42,7 @@ public class BeastToken2 extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "DD3GVL")); + tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "DD3GVL", "MM3")); } public BeastToken2() { @@ -76,7 +76,7 @@ public class BeastToken2 extends Token { @Override public void setExpansionSetCodeForImage(String code) { super.setExpansionSetCodeForImage(code); - if (getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD") || getOriginalExpansionSetCode().equals("DD3GVL")) { + if (getOriginalExpansionSetCode().equals("C14") || getOriginalExpansionSetCode().equals("DDD") || getOriginalExpansionSetCode().equals("DD3GVL") || getOriginalExpansionSetCode().equals("MM3")) { this.setTokenType(2); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/BirdToken.java b/Mage/src/main/java/mage/game/permanent/token/BirdToken.java index 1cd2e04d631..6babfef8b3e 100644 --- a/Mage/src/main/java/mage/game/permanent/token/BirdToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/BirdToken.java @@ -47,7 +47,7 @@ public class BirdToken extends Token { power = new MageInt(1); toughness = new MageInt(1); addAbility(FlyingAbility.getInstance()); - availableImageSetCodes.addAll(Arrays.asList("BNG", "RTR", "ZEN", "C16")); + availableImageSetCodes.addAll(Arrays.asList("BNG", "RTR", "ZEN", "C16", "MM3", "DGM")); } public BirdToken(final BirdToken token) { diff --git a/Mage/src/main/java/mage/game/permanent/token/CentaurToken.java b/Mage/src/main/java/mage/game/permanent/token/CentaurToken.java index d36a2886ac7..57f0be773b5 100644 --- a/Mage/src/main/java/mage/game/permanent/token/CentaurToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/CentaurToken.java @@ -28,6 +28,9 @@ package mage.game.permanent.token; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import mage.constants.CardType; import mage.MageInt; import mage.util.RandomUtil; @@ -38,6 +41,12 @@ import mage.util.RandomUtil; */ public class CentaurToken extends Token { + final static private List tokenImageSets = new ArrayList<>(); + + static { + tokenImageSets.addAll(Arrays.asList("RTR", "MM3")); + } + public CentaurToken() { super("Centaur", "3/3 green Centaur creature token"); cardType.add(CardType.CREATURE); @@ -46,7 +55,6 @@ public class CentaurToken extends Token { subtype.add("Centaur"); power = new MageInt(3); toughness = new MageInt(3); - setOriginalExpansionSetCode("RTR"); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/DragonToken.java b/Mage/src/main/java/mage/game/permanent/token/DragonToken.java index 0059cc6768b..579c9c89c77 100644 --- a/Mage/src/main/java/mage/game/permanent/token/DragonToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/DragonToken.java @@ -44,7 +44,7 @@ public class DragonToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("DTK", "MMA", "ALA")); + tokenImageSets.addAll(Arrays.asList("DTK", "MMA", "ALA", "MM3")); } public DragonToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/ElephantToken.java b/Mage/src/main/java/mage/game/permanent/token/ElephantToken.java index a2827d76551..88b4593face 100644 --- a/Mage/src/main/java/mage/game/permanent/token/ElephantToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/ElephantToken.java @@ -43,7 +43,7 @@ public class ElephantToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("C14", "CNS", "DDD", "MM2", "WWK", "OGW", "C15", "DD3GVL")); + tokenImageSets.addAll(Arrays.asList("C14", "CNS", "DDD", "MM2", "WWK", "OGW", "C15", "DD3GVL", "MM3")); } public ElephantToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java b/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java index dbcc5450679..89cd0247c7b 100644 --- a/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/GoblinToken.java @@ -43,7 +43,7 @@ public class GoblinToken extends Token { static { tokenImageSets.addAll(Arrays.asList("10E", "ALA", "SOM", "M10", "NPH", "M13", "RTR", - "MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "DD3EVG", "MM2")); + "MMA", "M15", "C14", "KTK", "EVG", "DTK", "ORI", "DDG", "DDN", "DD3EVG", "MM2", "MM3", "EMA", "C16")); } public GoblinToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/GolemToken.java b/Mage/src/main/java/mage/game/permanent/token/GolemToken.java index 4bbd644b703..83fcd2913de 100644 --- a/Mage/src/main/java/mage/game/permanent/token/GolemToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/GolemToken.java @@ -43,7 +43,7 @@ public class GolemToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("MM2", "NPH", "SOM")); + tokenImageSets.addAll(Arrays.asList("MM2", "NPH", "SOM", "MM3")); } public GolemToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/SaprolingToken.java b/Mage/src/main/java/mage/game/permanent/token/SaprolingToken.java index 01bd26a3efb..d90d0e7cb41 100644 --- a/Mage/src/main/java/mage/game/permanent/token/SaprolingToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/SaprolingToken.java @@ -44,7 +44,7 @@ public class SaprolingToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("10E", "ALA", "DDE", "DDH", "DDJ", "M12", "M13", "M14", "MM2", "MMA", "RTR", "C15")); + tokenImageSets.addAll(Arrays.asList("10E", "ALA", "DDE", "DDH", "DDJ", "M12", "M13", "M14", "MM2", "MMA", "RTR", "C15", "MM3", "C16")); } public SaprolingToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/SoldierToken.java b/Mage/src/main/java/mage/game/permanent/token/SoldierToken.java index 996b3ff6037..2fed39fb0df 100644 --- a/Mage/src/main/java/mage/game/permanent/token/SoldierToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/SoldierToken.java @@ -44,7 +44,7 @@ public class SoldierToken extends Token { static { tokenImageSets.addAll(Arrays.asList("10E", "M15", "C14", "ORI", "ALA", "DDF", "THS", "M12", "M13", "MM2", "MMA", "RTR", - "SOM", "DDO", "M10", "ORI", "EMN", "EMA", "CN2", "C16")); + "SOM", "DDO", "M10", "ORI", "EMN", "EMA", "CN2", "C16", "MM3")); } public SoldierToken() { @@ -65,7 +65,7 @@ public class SoldierToken extends Token { if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("THS")) { this.setTokenType(RandomUtil.nextInt(2) + 1); } - if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("CN2")) { + if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("CN2") || getOriginalExpansionSetCode().equals("MM3")) { setTokenType(1); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/SoldierTokenWithHaste.java b/Mage/src/main/java/mage/game/permanent/token/SoldierTokenWithHaste.java index 458310b2ef8..7db5eb6c50e 100644 --- a/Mage/src/main/java/mage/game/permanent/token/SoldierTokenWithHaste.java +++ b/Mage/src/main/java/mage/game/permanent/token/SoldierTokenWithHaste.java @@ -28,6 +28,9 @@ package mage.game.permanent.token; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import mage.constants.CardType; import mage.MageInt; import mage.abilities.keyword.HasteAbility; @@ -38,6 +41,12 @@ import mage.abilities.keyword.HasteAbility; */ public class SoldierTokenWithHaste extends Token { + final static private List tokenImageSets = new ArrayList<>(); + + static { + tokenImageSets.addAll(Arrays.asList("GTC", "MM3")); + } + public SoldierTokenWithHaste() { super("Soldier", "1/1 red and white Soldier creature token with haste"); cardType.add(CardType.CREATURE); @@ -47,6 +56,23 @@ public class SoldierTokenWithHaste extends Token { power = new MageInt(1); toughness = new MageInt(1); addAbility(HasteAbility.getInstance()); - setOriginalExpansionSetCode("GTC"); + } + + + @Override + public void setExpansionSetCodeForImage(String code) { + super.setExpansionSetCodeForImage(code); + if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("MM3")) { + setTokenType(2); + } + } + + public SoldierTokenWithHaste(final SoldierTokenWithHaste token) { + super(token); + } + + @Override + public SoldierTokenWithHaste copy() { + return new SoldierTokenWithHaste(this); //To change body of generated methods, choose Tools | Templates. } } diff --git a/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java b/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java index a1ff71d0a99..8dbe924221e 100644 --- a/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/SpiritWhiteToken.java @@ -42,7 +42,7 @@ public class SpiritWhiteToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16")); + tokenImageSets.addAll(Arrays.asList("AVR", "C14", "CNS", "DDC", "DDK", "FRF", "ISD", "KTK", "M15", "MM2", "SHM", "SOI", "EMA", "C16", "MM3")); } public SpiritWhiteToken() { diff --git a/Mage/src/main/java/mage/game/permanent/token/WarriorVigilantToken.java b/Mage/src/main/java/mage/game/permanent/token/WarriorVigilantToken.java new file mode 100644 index 00000000000..c3e00a228f2 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/WarriorVigilantToken.java @@ -0,0 +1,62 @@ +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.game.permanent.token; + +import java.util.Arrays; + +import mage.MageInt; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.CardType; + +/** + * + * @author fireshoes + */ +public class WarriorVigilantToken extends Token { + + public WarriorVigilantToken() { + super("Warrior", "1/1 white Warrior creature token with vigilance"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add("Warrior"); + power = new MageInt(1); + toughness = new MageInt(1); + addAbility(VigilanceAbility.getInstance()); + availableImageSetCodes.addAll(Arrays.asList("AKH")); + } + + public WarriorVigilantToken(final WarriorVigilantToken token) { + super(token); + } + + @Override + public WarriorVigilantToken copy() { + return new WarriorVigilantToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/WurmToken2.java b/Mage/src/main/java/mage/game/permanent/token/WurmToken2.java index e4b27e261dc..43fcceceb16 100644 --- a/Mage/src/main/java/mage/game/permanent/token/WurmToken2.java +++ b/Mage/src/main/java/mage/game/permanent/token/WurmToken2.java @@ -28,6 +28,9 @@ package mage.game.permanent.token; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import mage.constants.CardType; import mage.MageInt; import mage.abilities.keyword.TrampleAbility; @@ -38,6 +41,12 @@ import mage.abilities.keyword.TrampleAbility; */ public class WurmToken2 extends Token { + final static private List tokenImageSets = new ArrayList<>(); + + static { + tokenImageSets.addAll(Arrays.asList("RTR", "MM3")); + } + public WurmToken2() { super("Wurm", "5/5 green Wurm creature token with trample"); cardType.add(CardType.CREATURE); @@ -46,6 +55,5 @@ public class WurmToken2 extends Token { power = new MageInt(5); toughness = new MageInt(5); addAbility(TrampleAbility.getInstance()); - setOriginalExpansionSetCode("RTR"); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/ZombieToken.java b/Mage/src/main/java/mage/game/permanent/token/ZombieToken.java index 0cd8b1b150e..19e1af1e7c2 100644 --- a/Mage/src/main/java/mage/game/permanent/token/ZombieToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/ZombieToken.java @@ -44,8 +44,8 @@ public class ZombieToken extends Token { final static private List tokenImageSets = new ArrayList<>(); static { - tokenImageSets.addAll(Arrays.asList("10E", "M10", "M11", "M12", "M13", "M14", "M15", "MBS", "ALA", "ISD", "C14", "C15", "CNS", - "MMA", "BNG", "KTK", "DTK", "ORI", "OGW", "SOI", "EMN", "EMA")); + tokenImageSets.addAll(Arrays.asList("10E", "M10", "M11", "M12", "M13", "M14", "M15", "MBS", "ALA", "ISD", "C14", "C15", "C16", "CNS", + "MMA", "BNG", "KTK", "DTK", "ORI", "OGW", "SOI", "EMN", "EMA", "MM3")); } public ZombieToken() { diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java index 777bc0a9adc..e71ea49ed98 100644 --- a/Mage/src/main/java/mage/game/stack/Spell.java +++ b/Mage/src/main/java/mage/game/stack/Spell.java @@ -27,8 +27,10 @@ */ package mage.game.stack; -import java.util.*; - +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.Mana; @@ -331,8 +333,8 @@ public class Spell extends StackObjImpl implements Card { * determine whether card was kicked or not. E.g. Desolation Angel */ private void updateOptionalCosts(int index) { - Ability abilityOrig = spellCards.get(index).getAbilities().get(spellAbilities.get(index).getId()); - if (abilityOrig != null) { + spellCards.get(index).getAbilities().get(spellAbilities.get(index).getId()).ifPresent(abilityOrig + -> { for (Object object : spellAbilities.get(index).getOptionalCosts()) { Cost cost = (Cost) object; for (Cost costOrig : abilityOrig.getOptionalCosts()) { @@ -346,7 +348,7 @@ public class Spell extends StackObjImpl implements Card { } } } - } + }); } @Override @@ -746,24 +748,7 @@ public class Spell extends StackObjImpl implements Card { @Override public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList appliedEffects) { - ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), sourceId, this.getOwnerId(), Zone.STACK, Zone.EXILED, appliedEffects); - if (!game.replaceEvent(event)) { - game.getStack().remove(this); - game.rememberLKI(this.getId(), event.getFromZone(), this); - - if (!this.isCopiedSpell()) { - if (exileId == null) { - game.getExile().getPermanentExile().add(this.card); - } else { - game.getExile().createZone(exileId, name).add(this.card); - } - - game.setZone(this.card.getId(), event.getToZone()); - } - game.fireEvent(event); - return event.getToZone() == Zone.EXILED; - } - return false; + return this.card.moveToExile(exileId, name, sourceId, game, appliedEffects); } @Override diff --git a/Mage/src/main/java/mage/game/tournament/Tournament.java b/Mage/src/main/java/mage/game/tournament/Tournament.java index 266edc736ce..7cdad0eebf8 100644 --- a/Mage/src/main/java/mage/game/tournament/Tournament.java +++ b/Mage/src/main/java/mage/game/tournament/Tournament.java @@ -27,10 +27,6 @@ */ package mage.game.tournament; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.UUID; import mage.cards.ExpansionSet; import mage.cards.decks.Deck; import mage.game.draft.Draft; @@ -39,6 +35,12 @@ import mage.game.events.PlayerQueryEvent; import mage.game.events.TableEvent; import mage.game.result.ResultProtos.TourneyProto; import mage.players.Player; +import mage.players.PlayerType; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.UUID; /** * @@ -48,7 +50,7 @@ public interface Tournament { UUID getId(); - void addPlayer(Player player, String playerType); + void addPlayer(Player player, PlayerType playerType); void removePlayer(UUID playerId); diff --git a/Mage/src/main/java/mage/game/tournament/TournamentImpl.java b/Mage/src/main/java/mage/game/tournament/TournamentImpl.java index baccdf74f70..b5f5ed2a93b 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentImpl.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentImpl.java @@ -38,6 +38,7 @@ import mage.game.match.Match; import mage.game.match.MatchPlayer; import mage.game.result.ResultProtos.*; import mage.players.Player; +import mage.players.PlayerType; import mage.util.RandomUtil; import org.apache.log4j.Logger; @@ -82,7 +83,7 @@ public abstract class TournamentImpl implements Tournament { } @Override - public void addPlayer(Player player, String playerType) { + public void addPlayer(Player player, PlayerType playerType) { players.put(player.getId(), new TournamentPlayer(player, playerType)); } diff --git a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java index 3160e2598ac..4140eedec71 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java @@ -27,10 +27,12 @@ */ package mage.game.tournament; +import mage.game.match.MatchOptions; +import mage.players.PlayerType; + import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import mage.game.match.MatchOptions; /** * @@ -40,7 +42,7 @@ public class TournamentOptions implements Serializable { protected String name; protected String tournamentType; - protected List playerTypes = new ArrayList<>(); + protected List playerTypes = new ArrayList<>(); protected MatchOptions matchOptions; protected LimitedOptions limitedOptions; protected boolean watchingAllowed = true; @@ -65,7 +67,7 @@ public class TournamentOptions implements Serializable { this.tournamentType = tournamentType; } - public List getPlayerTypes() { + public List getPlayerTypes() { return playerTypes; } diff --git a/Mage/src/main/java/mage/game/tournament/TournamentPlayer.java b/Mage/src/main/java/mage/game/tournament/TournamentPlayer.java index 21afc64ffbb..0e0f6f7f817 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentPlayer.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentPlayer.java @@ -28,14 +28,16 @@ package mage.game.tournament; -import java.util.Set; import mage.cards.decks.Deck; import mage.constants.TournamentPlayerState; import mage.game.result.ResultProtos.TourneyPlayerProto; import mage.game.result.ResultProtos.TourneyQuitStatus; import mage.players.Player; +import mage.players.PlayerType; import mage.util.TournamentUtil; +import java.util.Set; + /** * * @author BetaSteward_at_googlemail.com @@ -43,7 +45,7 @@ import mage.util.TournamentUtil; public class TournamentPlayer { protected int points; - protected String playerType; + protected PlayerType playerType; protected TournamentPlayerState state; protected String stateInfo; protected String disconnectInfo; @@ -57,7 +59,7 @@ public class TournamentPlayer { protected TourneyQuitStatus quitStatus = TourneyQuitStatus.NO_TOURNEY_QUIT; protected TournamentPlayer replacedTournamentPlayer; - public TournamentPlayer(Player player, String playerType) { + public TournamentPlayer(Player player, PlayerType playerType) { this.player = player; this.playerType = playerType; this.state = TournamentPlayerState.JOINED; @@ -70,7 +72,7 @@ public class TournamentPlayer { return player; } - public String getPlayerType() { + public PlayerType getPlayerType() { return playerType; } @@ -232,7 +234,7 @@ public class TournamentPlayer { public TourneyPlayerProto toProto() { return TourneyPlayerProto.newBuilder() .setName(this.player.getName()) - .setPlayerType(this.playerType) + .setPlayerType(this.playerType.toString()) .setQuit(this.quitStatus) .build(); } diff --git a/Mage/src/main/java/mage/game/turn/Turn.java b/Mage/src/main/java/mage/game/turn/Turn.java index cd4f6301382..1de664ff84d 100644 --- a/Mage/src/main/java/mage/game/turn/Turn.java +++ b/Mage/src/main/java/mage/game/turn/Turn.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; +import mage.abilities.Ability; import mage.constants.PhaseStep; import mage.constants.TurnPhase; import mage.counters.CounterType; @@ -268,8 +269,9 @@ public class Turn implements Serializable { * * @param game * @param activePlayerId + * @param source */ - public void endTurn(Game game, UUID activePlayerId) { + public void endTurn(Game game, UUID activePlayerId, Ability source) { // Ending the turn this way (Time Stop) means the following things happen in order: setEndTurnRequested(true); @@ -277,9 +279,9 @@ public class Turn implements Serializable { // 1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve. // It also includes spells and abilities that can't be countered. while (!game.getStack().isEmpty()) { - StackObject stackObject = game.getStack().removeLast(); + StackObject stackObject = game.getStack().peekFirst(); if (stackObject instanceof Spell) { - ((Spell) stackObject).moveToExile(null, "", null, game); + ((Spell) stackObject).moveToExile(null, "", source.getSourceId(), game); } } // 2) All attacking and blocking creatures are removed from combat. diff --git a/Mage/src/main/java/mage/players/Library.java b/Mage/src/main/java/mage/players/Library.java index 9b4a8adc8f5..65fab4a09e9 100644 --- a/Mage/src/main/java/mage/players/Library.java +++ b/Mage/src/main/java/mage/players/Library.java @@ -27,26 +27,16 @@ */ package mage.players; -import java.io.Serializable; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - import mage.cards.Card; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; import mage.util.RandomUtil; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + /** * @author BetaSteward_at_googlemail.com */ @@ -182,11 +172,7 @@ public class Library implements Serializable { } public List getCards(Game game) { - List cards = new ArrayList<>(); - for (UUID cardId : library) { - cards.add(game.getCard(cardId)); - } - return cards; + return library.stream().map(game::getCard).collect(Collectors.toList()); } public Set getTopCards(Game game, int amount) { @@ -214,13 +200,7 @@ public class Library implements Serializable { } public int count(FilterCard filter, Game game) { - int result = 0; - for (UUID card : library) { - if (filter.match(game.getCard(card), game)) { - result++; - } - } - return result; + return (int) library.stream().filter(cardId -> filter.match(game.getCard(cardId), game)).count(); } public boolean isEmptyDraw() { diff --git a/Mage/src/main/java/mage/players/ManaPool.java b/Mage/src/main/java/mage/players/ManaPool.java index 71e131b29be..0df36cae431 100644 --- a/Mage/src/main/java/mage/players/ManaPool.java +++ b/Mage/src/main/java/mage/players/ManaPool.java @@ -118,7 +118,7 @@ public class ManaPool implements Serializable { return false; } if (autoPayment && autoPaymentRestricted && !wasManaAddedBeyondStock() && manaType != unlockedManaType) { - // if automatic restricted payment and there is laready mana in the pool + // if automatic restricted payment and there is already mana in the pool // and the needed mana type was not unlocked, nothing will be paid return false; } @@ -146,7 +146,7 @@ public class ManaPool implements Serializable { continue; } if (mana.get(usableManaType) > 0) { - GameEvent event = new GameEvent(GameEvent.EventType.MANA_PAYED, ability.getId(), mana.getSourceId(), ability.getControllerId(), 0, mana.getFlag()); + GameEvent event = new GameEvent(GameEvent.EventType.MANA_PAID, ability.getId(), mana.getSourceId(), ability.getControllerId(), 0, mana.getFlag()); event.setData(mana.getOriginalId().toString()); game.fireEvent(event); mana.remove(usableManaType); @@ -205,6 +205,10 @@ public class ManaPool implements Serializable { doNotEmptyManaTypes.add(manaType); } + public void init() { + manaItems.clear(); + } + public int emptyPool(Game game) { int total = 0; Iterator it = manaItems.iterator(); @@ -424,7 +428,7 @@ public class ManaPool implements Serializable { for (ConditionalMana mana : getConditionalMana()) { if (mana.get(manaType) > 0 && mana.apply(ability, game, mana.getManaProducerId(), costToPay)) { mana.set(manaType, mana.get(manaType) - 1); - GameEvent event = new GameEvent(GameEvent.EventType.MANA_PAYED, ability.getId(), mana.getManaProducerId(), ability.getControllerId(), 0, mana.getFlag()); + GameEvent event = new GameEvent(GameEvent.EventType.MANA_PAID, ability.getId(), mana.getManaProducerId(), ability.getControllerId(), 0, mana.getFlag()); event.setData(mana.getManaProducerOriginalId().toString()); game.fireEvent(event); break; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 1630782d5d4..dae06986196 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -422,6 +422,7 @@ public abstract class PlayerImpl implements Player, Serializable { this.castSourceIdWithAlternateMana = null; this.castSourceIdManaCosts = null; this.castSourceIdCosts = null; + this.getManaPool().init(); // needed to remove mana that not empties on step change from previous game if left } /** diff --git a/Mage/src/main/java/mage/players/PlayerType.java b/Mage/src/main/java/mage/players/PlayerType.java new file mode 100644 index 00000000000..2f8c36e6106 --- /dev/null +++ b/Mage/src/main/java/mage/players/PlayerType.java @@ -0,0 +1,32 @@ +package mage.players; + +/** + * Created by IGOUDT on 2-4-2017. + */ +public enum PlayerType { + HUMAN("Human"), + COMPUTER_DRAFT_BOT("Computer - draftbot"), + COMPUTER_MINIMAX_HYBRID("Computer - minimax hybrid"), + COMPUTER_MONTE_CARLO("Computer - monte carlo"), + COMPUTER_MAD("Computer - mad"); + + String description; + + PlayerType(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } + + public static PlayerType getByDescription(String description) { + for (PlayerType type : values()) { + if (type.description.equals(description)) { + return type; + } + } + throw new IllegalArgumentException(String.format("PlayerType (%s) is not configured", description)); + } +} diff --git a/Mage/src/main/java/mage/target/TargetAmount.java b/Mage/src/main/java/mage/target/TargetAmount.java index b9f8f5fabf2..4e6fe35fcfc 100644 --- a/Mage/src/main/java/mage/target/TargetAmount.java +++ b/Mage/src/main/java/mage/target/TargetAmount.java @@ -34,6 +34,7 @@ import mage.abilities.dynamicvalue.common.StaticValue; import mage.constants.Outcome; import mage.game.Game; import java.util.*; +import java.util.stream.Collectors; /** * @@ -142,12 +143,7 @@ public abstract class TargetAmount extends TargetImpl { t.addTarget(targetId, n, source, game, true); if (t.remainingAmount > 0) { if (targets.size() > 1) { - Set newTargets = new HashSet<>(); - for (UUID newTarget: targets) { - if (!newTarget.equals(targetId)) { - newTargets.add(newTarget); - } - } + Set newTargets = targets.stream().filter(newTarget -> !newTarget.equals(targetId)).collect(Collectors.toSet()); addTargets(t, newTargets, options, source, game); } } diff --git a/Mage/src/main/java/mage/target/TargetCard.java b/Mage/src/main/java/mage/target/TargetCard.java index 87b26a64e46..9103309c21c 100644 --- a/Mage/src/main/java/mage/target/TargetCard.java +++ b/Mage/src/main/java/mage/target/TargetCard.java @@ -27,9 +27,7 @@ */ package mage.target; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; +import mage.MageItem; import mage.cards.Card; import mage.cards.Cards; import mage.constants.Zone; @@ -38,6 +36,11 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + /** * * @author BetaSteward_at_googlemail.com @@ -200,11 +203,7 @@ public class TargetCard extends TargetObject { } public Set possibleTargets(UUID sourceControllerId, Cards cards, Game game) { - Set possibleTargets = new HashSet<>(); - for (Card card : cards.getCards(filter, game)) { - possibleTargets.add(card.getId()); - } - return possibleTargets; + return cards.getCards(filter,game).stream().map(MageItem::getId).collect(Collectors.toSet()); } @Override diff --git a/Mage/src/main/java/mage/target/TargetPlayer.java b/Mage/src/main/java/mage/target/TargetPlayer.java index d70085d98a8..af3fab1ad08 100644 --- a/Mage/src/main/java/mage/target/TargetPlayer.java +++ b/Mage/src/main/java/mage/target/TargetPlayer.java @@ -27,15 +27,16 @@ */ package mage.target; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.filter.FilterPlayer; import mage.game.Game; import mage.players.Player; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -158,12 +159,7 @@ public class TargetPlayer extends TargetImpl { if (getNumberOfTargets() == 0 && targets.isEmpty()) { return true; // 0 targets selected is valid } - for (UUID playerId : targets.keySet()) { - if (canTarget(playerId, source, game)) { - return true; - } - } - return false; + return targets.keySet().stream().anyMatch(playerId -> canTarget(playerId, source, game)); } @Override diff --git a/Mage/src/main/java/mage/target/TargetSpell.java b/Mage/src/main/java/mage/target/TargetSpell.java index 408e277bf93..9495b4dbec4 100644 --- a/Mage/src/main/java/mage/target/TargetSpell.java +++ b/Mage/src/main/java/mage/target/TargetSpell.java @@ -27,9 +27,6 @@ */ package mage.target; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.constants.Zone; import mage.filter.FilterSpell; @@ -37,6 +34,11 @@ import mage.game.Game; import mage.game.stack.Spell; import mage.game.stack.StackObject; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + /** * * @author BetaSteward_at_googlemail.com @@ -112,13 +114,10 @@ public class TargetSpell extends TargetObject { @Override public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { - Set possibleTargets = new HashSet<>(); - for (StackObject stackObject : game.getStack()) { - if (canBeChosen(stackObject, sourceId, sourceControllerId, game)) { - possibleTargets.add(stackObject.getId()); - } - } - return possibleTargets; + return game.getStack().stream() + .filter(stackObject -> canBeChosen(stackObject, sourceId, sourceControllerId, game)) + .map(StackObject::getId) + .collect(Collectors.toSet()); } @Override diff --git a/Mage/src/main/java/mage/target/Targets.java b/Mage/src/main/java/mage/target/Targets.java index f0565aa76f5..43ed15e295a 100644 --- a/Mage/src/main/java/mage/target/Targets.java +++ b/Mage/src/main/java/mage/target/Targets.java @@ -27,14 +27,16 @@ */ package mage.target; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.abilities.Ability; import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + /** * * @author BetaSteward_at_googlemail.com @@ -51,13 +53,7 @@ public class Targets extends ArrayList { } public List getUnchosen() { - List unchosen = new ArrayList<>(); - for (Target target : this) { - if (!target.isChosen()) { - unchosen.add(target); - } - } - return unchosen; + return stream().filter(target -> !target.isChosen()).collect(Collectors.toList()); } public void clearChosen() { @@ -67,12 +63,7 @@ public class Targets extends ArrayList { } public boolean isChosen() { - for (Target target : this) { - if (!target.isChosen()) { - return false; - } - } - return true; + return stream().allMatch(Target::isChosen); } public boolean choose(Outcome outcome, UUID playerId, UUID sourceId, Game game) { @@ -122,12 +113,8 @@ public class Targets extends ArrayList { public boolean stillLegal(Ability source, Game game) { // 608.2 // The spell or ability is countered if all its targets, for every instance of the word "target," are now illegal - int illegalCount = 0; - for (Target target : this) { - if (!target.isLegal(source, game)) { - illegalCount++; - } - } + int illegalCount = (int) stream().filter(target -> !target.isLegal(source, game)).count(); + // it is legal when either there is no target or not all targets are illegal return this.isEmpty() || this.size() != illegalCount; } @@ -142,12 +129,7 @@ public class Targets extends ArrayList { * @return - true if enough valid targets exist */ public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { - for (Target target : this) { - if (!target.canChoose(sourceId, sourceControllerId, game)) { - return false; - } - } - return true; + return stream().allMatch(target -> target.canChoose(sourceId, sourceControllerId, game)); } /** @@ -160,12 +142,7 @@ public class Targets extends ArrayList { * @return - true if enough valid objects exist */ public boolean canChoose(UUID sourceControllerId, Game game) { - for (Target target : this) { - if (!target.canChoose(sourceControllerId, game)) { - return false; - } - } - return true; + return stream().allMatch(target -> target.canChoose(sourceControllerId, game)); } public UUID getFirstTarget() { @@ -174,7 +151,6 @@ public class Targets extends ArrayList { } return null; } - public Targets copy() { return new Targets(this); } diff --git a/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java b/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java index c9d116bd969..9b472017ed3 100644 --- a/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java +++ b/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java @@ -28,27 +28,27 @@ package mage.target.common; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; -import mage.constants.Zone; import mage.abilities.Ability; import mage.constants.AbilityType; +import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterAbility; import mage.game.Game; import mage.game.stack.StackObject; import mage.target.TargetObject; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author LevelX2 */ public class TargetActivatedOrTriggeredAbility extends TargetObject { - public TargetActivatedOrTriggeredAbility() { + public TargetActivatedOrTriggeredAbility() { this.minNumberOfTargets = 1; this.maxNumberOfTargets = 1; this.zone = Zone.STACK; @@ -78,12 +78,9 @@ public class TargetActivatedOrTriggeredAbility extends TargetObject { @Override public boolean canChoose(UUID sourceControllerId, Game game) { - for (StackObject stackObject : game.getStack()) { - if (isActivatedOrTriggeredAbility(stackObject)) { - return true; - } - } - return false; + return game.getStack() + .stream() + .anyMatch(TargetActivatedOrTriggeredAbility::isActivatedOrTriggeredAbility); } @Override @@ -93,13 +90,10 @@ public class TargetActivatedOrTriggeredAbility extends TargetObject { @Override public Set possibleTargets(UUID sourceControllerId, Game game) { - Set possibleTargets = new HashSet<>(); - for (StackObject stackObject : game.getStack()) { - if (isActivatedOrTriggeredAbility(stackObject)) { - possibleTargets.add(stackObject.getStackAbility().getId()); - } - } - return possibleTargets; + return game.getStack().stream() + .filter(TargetActivatedOrTriggeredAbility::isActivatedOrTriggeredAbility) + .map(stackObject -> stackObject.getStackAbility().getId()) + .collect(Collectors.toSet()); } @Override @@ -117,9 +111,9 @@ public class TargetActivatedOrTriggeredAbility extends TargetObject { return false; } if (stackObject instanceof Ability) { - Ability ability = (Ability)stackObject; + Ability ability = (Ability) stackObject; return ability.getAbilityType() == AbilityType.TRIGGERED - || ability.getAbilityType() == AbilityType.ACTIVATED; + || ability.getAbilityType() == AbilityType.ACTIVATED; } return false; } diff --git a/Mage/src/main/java/mage/target/common/TargetCardInGraveyardOrBattlefield.java b/Mage/src/main/java/mage/target/common/TargetCardInGraveyardOrBattlefield.java index e6ccb15a7e2..337b2711526 100644 --- a/Mage/src/main/java/mage/target/common/TargetCardInGraveyardOrBattlefield.java +++ b/Mage/src/main/java/mage/target/common/TargetCardInGraveyardOrBattlefield.java @@ -27,8 +27,6 @@ */ package mage.target.common; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.cards.Card; @@ -39,8 +37,10 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetCard; +import java.util.Set; +import java.util.UUID; + /** - * * @author LevelX2 */ public class TargetCardInGraveyardOrBattlefield extends TargetCard { @@ -82,8 +82,7 @@ public class TargetCardInGraveyardOrBattlefield extends TargetCard { } @Override - public boolean canTarget(UUID id, Ability source, Game game - ) { + public boolean canTarget(UUID id, Ability source, Game game) { Permanent permanent = game.getPermanent(id); if (permanent != null) { return filter.match(permanent, game); @@ -93,8 +92,7 @@ public class TargetCardInGraveyardOrBattlefield extends TargetCard { } @Override - public Set possibleTargets(UUID sourceControllerId, Game game - ) { + public Set possibleTargets(UUID sourceControllerId, Game game) { //return super.possibleTargets(sourceControllerId, game); //To change body of generated methods, choose Tools | Templates. Set possibleTargets = super.possibleTargets(sourceControllerId, game); for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterPermanent(), sourceControllerId, game)) { @@ -106,8 +104,7 @@ public class TargetCardInGraveyardOrBattlefield extends TargetCard { } @Override - public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game - ) { + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { Set possibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); MageObject targetSource = game.getObject(sourceId); for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterPermanent(), sourceControllerId, game)) { diff --git a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentWithDifferentTypes.java b/Mage/src/main/java/mage/target/common/TargetCreaturePermanentWithDifferentTypes.java index 9d2b1fd48a7..b4006f4e2d7 100644 --- a/Mage/src/main/java/mage/target/common/TargetCreaturePermanentWithDifferentTypes.java +++ b/Mage/src/main/java/mage/target/common/TargetCreaturePermanentWithDifferentTypes.java @@ -27,12 +27,12 @@ */ package mage.target.common; -import java.util.UUID; import mage.abilities.Ability; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.util.CardUtil; + +import java.util.UUID; /** * @@ -62,7 +62,7 @@ public class TargetCreaturePermanentWithDifferentTypes extends TargetCreaturePer UUID targetId = (UUID) object; Permanent selectedCreature = game.getPermanent(targetId); if (!creature.getId().equals(selectedCreature.getId())) { - if (CardUtil.shareSubtypes(creature, selectedCreature, game)) { + if (creature.shareSubtypes(selectedCreature, game)) { return false; } } diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index baecd62ca63..a431a616f6c 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -35,10 +35,8 @@ import mage.abilities.ActivatedAbility; import mage.abilities.SpellAbility; import mage.abilities.costs.VariableCost; import mage.abilities.costs.mana.*; -import mage.abilities.keyword.ChangelingAbility; import mage.cards.Card; import mage.cards.SplitCard; -import mage.constants.CardType; import mage.filter.FilterMana; import mage.game.Game; import mage.game.permanent.Permanent; @@ -84,57 +82,9 @@ public final class CardUtil { "Trap", "Arcane"}; public static final Set NON_CREATURE_SUBTYPES = new HashSet<>(Arrays.asList(NON_CHANGELING_SUBTYPES_VALUES)); - /** - * Checks whether two cards share card types. - * - * @param card1 - * @param card2 - * @return - */ - public static boolean shareTypes(Card card1, Card card2) { - if (card1 == null || card2 == null) { - throw new IllegalArgumentException("Params can't be null"); - } - for (CardType type : card1.getCardType()) { - if (card2.getCardType().contains(type)) { - return true; - } - } - return false; - } - - /** - * Checks whether two cards share card subtypes. - * - * @param card1 - * @param card2 - * @return - */ - public static boolean shareSubtypes(Card card1, Card card2, Game game) { - - if (card1 == null || card2 == null) { - throw new IllegalArgumentException("Params can't be null"); - } - - if (card1.isCreature() && card2.isCreature()) { - if (card1.getAbilities().contains(ChangelingAbility.getInstance()) - || card1.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE) - || card2.getAbilities().contains(ChangelingAbility.getInstance()) - || card2.getSubtype(game).contains(ChangelingAbility.ALL_CREATURE_TYPE)) { - return true; - } - } - for (String subtype : card1.getSubtype(game)) { - if (card2.getSubtype(game).contains(subtype)) { - return true; - } - } - - return false; - } /** * Increase spell or ability cost to be paid. diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index caa9156a522..f586453abb3 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -110,6 +110,7 @@ Magic Player Rewards|MagicPlayerRewards| Magic: The Gathering-Commander|Commander| Magic: The Gathering-Conspiracy|Conspiracy| Masterpiece Series|MasterpieceSeries| +Masterpiece Series Amonkhet|MasterpieceSeriesAmonkhet| Masters Edition|MastersEdition| Masters Edition II|MastersEditionII| Masters Edition III|MastersEditionIII| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7fbd5d3285a..bdb3addad84 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -10736,6 +10736,7 @@ Angel of Deliverance|Launch Party|35|R|{6}{W}{W}|Creature - Angel|6|6|Flying$ Identity Thief|Launch Party|36|R|{2}{U}{U}|Creature - Shapeshifter|0|3|Whenever Identity Thief attacks, you may exile another target non-token creature. If you do, Identity Thief becomes a copy of that creature until end of turn. Return the exiled card to the battlefield under its owner's control at the beginning of the next end step.| Saheeli's Artistry|Launch Party|37|R|{4}{U}{U}|Sorcery|||Choose one or both — Create a token that's a copy of target artifact.; or Create a token that's a copy of target creature, except it's an artifact in addition to its other types.| Quicksmith Rebel|Launch Party|38|R|{3}{R}|Creature - Human Artificer|3|2|When Quicksmith Rebel enters the battlefield, target artifact you control gains "{T}: This artifact deals 2 damage to target creature or player" for as long as you control Quicksmith Rebel.| +Oracle's Vault|Launch Party|39|R|{4}|Artifact|||{2}, {T}: Exile the top card of your library. Until end of turn, you may play that card. Put a brick counter on Oracle's Vault.${T}: Exile the top card of your library. Until end of turn, you may play that card without paying its mana cost. Activate this ability only if there are three or more brick counters on Oracle's Vault.| Abomination|Legends|1|U|{3}{B}{B}|Creature - Horror|2|6|Whenever Abomination blocks or becomes blocked by a green or white creature, destroy that creature at end of combat.| Evil Eye of Orms-by-Gore|Legends|10|U|{4}{B}|Creature - Eye|3|6|Non-Eye creatures you control can't attack.$Evil Eye of Orms-by-Gore can't be blocked except by Walls.| Fire Sprites|Legends|100|C|{1}{G}|Creature - Faerie|1|1|Flying${G}, {tap}: Add {R} to your mana pool.| @@ -28612,7 +28613,8 @@ Heron's Grace Champion|Game Day|54|R|{2}{G}{W}|Creature - Human Knight|3|3|Flash Essence Extraction|Game Day|55|U|{1}{B}{B}|Instant|||Essence Extraction deals 3 damage to target creature and you gain 3 life.| Cultivator of Blades|Game Day|56|R|{3}{G}{G}|Creature - Elf Artificer|1|1|Fabricate 2$Whenever Cultivator of Blades attacks, you may have other attacking creatures get +X/+X until end of turn, where X is Cultivator of Blades's power.| Trophy Mage|Game Day|57|U|{2}{U}|Creature - Human Wizard|2|2|When Trophy Mage enters the battlefield, you may search your library for an artifact card with converted mana cost 3, reveal it, put it into your hand, then shuffle your library.| -Yahenni's Expertise|Aether Revolt|75|R|{2}{B}{B}|Sorcery|||All creatures get -3/-3 until end of turn.$You may cast a card with converted mana cost 3 or less from your hand without paying its mana cost.| +Yahenni's Expertise|Game Day|58|R|{2}{B}{B}|Sorcery|||All creatures get -3/-3 until end of turn.$You may cast a card with converted mana cost 3 or less from your hand without paying its mana cost.| +Glorybringer|Game Day|59|R|{3}{R}{R}|Creature - Dragon|4|4|Flying, haste$You may exert Glorybringer as it attacks. When you do, it deals 4 damage to target non-Dragon creature an opponent controls.| Garruk Relentless|Innistrad|181a|M|{3}{G}|Planeswalker - Garruk|||When Garruk Relentless has two or fewer loyalty counters on him, transform him.$0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him.$0: Put a 2/2 green Wolf creature token onto the battlefield.| Garruk, the Veil-Cursed|Innistrad|181b|M||Planeswalker - Garruk|||+1: Put a 1/1 black Wolf creature token with deathtouch onto the battlefield.$-1: Sacrifice a creature. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle your library.$-3: Creatures you control gain trample and get +X/+X until end of turn, where X is the number of creature cards in your graveyard.| Stand|Invasion|292a|U|{W}|Instant|||Prevent the next 2 damage that would be dealt to target creature this turn.$| @@ -28844,6 +28846,7 @@ Ulvenwald Observer|Media Inserts|161|R|{4}{G}{G}|Creature - Treefolk|6|6|Wheneve Skyship Stalker|Media Inserts|162|R|{2}{R}{R}|Creature - Dragon|3|3|Flying${R}: Skyship Stalker gets +1/+0 until end of turn.${R}: Skyship Stalker gains first strike until end of turn.${R}: Skyship Stalker gains haste until end of turn.| Emrakul, the Aeons Torn|Media Inserts|163|M|{15}|Legendary Creature - Eldrazi|15|15|Emrakul, the Aeons Torn can't be countered.$When you cast Emrakul, take an extra turn after this one.$Flying, protection from colored spells, annihilator 6$When Emrakul is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.| Scrap Trawler|Media Inserts|164|R|{3}|Artifact Creature - Construct|3|2|Whenever Scrap Trawler or another artifact you control is put into a graveyard from the battlefield, return to your hand target artifact card in your graveyard with lesser converted mana cost.| +Archfiend of Ifnir|Media Inserts|165|R|{3}{B}{B}|Creature - Demon|5|4|Flying$Whenever you cycle or discard another card, put a -1/-1 counter on each creature your opponents control.$Cycling {2}| Kytheon, Hero of Akros|Media Inserts|994|Special|{W}|Legendary Creature - Human Soldier|2|1|At end of combat, if Kytheon, Hero of Akros and at least two other creatures attacked this combat, exile Kytheon, then return him to the battlefield transformed under his owner's control.${2}{W}: Kytheon gains indestructible until end of turn.| Gideon, Battle-Forged|Media Inserts|994|Special||Planeswalker - Gideon|3|+2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able.$+1: Until your next turn, target creature gains indestructible. Untap that creature.$0: Until end of turn, Gideon, Battle-Forged becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.| Jace, Vryn's Prodigy|Media Inserts|995|Special|{1}{U}|Legendary Creature - Human Wizard|0|2|{T}: Draw a card, then discard a card. If there are five or more cards in your graveyard, exile Jace, Vryn''s Prodigy, then return him to the battefield transformed under his owner's control. | @@ -30002,6 +30005,32 @@ Sword of War and Peace|Masterpiece Series|51|M|{3}|Artifact|||Equipped creature Trinisphere|Masterpiece Series|52|M|{3}|Artifact|||As long as Trinisphere is untapped, each spell that would cost less than three mana to cast costs three mana to cast.| Vedalken Shackles|Masterpiece Series|53|M|{3}|Artifact|||You may choose not to untap Vedalken Shackles during your untap step.${2}, {T}: Gain control of target creature with power less than or equal to the number of Islands you control for as long as Vedalken Shackles remains tapped.| Wurmcoil Engine|Masterpiece Series|54|M|{6}|Artifact Creature - Wurm|6|6|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.| +Austere Command|Masterpiece Series Amonkhet|1|Special|{4}{W}{W}|Sorcery|||Choose two - Destroy all artifacts.; Destroy all enchantments.; Destroy all creatures with converted mana cost 3 or less.; Destroy all creatures with converted mana cost 4 or greater.| +Aven Mindcensor|Masterpiece Series Amonkhet|2|Special|{2}{W}|Creature - Bird Wizard|2|1|Flash$Flying$If an opponent would search a library, that player search the top four cards of that library instead.| +Containment Priest|Masterpiece Series Amonkhet|3|Special|{1}{W}|Creature - Human Cleric|2|2|Flash$If a nontoken creature would enter the battlefield and it wasn't cast, exile it instead.| +Loyal Retainers|Masterpiece Series Amonkhet|4|Special|{2}{W}|Creature - Human Advisor|1|1|Sacrifice Loyal Retainers: Return target legendary creature card from your graveyard to the battlefield. Activate this ability only during your turn, before attackers are declared.| +Worship|Masterpiece Series Amonkhet|6|Special|{3}{W}|Enchantment|||If you control a creature, damage that would reduce your life total to less than 1 reduces it to 1 instant.| +Wrath of God|Masterpiece Series Amonkhet|7|Special|{2}{W}{W}|Sorcery|||Destroy all creatures. They can't be regenerated.| +Consecrated Sphinx|Masterpiece Series Amonkhet|8|Special|{4}{U}{U}|Creature - Sphinx|4|6|Flying$Whenever an opponent draws a card, you may draw two cards.| +Counterbalance|Masterpiece Series Amonkhet|9|Special|{U}{U}|Enchantment|||Whenever an opponent casts a spell, you may reveal the top card of your library. If you do, counter that spell if it has the same converted mana cost as the revealed card.| +Counterspell|Masterpiece Series Amonkhet|10|Special|{U}{U}|Instant|||Counter target spell.| +Cryptic Command|Masterpiece Series Amonkhet|11|Special|{1}{U}{U}{U}|Instant|||Choose two - Counter target spell.; Return target permanent to its owner's hand.; Tap all creatures your opponents control.; Draw a card.| +Daze|Masterpiece Series Amonkhet|12|Special|{1}{U}|Instant|||You may return an Island you control to its owner's hand rather than pay Daze's mana cost.$Counter target spell unless its controller pays {1}.| +Divert|Masterpiece Series Amonkhet|13|Special|{U}|Instant|||Change the target of target spell with a single target unless that spell's controller pays {2}.| +Force of Will|Masterpiece Series Amonkhet|14|Special|{3}{U}{U}|Instant|||You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.$Counter target spell.| +Pact of Negation|Masterpiece Series Amonkhet|16|Special|{0}|Instant|||Counter target spell.$At the beginning of your next upkeep, pay {3}{U}{U}. If you don't, you lose the game.| +Spell Pierce|Masterpiece Series Amonkhet|17|Special|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| +Stifle|Masterpiece Series Amonkhet|18|Special|{U}|Instant|||Counter target activated or triggered ability.| +Attrition|Masterpiece Series Amonkhet|19|Special|{1}{B}{B}|Enchantment|||{B}, Sacrifice a creature: Destroy target nonblack creature.| +Dark Ritual|Masterpiece Series Amonkhet|21|Special|{B}|Instant|||Add {B}{B}{B} to your mana pool.| +Diabolic Intent|Masterpiece Series Amonkhet|22|Special|{1}{B}|Sorcery|||As an additional cost to cast Diabolic Intent, sacrifice a creature.$Search your library for a card and put that card into your hand. Then shuffle your library.| +Entomb|Masterpiece Series Amonkhet|23|Special|{B}|Instant|||Search your library for a card and put that card into your graveyard. Then shuffle your library.| +Mind Twist|Masterpiece Series Amonkhet|24|Special|{X}{B}|Sorcery|||Target player discards X cards at random.| +Aggravated Assault|Masterpiece Series Amonkhet|25|Special|{2}{R}|Enchantment|||{3}{R}{R}: Untap all creatures you control. After this main phase, there is an additional combat phase followed by an additional main phase. Activate this ability only any time you could cast a sorcery.| +Chain Lightning|Masterpiece Series Amonkhet|26|Special|{R}|Sorcery|||Chain Lightning deals 3 damage to target creature or player. Then that player or that creature's controller may pay {R}{R}. If the player does, he or she may copy this spell and may choose a new target for that copy.| +Hazoret the Fervent|Masterpiece Series Amonkhet|27|Special|{3}{R}|Legendary Creature - God|5|4|Indestructible, haste$Hazoret the Fervent can't attack or block unless you have one or fewer cards in hand.${2}{R}, Discard a card: Hazoret deals 2 damage to each opponent.| +Maelstrom Pulse|Masterpiece Series Amonkhet|29|Special|{1}{B}{G}|Sorcery|||Destroy target nonland permanent and all other permanents with the same name as that permanent.| +Vindicate|Masterpiece Series Amonkhet|30|Special|{1}{W}{B}|Sorcery|||Destroy target permanent.| Duelist's Heritage|Commander 2016|1|R|{2}{W}|Enchantment|||Whenever one or more creatures attack, you may have target attacking creature gain double strike until end of turn.| Entrapment Maneuver|Commander 2016|2|R|{3}{W}|Instant|||Target player sacrifices an attacking creature. You create X 1/1 white Soldier creature tokens, where X is that creature's toughness.| Orzhov Advokist|Commander 2016|3|U|{2}{W}|Creature - Human Advisor|1|4|At the beginning of your upkeep, each player may put two +1/+1 counters on a creature he or she controls. If a player does, creatures that player controls can't attack you or a planeswalker you control until your next turn.| @@ -30798,3 +30827,91 @@ Selesnya Guildgate|Modern Masters 2017|246|C||Land - Gate|||Selesnya Guildgate e Shimmering Grotto|Modern Masters 2017|247|C||Land|||{T}: Add {C} to your mana pool.${1}, {T}: Add one mana of any color to your mana pool.| Simic Guildgate|Modern Masters 2017|248|C||Land - Gate|||Simic Guildgate enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.| Verdant Catacombs|Modern Masters 2017|249|R||Land|||{T}, Pay 1 life, Sacrifice Verdant Catacombs: Search your library for a Swamp or Forest card and put it onto the battlefield. Then shuffle your library.| +Anointer Priest|Amonkhet|3|C|{1}{W}|Creature - Human Cleric|1|3|Whenever a creature token enters the battlefield under your control, you gain 1 life.$Embalm {3}{W}| +Aven Mindcensor|Amonkhet|5|R|{2}{W}|Creature - Bird Wizard|2|1|Flash$Flying$If an opponent would search a library, that player searches the top four cards of that library instead.| +Cartouche of Solidarity|Amonkhet|7|C|{W}|Enchantment - Aura Cartouche|||Enchant creature you control$When Cartouche of Solidarity enters the battlefield, create a 1/1 white Warrior creature token with vigilance.$Enchanted creature gets +1/+1 and has first strike.| +Cast Out|Amonkhet|8|U|{3}{W}|Enchantment|||Flash$When Cast Out enters the battlefield, exile target nonland permanent an opponent controls until Cast Out leaves the battlefield.$Cycling {W}| +Djeru's Resolve|Amonkhet|11|C|{W}|Instant|||Untap target creature. Prevent all damage that would be dealt to it this turn.$Cycling {2}| +Impeccable Timing|Amonkhet|18|C|{1}{W}|Instant|||Impeccable Timing deals 3 damage to target attacking or blocking creature.| +In Oketra's Name|Amonkhet|19|C|{1}{W}|Instant|||Zombies you control get +2/+1 until end of turn. Other creatures you control get +1/+1 until end of turn.| +Mighty Leap|Amonkhet|20|C|{1}{W}|Instant|||Target creature gets +2/+2 and gains flying until end of turn.| +Renewed Faith|Amonkhet|25|U|{2}{W}|Instant|||You gain 6 life.$Cycling {1}{W}$When you cycle Renewed Faith, you may gain 2 life.| +Sacred Cat|Amonkhet|27|C|{W}|Creature - Cat|1|1|Lifelink$Embalm {W}| +Tah-Crop Elite|Amonkhet|31|C|{3}{W}|Creature - Bird Warrior|2|2|Flying$You may exert Tah-Crop Elite as it attacks. When you do, creatures you control get +1/+1 until end of turn.| +Trueheart Duelist|Amonkhet|35|U|{1}{W}|Creature - Human Warrior|2|2|Trueheart Duelist can block an additional creature each combat.$Embalm {2}{W}| +Unwavering Initiate|Amonkhet|36|C|{2}{W}|Creature - Human Warrior|3|2|Vigilance$Embalm {4}{W} ({4}{W}, Exile this card from your graveyard: Create a token that's a copy of it, except it's a white Zombie Human Warrior with no mana cost. Embalm only as a sorcery.)| +Ancient Crab|Amonkhet|40|C|{1}{U}{U}|Creature - Crab|1|5|| +Angler Drake|Amonkhet|41|U|{4}{U}{U}|Creature - Drake|4|4|Flying$When Angler Drake enters the battlefield, you may return target creature to its owner's hand.| +Decision Paralysis|Amonkhet|50|C|{3}{U}|Instant|||Tap up to two target creatures. Those creatures don't untap during their controller's next untap step.| +Drake Haven|Amonkhet|51|R|{2}{U}|Enchantment|||When you cycle or discard a card, you may pay {1}. If you do, create a 2/2 blue Drake creature token with flying.| +Essence Scatter|Amonkhet|52|C|{1}{U}|Instant|||Counter target creature spell.| +Kefnet the Careful|Amonkhet|59|M|{2}{U}|Legendary Creature - God|5|5|Flying, indestructible$Kefnet the Careful can't attack or block unless you have seven or more cards in your hand.${3}{U}: Draw a card. You may return a land you control to its owner's hand.| +Scribe of the Mindful|Amonkhet|68|C|{2}{U}|Creature - Human Cleric|2|2|{1}, {T}, Sacrifice Scribe of the Mindful: Return target instant or sorcery card from your graveyard to your hand.| +Trial of Knowledge|Amonkhet|73|U|{3}{U}|Enchantment|||When Trial of Knowledge enters the battlefield, draw three cards, then discard a card.$When a Cartouche enters the battlefield under your control, return Trial of Knowledge to its owner's hand.| +Archfiend of Ifnir|Amonkhet|78|R|{3}{B}{B}|Creature - Demon|5|4|Flying$Whenever you cycle or discard another card, put a -1/-1 counter on each creature your opponents control.$Cycling {2}| +Cursed Minotaur|Amonkhet|85|C|{2}{B}|Creature - Zombie Minotaur|3|2|Menace| +Dune Beetle|Amonkhet|89|C|{1}{B}|Creature - Insect|1|4|| +Gravedigger|Amonkhet|93|U|{3}{B}|Creature - Zombie|2|2|When Gravedigger enters the battlefield, you may return target creature card from your graveyard to your hand.| +Lay Bare the Heart|Amonkhet|96|U|{1}{B}|Sorcery|||Target opponent reveals his or her hand. You choose a nonlegendary, nonland card from it. That player discards that card.| +Miasma Mummy|Amonkhet|100|C|{1}{B}|Creature - Zombie Jackal|2|2|When Miasma Mummy enters the battlefield, each player discards a card.| +Nest of Scarabs|Amonkhet|101|U|{2}{B}|Enchantment|||Whenever you put one or more -1/-1 counters on a creature, create that many 1/1 black Insect tokens.| +Splendid Agony|Amonkhet|109|C|{2}{B}|Instant|||Distribute two -1/-1 counters among one or two target creatures.| +Ahn-Crop Crasher|Amonkhet|117|U|{2}{R}|Creature - Minotaur Warrior|3|2|Haste$You may exert Ahn-Crop Crasher as it attacks. When you do, target creature can't block this turn.| +Consuming Fervor|Amonkhet|126|U|{R}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +3/+3 and has "At the beginning of your upkeep, put a -1/-1 counter on this creature."| +Glorybringer|Amonkhet|174|R|{3}{R}{R}|Creature - Dragon|4|4|Flying, haste$You may exert Glorybringer as it attacks. When you do, it deals 4 damage to target non-Dragon creature an opponent controls.| +Flameblade Adept|Amonkhet|131|U|{R}|Creature - Jackal Warrior|1|2|Menace$Whenever you cycle or discard a card, Flameblade Adept gets +1/+0 until end of turn.| +Fling|Amonkhet|132|C|{1}{R}|Instant|||As an additional cost to cast Fling, sacrifice a creature.$Fling deals damage equal to the sacrificed creature's power to target creature or player.| +Hazoret the Fervent|Amonkhet|136|M|{3}{R}|Legendary Creature - God|5|4|Indestructible, haste$Hazoret the Fervent can't attack or block unless you have one or fewer cards in hand.${2}{R}, Discard a card: Hazoret deals 2 damage to each opponent.| +Limits of Solidarity|Amonkhet|140|U|{3}{R}|Sorcery|||Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn.$Cycling {2}| +Hyena Pack|Amonkhet|139|C|{2}{R}{R}|Creature - Hyena|3|4|| +Channeler Initiate|Amonkhet|160|R|{1}{G}|Creature - Human Druid|3|4|When Channeler Initiate enters the battlefield, put three -1/-1 counters on target creature you control.${T}, Remove a -1/-1 counter from Channeler Initiate: Add one mana of any color to your mana pool.| +Crocodile of the Crossing|Amonkhet|162|U|{3}{G}|Creature - Crocodile|5|4|Haste$When Crocodile of the Crossing enters the battlefield, put a -1/-1 counter on target creature you control.| +Exemplar of Strength|Amonkhet|165|U|{1}{G}|Creature - Human Warrior|4|4|When Exemplar of Strength enters the battlefield, put three -1/-1 counters on target creature you control.$Whenever Exemplar of Strength attacks, remove a -1/-1 counter from it. If you do, you gain 1 life.| +Giant Spider|Amonkhet|166|C|{3}{G}|Creature - Spider|2|4|Reach| +Prowling Serpopard|Amonkhet|180|R|{1}{G}{G}|Creature - Cat Snake|4|3|Prowling Serpopard can't be countered.$Creature spells you control can't be countered.| +Sixth Sense|Amonkhet|187|U|{G}|Enchantment - Aura|||Enchant creature$Enchanted creature has "Whenever this creature deals combat damage to a player, you may draw a card."| +Spidery Grasp|Amonkhet|188|C|{2}{G}|Instant|||Untap target creature. It gets +2/+4 and gains reach until end of turn.| +Temmet, Vizier of Naktamun|Amonkhet|207|R|{W}{U}|Legendary Creature - Human Cleric|2|2|At the beginning of combat on your turn, target creature you control gets +1/+1 until end of turn and can't be blocked this turn.$Embalm {3}{W}{U}| +Dusk|Amonkhet|210a|R|{2}{W}{W}|Sorcery|||Destroy all creatures with power 3 or greater.| +Dawn|Amonkhet|210b|R|{3}{W}{W}|Sorcery|||Aftermath (Cast this spell only from your graveyard. Then exile it.)$Return all creature cards with power 2 or less from your graveyard to your hand.| +Destined|Amonkhet|217a|U|{1}{B}|Instant|||Target creature gets +1/+0 and gains indestuctible until end of turn.| +Lead|Amonkhet|217b|U|{3}{G}|Sorcery|||Aftermath (Cast this spell only from your graveyard. Then exile it.)$All creatures able to block target creature this turn do so.| +Onward|Amonkhet|218a|U|{2}{R}|Instant|||Target creature gets +X/+0 until end of turn, where X is its power.| +Victory|Amonkhet|218b|U|{2}{W}|Sorcery|||Aftermath$Target creature gains double strike until end of turn.| +Prepared|Amonkhet|220a|R|{1}{W}|Instant|||Untap target creature. It gains +2/+2 and has lifelink until end of turn.| +Fight|Amonkhet|220b|R|{3}{G}|Sorcery|||Target creature you control fights target an opponent controls.| +Bontu's Monument|Amonkhet|225|U|{3}|Legendary Artifact|||Black creature spells you cast cost {1} less to cast.$Whenever you cast a creature spell, each opponent loses 1 life and you gain 1 life.| +Hazoret's Monument|Amonkhet|229|U|{3}|Legendary Artifact|||Red creature spells you cast cost {1} less to cast.$Whenever you cast a creature spell, you may discard a card. If you do, draw a card.| +Kefnet's Monument|Amonkhet|231|U|{3}|Legendary Artifact|||Blue creature spells you cast cost {1} less to cast.$Whenever you cast a creature spell, target creature an opponent controls doesn't untap during its controller's next untap step.| +Oketra's Monument|Amonkhet|233|U|{3}|Legendary Artifact|||White creature spells you cast cost {1} less to cast.$Whenever you cast a creature spell, create 1/1 white Warrior creature token with vigilance.| +Oracle's Vault|Amonkhet|234|R|{4}|Artifact|||{2}, {T}: Exile the top card of your library. Until end of turn, you may play that card. Put a brick counter on Oracle's Vault.${T}: Exile the top card of your library. Until end of turn, you may play that card without paying its mana cost. Activate this ability only if there are three or more brick counters on Oracle's Vault.| +Rhonas's Monument|Amonkhet|236|U|{3}|Legendary Artifact|||Green creature spells you cast cost {1} less to cast.$Whenever you cast a creature spell, target creature you control gets +2/+2 and gains trample until end of turn.| +Canyon Slough|Amonkhet|239|R||Land - Swamp Mountain|||({T}: Add {B} or {R} to your mana pool.)$Canyon Slough enters the battlefield tapped.$Cycling {2}| +Fetid Pools|Amonkhet|243|R||Land - Island Swamp|||({T}: Add {U} or {B} to your mana pool.)$Fetid Pools enters the battlefield tapped.$Cycling {2}| +Irrigated Farmland|Amonkhet|245|R||Land - Plains Island|||({T}: Add {W} or {U} to your mana pool.)$Irrigated Farmland enters the battlefield tapped.$Cycling {2}| +Scattered Groves|Amonkhet|247|R||Land - Forest Plains|||({T}: Add {G} or {W} to your mana pool.)$Scattered Groves enters the battlefield tapped.$Cycling {2}| +Sheltered Thicket|Amonkhet|248|R||Land - Mountain Forest|||({T}: Add {R} or {G} to your mana pool.)$Sheltered Thicket enters the battlefield tapped.$Cycling {2}| +Plains|Amonkhet|250|L||Basic Land - Plains|||| +Island|Amonkhet|251|L||Basic Land - Island|||| +Swamp|Amonkhet|252|L||Basic Land - Swamp|||| +Mountain|Amonkhet|253|L||Basic Land - Mountain|||| +Forest|Amonkhet|254|L||Basic Land - Forest|||| +Plains|Amonkhet|255|L||Basic Land - Plains|||| +Plains|Amonkhet|256|L||Basic Land - Plains|||| +Plains|Amonkhet|257|L||Basic Land - Plains|||| +Island|Amonkhet|258|L||Basic Land - Island|||| +Island|Amonkhet|259|L||Basic Land - Island|||| +Island|Amonkhet|260|L||Basic Land - Island|||| +Swamp|Amonkhet|261|L||Basic Land - Swamp|||| +Swamp|Amonkhet|262|L||Basic Land - Swamp|||| +Swamp|Amonkhet|263|L||Basic Land - Swamp|||| +Mountain|Amonkhet|264|L||Basic Land - Mountain|||| +Mountain|Amonkhet|265|L||Basic Land - Mountain|||| +Mountain|Amonkhet|266|L||Basic Land - Mountain|||| +Forest|Amonkhet|267|L||Basic Land - Forest|||| +Forest|Amonkhet|268|L||Basic Land - Forest|||| +Forest|Amonkhet|269|L||Basic Land - Forest|||| +Gideon, Martial Paragon|Amonkhet|270|M|{4}{W}|Planeswalker - Gideon|||+2: Untap all creatures you control. Those creatures get +1/+1 until end of turn.$0: Until end of turn, Gideon, Martial Paragon, becomes a 5/5 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.$-10: Creatures you control get +2/+2 until end of turn. Tap all creatures your opponents control.| +Graceful Cat|Amonkhet|273|C|{2}{W}|Creature - Cat|2|2|Whenever Graceful Cat attacks, it gets +1/+1 until end of turn.| +Liliana, Death Wielder|Amonkhet|274|M|{5}{B}{B}|Planeswalker - Liliana|||+2: Put a -1/-1 counter on up to one target creature.$-3: Destroy target creature with a -1/-1 counter on it.$-10: Return all creature cards from your graveyard to the battlefield.| +Tattered Mummy|Amonkhet|278|C|{1}{B}|Creature - Zombie Jackal|1|2|When Tattered Mummy dies, each opponent loses 2 life.| \ No newline at end of file diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index ec33c790b97..e131cd91321 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -128,6 +128,7 @@ Mercadian Masques|MMQ| Morningtide|MOR| Magic Player Rewards|MPRP| Masterpiece Series|MPS| +Masterpiece Series Amonkhet|MPS-AKH| Mirrodin|MRD| Nemesis|NEM| New Phyrexia|NPH|