diff --git a/Mage.Client/release/sample-decks/Commander/Commander 2016/Breed Lethality (GWUB).dck b/Mage.Client/release/sample-decks/Commander/Commander 2016/Breed Lethality (GWUB).dck index ddd95532234..013c0f960cd 100644 --- a/Mage.Client/release/sample-decks/Commander/Commander 2016/Breed Lethality (GWUB).dck +++ b/Mage.Client/release/sample-decks/Commander/Commander 2016/Breed Lethality (GWUB).dck @@ -17,7 +17,9 @@ 1 [C16:57] Abzan Falconer 1 [C16:56] Ash Barrens 1 [C16:9] Grip of Phyresis -5 [C16:337] Plains +2 [C16:337] Plains +1 [C16:338] Plains +2 [C16:339] Plains 1 [C16:99] Tezzeret's Gambit 1 [C16:217] Putrefy 1 [C16:7] Deepglow Skate @@ -67,17 +69,23 @@ 1 [C16:33] Ishai, Ojutai Dragonspeaker 1 [C16:40] Reyhan, Last of the Abzan 1 [C16:186] Bred for the Hunt -4 [C16:340] Island +1 [C16:340] Island +2 [C16:341] Island +1 [C16:342] Island 1 [C16:100] Thrummingbird 1 [C16:144] Champion of Lambholt 1 [C16:101] Treasure Cruise 1 [C16:266] Orzhov Signet -5 [C16:343] Swamp +2 [C16:343] Swamp +1 [C16:344] Swamp +2 [C16:345] Swamp 1 [C16:106] Bane of the Living 1 [C16:227] Vorel of the Hull Clade 1 [C16:44] Sylvan Reclamation 1 [C16:88] Disdainful Stroke 1 [C16:228] Vulturous Zombie -7 [C16:349] Forest +3 [C16:349] Forest +2 [C16:350] Forest +2 [C16:351] Forest 1 [C16:308] Murmuring Bosk SB: 1 [C16:28] Atraxa, Praetors' Voice diff --git a/Mage.Client/release/sample-decks/Commander/Commander 2016/Entropic Uprising (UBRG).dck b/Mage.Client/release/sample-decks/Commander/Commander 2016/Entropic Uprising (UBRG).dck index cfce6fc688e..e2ebfff4137 100644 --- a/Mage.Client/release/sample-decks/Commander/Commander 2016/Entropic Uprising (UBRG).dck +++ b/Mage.Client/release/sample-decks/Commander/Commander 2016/Entropic Uprising (UBRG).dck @@ -63,22 +63,30 @@ 1 [C16:184] Bloodbraid Elf 1 [C16:82] Aeon Chronicler 1 [C16:81] Academy Elite -5 [C16:340] Island +2 [C16:340] Island +2 [C16:341] Island +1 [C16:342] Island 1 [C16:143] Burgeoning 1 [C16:188] Coiling Oracle 1 [C16:101] Treasure Cruise 1 [C16:189] Consuming Aberration 1 [C16:222] Spellheart Chimera 1 [C16:49] Vial Smasher the Fierce -5 [C16:343] Swamp +2 [C16:343] Swamp +2 [C16:344] Swamp +1 [C16:345] Swamp 1 [C16:268] Rakdos Signet 1 [C16:47] Treacherous Terrain 1 [C16:104] Windfall 1 [C16:148] Far Wanderings 1 [C16:46] Thrasios, Triton Hero -5 [C16:346] Mountain +1 [C16:346] Mountain +2 [C16:347] Mountain +1 [C16:348] Mountain 1 [C16:105] Army of the Damned 1 [C16:303] Jungle Hollow -5 [C16:349] Forest +2 [C16:349] Forest +2 [C16:350] Forest +1 [C16:351] Forest 1 [C16:229] Whispering Madness SB: 1 [C16:50] Yidris, Maelstrom Wielder diff --git a/Mage.Client/release/sample-decks/Commander/Commander 2016/Invent Superiority (WUBR).dck b/Mage.Client/release/sample-decks/Commander/Commander 2016/Invent Superiority (WUBR).dck index d197ca84e29..a9583cbcbd4 100644 --- a/Mage.Client/release/sample-decks/Commander/Commander 2016/Invent Superiority (WUBR).dck +++ b/Mage.Client/release/sample-decks/Commander/Commander 2016/Invent Superiority (WUBR).dck @@ -19,7 +19,9 @@ 1 [C16:12] Curse of Vengeance 1 [C16:9] Grip of Phyresis 1 [C16:8] Faerie Artisans -5 [C16:337] Plains +1 [C16:337] Plains +2 [C16:338] Plains +2 [C16:339] Plains 1 [C16:6] Coastal Breach 1 [C16:64] Dispeller's Capsule 1 [C16:281] Arcane Sanctum @@ -68,17 +70,23 @@ 1 [C16:140] Whipflare 1 [C16:262] Mycosynth Wellspring 1 [C16:263] Myr Battlesphere -5 [C16:340] Island +2 [C16:340] Island +1 [C16:341] Island +2 [C16:342] Island 1 [C16:264] Myr Retriever 1 [C16:221] Sharuum the Hegemon 1 [C16:265] Nevinyrral's Disk -4 [C16:343] Swamp +1 [C16:343] Swamp +2 [C16:344] Swamp +1 [C16:345] Swamp 1 [C16:223] Sphinx Summoner 1 [C16:102] Trinket Mage 1 [C16:224] Sydri, Galvanic Genius 1 [C16:103] Vedalken Engineer 1 [C16:269] Shimmer Myr -4 [C16:346] Mountain +2 [C16:346] Mountain +1 [C16:347] Mountain +1 [C16:348] Mountain 1 [C16:89] Etherium Sculptor 1 [C16:107] Beacon of Unrest 1 [C16:109] Executioner's Capsule diff --git a/Mage.Client/release/sample-decks/Commander/Commander 2016/Open Hostility (BRGW).dck b/Mage.Client/release/sample-decks/Commander/Commander 2016/Open Hostility (BRGW).dck index c0028d1d0f9..9d2ef543779 100644 --- a/Mage.Client/release/sample-decks/Commander/Commander 2016/Open Hostility (BRGW).dck +++ b/Mage.Client/release/sample-decks/Commander/Commander 2016/Open Hostility (BRGW).dck @@ -22,7 +22,9 @@ 1 [C16:215] Necrogenesis 1 [C16:336] Windbrisk Heights 1 [C16:56] Ash Barrens -3 [C16:337] Plains +1 [C16:337] Plains +1 [C16:338] Plains +1 [C16:339] Plains 1 [C16:160] Quirion Explorer 1 [C16:161] Rampant Growth 1 [C16:240] Order // Chaos @@ -69,12 +71,16 @@ 1 [C16:185] Boros Charm 1 [C16:142] Beastmaster Ascension 1 [C16:187] Clan Defiance -3 [C16:343] Swamp +1 [C16:343] Swamp +1 [C16:344] Swamp +1 [C16:345] Swamp 1 [C16:300] Gruul Turf 1 [C16:48] Tymna the Weaver 1 [C16:147] Den Protector 1 [C16:47] Treacherous Terrain -5 [C16:346] Mountain +2 [C16:346] Mountain +1 [C16:347] Mountain +2 [C16:348] Mountain 1 [C16:225] Terminate 1 [C16:45] Tana, the Bloodsower 1 [C16:149] Farseek @@ -82,7 +88,9 @@ 1 [C16:304] Jungle Shrine 1 [C16:44] Sylvan Reclamation 1 [C16:305] Karplusan Forest -5 [C16:349] Forest +2 [C16:349] Forest +1 [C16:350] Forest +2 [C16:351] Forest 1 [C16:108] Brutal Hordechief 1 [C16:307] Mosswort Bridge SB: 1 [C16:41] Saskia the Unyielding diff --git a/Mage.Client/release/sample-decks/Commander/Commander 2016/Stalwart Unity (RGWU) .dck b/Mage.Client/release/sample-decks/Commander/Commander 2016/Stalwart Unity (RGWU) .dck index 8ace597f7e1..819d5e9de2a 100644 --- a/Mage.Client/release/sample-decks/Commander/Commander 2016/Stalwart Unity (RGWU) .dck +++ b/Mage.Client/release/sample-decks/Commander/Commander 2016/Stalwart Unity (RGWU) .dck @@ -18,7 +18,9 @@ 1 [C16:259] Keening Stone 1 [C16:55] Prismatic Geoscope 1 [C16:216] Progenitor Mimic -5 [C16:337] Plains +2 [C16:337] Plains +2 [C16:338] Plains +1 [C16:339] Plains 1 [C16:219] Rubblehulk 1 [C16:4] Selfless Squire 1 [C16:3] Orzhov Advokist @@ -66,7 +68,9 @@ 1 [C16:83] Arcane Denial 1 [C16:141] Beast Within 1 [C16:80] Windborn Muse -5 [C16:340] Island +2 [C16:340] Island +1 [C16:341] Island +2 [C16:342] Island 1 [C16:220] Selvala, Explorer Returned 1 [C16:145] Collective Voyage 1 [C16:146] Cultivate @@ -75,10 +79,14 @@ 1 [C16:301] Homeward Path 1 [C16:47] Treacherous Terrain 1 [C16:302] Izzet Boilerworks -5 [C16:346] Mountain +1 [C16:346] Mountain +2 [C16:347] Mountain +2 [C16:348] Mountain 1 [C16:304] Jungle Shrine 1 [C16:44] Sylvan Reclamation -5 [C16:349] Forest +1 [C16:349] Forest +2 [C16:350] Forest +2 [C16:351] Forest 1 [C16:306] Krosan Verge 1 [C16:309] Myriad Landscape SB: 1 [C16:36] Kynaios and Tiro of Meletis diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.form b/Mage.Client/src/main/java/mage/client/MageFrame.form index f0741e20828..de5ca825483 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.form +++ b/Mage.Client/src/main/java/mage/client/MageFrame.form @@ -26,8 +26,8 @@ - - + + @@ -78,9 +78,12 @@ + + + - + @@ -91,35 +94,36 @@ - + + + + - + - - - + - - + + - + - - - + + + - + @@ -130,9 +134,12 @@ - + + + + - + @@ -143,9 +150,12 @@ + + + - + @@ -154,11 +164,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -167,30 +214,15 @@ - - - - - - - - - - - + + + + - - - - - - - - - - + + diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 5b91c2b29b8..c6eec4f6d83 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -63,7 +63,6 @@ import java.util.concurrent.TimeUnit; import java.util.prefs.Preferences; import javax.imageio.ImageIO; import javax.swing.AbstractButton; -import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JButton; @@ -79,7 +78,6 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JToggleButton; -import javax.swing.JToolBar.Separator; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; @@ -357,41 +355,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { balloonTip.setPositioner(new LeftAbovePositioner(0, 0)); balloonTip.setVisible(false); - mageToolbar.add(new javax.swing.JToolBar.Separator()); - mageToolbar.add(createWindowsButton()); - - //TODO: move to plugin impl - if (Plugins.getInstance().isCardPluginLoaded()) { - Separator separator = new javax.swing.JToolBar.Separator(); - mageToolbar.add(separator); - - JButton btnDownloadSymbols = new JButton("Symbols"); - btnDownloadSymbols.setFocusable(false); - btnDownloadSymbols.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnDownloadSymbols.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnDownloadSymbols.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnSymbolsActionPerformed(evt); - } - }); - mageToolbar.add(btnDownloadSymbols); - - separator = new javax.swing.JToolBar.Separator(); - mageToolbar.add(separator); - - JButton btnDownload = new JButton("Images"); - btnDownload.setFocusable(false); - btnDownload.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnDownload.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnDownload.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnImagesActionPerformed(evt); - } - }); - mageToolbar.add(btnDownload); - } + mageToolbar.add(createSwitchPanelsButton(), 0); + mageToolbar.add(new javax.swing.JToolBar.Separator(), 1); if (Plugins.getInstance().isCounterPluginLoaded()) { int i = Plugins.getInstance().getGamesPlayed(); @@ -402,8 +367,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { label.setBounds(0, 0, 180, 30); } - UI.addButton(MageComponents.TABLES_MENU_BUTTON, btnGames); - setGUISize(); SwingUtilities.invokeLater(new Runnable() { @@ -567,22 +530,22 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { setIconImage(image); } - private AbstractButton createWindowsButton() { - final JToggleButton windowButton = new JToggleButton("Windows"); - windowButton.addItemListener(new ItemListener() { + private AbstractButton createSwitchPanelsButton() { + final JToggleButton switchPanelsButton = new JToggleButton("Switch panels"); + switchPanelsButton.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { - createAndShowMenu((JComponent) e.getSource(), windowButton); + createAndShowSwitchPanelsMenu((JComponent) e.getSource(), switchPanelsButton); } } }); - windowButton.setFocusable(false); - windowButton.setHorizontalTextPosition(SwingConstants.LEADING); - return windowButton; + switchPanelsButton.setFocusable(false); + switchPanelsButton.setHorizontalTextPosition(SwingConstants.LEADING); + return switchPanelsButton; } - private void createAndShowMenu(final JComponent component, final AbstractButton windowButton) { + private void createAndShowSwitchPanelsMenu(final JComponent component, final AbstractButton windowButton) { JPopupMenu menu = new JPopupMenu(); JInternalFrame[] windows = desktopPane.getAllFramesInLayer(javax.swing.JLayeredPane.DEFAULT_LAYER); MagePaneMenuItem menuItem; @@ -641,18 +604,16 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } } - public void btnImagesActionPerformed(java.awt.event.ActionEvent evt) { - List cards = CardRepository.instance.findCards(new CardCriteria()); - DownloadPictures.startDownload(null, cards); - } - - public void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) { - UserRequestMessage message = new UserRequestMessage("Download additional resources", "Do you want to download game symbols and additional image files?"); - message.setButton1("No", null); - message.setButton2("Yes", PlayerAction.CLIENT_DOWNLOAD_SYMBOLS); - showUserRequestDialog(message); - } - +// public void btnImagesActionPerformed(java.awt.event.ActionEvent evt) { +// List cards = CardRepository.instance.findCards(new CardCriteria()); +// DownloadPictures.startDownload(null, cards); +// } +// public void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) { +// UserRequestMessage message = new UserRequestMessage("Download additional resources", "Do you want to download game symbols and additional image files?"); +// message.setButton1("No", null); +// message.setButton2("Yes", PlayerAction.CLIENT_DOWNLOAD_SYMBOLS); +// showUserRequestDialog(message); +// } public static void setActive(MagePane frame) { if (frame == null) { activeFrame = null; @@ -888,8 +849,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { btnPreferences = new javax.swing.JButton(); jSeparator4 = new javax.swing.JToolBar.Separator(); btnConnect = new javax.swing.JButton(); - jSeparator3 = new javax.swing.JToolBar.Separator(); - btnGames = new javax.swing.JButton(); + lblStatus = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JToolBar.Separator(); btnDeckEditor = new javax.swing.JButton(); jSeparator2 = new javax.swing.JToolBar.Separator(); @@ -897,12 +857,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { jSeparator5 = new javax.swing.JToolBar.Separator(); btnSendFeedback = new javax.swing.JButton(); jSeparator6 = new javax.swing.JToolBar.Separator(); + btnSymbols = new javax.swing.JButton(); + jSeparatorSymbols = new javax.swing.JToolBar.Separator(); + btnImages = new javax.swing.JButton(); + jSeparatorImages = new javax.swing.JToolBar.Separator(); btnAbout = new javax.swing.JButton(); jSeparator7 = new javax.swing.JToolBar.Separator(); - btnExit = new javax.swing.JButton(); jMemUsageLabel = new javax.swing.JLabel(); - jSeparator8 = new javax.swing.JToolBar.Separator(); - lblStatus = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); setMinimumSize(new java.awt.Dimension(1024, 768)); @@ -916,9 +877,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.setMinimumSize(new java.awt.Dimension(566, 60)); mageToolbar.setPreferredSize(new java.awt.Dimension(614, 60)); + btnPreferences.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/preferences.png"))); // NOI18N btnPreferences.setText("Preferences"); btnPreferences.setFocusable(false); - btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnPreferences.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -928,9 +890,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.add(btnPreferences); mageToolbar.add(jSeparator4); - btnConnect.setText("Connect"); + btnConnect.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/connect.png"))); // NOI18N + btnConnect.setToolTipText("Connect to or disconnect from a XMage server."); btnConnect.setFocusable(false); - btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnConnect.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -938,23 +901,18 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } }); mageToolbar.add(btnConnect); - mageToolbar.add(jSeparator3); - btnGames.setText("Games"); - btnGames.setFocusable(false); - btnGames.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnGames.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnGames.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnGamesActionPerformed(evt); - } - }); - mageToolbar.add(btnGames); + lblStatus.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + lblStatus.setText("Not connected"); + lblStatus.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + lblStatus.setInheritsPopupMenu(false); + mageToolbar.add(lblStatus); mageToolbar.add(jSeparator1); + btnDeckEditor.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/deck_editor.png"))); // NOI18N btnDeckEditor.setText("Deck Editor"); btnDeckEditor.setFocusable(false); - btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnDeckEditor.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -964,9 +922,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.add(btnDeckEditor); mageToolbar.add(jSeparator2); - btnCollectionViewer.setText("Collection Viewer"); + btnCollectionViewer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/collection.png"))); // NOI18N + btnCollectionViewer.setText("Viewer"); btnCollectionViewer.setFocusable(false); - btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -976,9 +935,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.add(btnCollectionViewer); mageToolbar.add(jSeparator5); + btnSendFeedback.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/feedback.png"))); // NOI18N btnSendFeedback.setText("Feedback"); btnSendFeedback.setFocusable(false); - btnSendFeedback.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnSendFeedback.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnSendFeedback.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnSendFeedback.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -988,9 +948,38 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.add(btnSendFeedback); mageToolbar.add(jSeparator6); + btnSymbols.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/symbol.png"))); // NOI18N + btnSymbols.setText("Symbols"); + btnSymbols.setToolTipText("Load symbols from the internet.
\nYou need to do that only once."); + btnSymbols.setFocusable(false); + btnSymbols.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + btnSymbols.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnSymbols.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSymbolsActionPerformed(evt); + } + }); + mageToolbar.add(btnSymbols); + mageToolbar.add(jSeparatorSymbols); + + btnImages.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/images.png"))); // NOI18N + btnImages.setText("Images"); + btnImages.setToolTipText("Load card images from external sources."); + btnImages.setFocusable(false); + btnImages.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); + btnImages.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnImages.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnImagesActionPerformed(evt); + } + }); + mageToolbar.add(btnImages); + mageToolbar.add(jSeparatorImages); + + btnAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/about.png"))); // NOI18N btnAbout.setText("About"); btnAbout.setFocusable(false); - btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); btnAbout.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -1000,31 +989,19 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { mageToolbar.add(btnAbout); mageToolbar.add(jSeparator7); - btnExit.setText("Exit"); - btnExit.setFocusable(false); - btnExit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnExit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnExit.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnExitActionPerformed(evt); - } - }); - mageToolbar.add(btnExit); - + jMemUsageLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + jMemUsageLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu/memory.png"))); // NOI18N jMemUsageLabel.setText("100% Free mem"); - mageToolbar.add(Box.createHorizontalGlue()); + jMemUsageLabel.setFocusable(false); + jMemUsageLabel.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT); mageToolbar.add(jMemUsageLabel); - mageToolbar.add(jSeparator8); - - lblStatus.setText("Not connected "); - mageToolbar.add(lblStatus); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(desktopPane) - .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 697, Short.MAX_VALUE) + .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 769, Short.MAX_VALUE) + .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -1041,14 +1018,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { showDeckEditor(DeckEditorMode.FREE_BUILDING, null, null, 0); }//GEN-LAST:event_btnDeckEditorActionPerformed - private void btnGamesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGamesActionPerformed - this.showGames(true); - }//GEN-LAST:event_btnGamesActionPerformed - - private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed - exitApp(); - }//GEN-LAST:event_btnExitActionPerformed - private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed if (SessionHandler.isConnected()) { UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "Are you sure you want to disconnect?"); @@ -1090,6 +1059,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { FeedbackDialog.main(new String[]{}); }//GEN-LAST:event_btnSendFeedbackActionPerformed + private void btnSymbolsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSymbolsActionPerformed + downloadAdditionalResources(); + }//GEN-LAST:event_btnSymbolsActionPerformed + + public void downloadAdditionalResources() { + UserRequestMessage message = new UserRequestMessage("Download additional resources", "Do you want to download game symbols and additional image files?"); + message.setButton1("No", null); + message.setButton2("Yes", PlayerAction.CLIENT_DOWNLOAD_SYMBOLS); + showUserRequestDialog(message); + } + + private void btnImagesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnImagesActionPerformed + downloadImages(); + }//GEN-LAST:event_btnImagesActionPerformed + + public void downloadImages() { + List cards = CardRepository.instance.findCards(new CardCriteria()); + DownloadPictures.startDownload(null, cards); + } + public void exitApp() { if (SessionHandler.isConnected()) { UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "You are currently connected. Are you sure you want to disconnect?"); @@ -1106,15 +1095,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { public void enableButtons() { btnConnect.setEnabled(true); - btnConnect.setText("Disconnect"); - btnGames.setEnabled(true); btnDeckEditor.setEnabled(true); } public void disableButtons() { btnConnect.setEnabled(true); - btnConnect.setText("Connect"); - btnGames.setEnabled(false); btnDeckEditor.setEnabled(true); } @@ -1131,9 +1116,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { if (setActive) { setActive(tablesPane); } else // if other panel was already shown, mamke sure it's topmost again - if (topPanebefore != null) { - setActive(topPanebefore); - } + if (topPanebefore != null) { + setActive(topPanebefore); + } } public void hideGames() { @@ -1305,20 +1290,20 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private javax.swing.JButton btnCollectionViewer; private javax.swing.JButton btnConnect; private javax.swing.JButton btnDeckEditor; - private javax.swing.JButton btnExit; - private javax.swing.JButton btnGames; + private javax.swing.JButton btnImages; private javax.swing.JButton btnPreferences; private javax.swing.JButton btnSendFeedback; + private javax.swing.JButton btnSymbols; private static javax.swing.JDesktopPane desktopPane; private javax.swing.JLabel jMemUsageLabel; private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar.Separator jSeparator2; - private javax.swing.JToolBar.Separator jSeparator3; private javax.swing.JToolBar.Separator jSeparator4; private javax.swing.JToolBar.Separator jSeparator5; private javax.swing.JToolBar.Separator jSeparator6; private javax.swing.JToolBar.Separator jSeparator7; - private javax.swing.JToolBar.Separator jSeparator8; + private javax.swing.JToolBar.Separator jSeparatorImages; + private javax.swing.JToolBar.Separator jSeparatorSymbols; private javax.swing.JLabel lblStatus; private javax.swing.JToolBar mageToolbar; // End of variables declaration//GEN-END:variables @@ -1330,7 +1315,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { public void setStatusText(String status) { this.lblStatus.setText(status); - changeGUISize(); // Needed to layout the tooltbar after text length chnage + changeGUISize(); // Needed to layout the tooltbar after text length change + this.lblStatus.repaint(); + this.lblStatus.revalidate(); } public static MageUI getUI() { 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 85079256e2b..f016f0edd24 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,12 +1,11 @@ package mage.client.components.tray; -import mage.client.MageFrame; -import org.apache.log4j.Logger; -import org.mage.plugins.card.utils.impl.ImageManagerImpl; - import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import mage.client.MageFrame; +import org.apache.log4j.Logger; +import org.mage.plugins.card.utils.impl.ImageManagerImpl; /** * @author noxx @@ -63,14 +62,14 @@ public class MageTray { imagesItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - MageFrame.getInstance().btnImagesActionPerformed(null); + MageFrame.getInstance().downloadImages(); } }); iconsItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - MageFrame.getInstance().btnSymbolsActionPerformed(null); + MageFrame.getInstance().downloadAdditionalResources(); } }); 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 9e366c2ceaf..646369c1668 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -602,7 +602,7 @@ public class TablesPanel extends javax.swing.JPanel { formatFilterList.add(RowFilter.regexFilter("^Limited", TableTableModel.COLUMN_DECK_TYPE)); } if (btnFormatOther.isSelected()) { - formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform", TableTableModel.COLUMN_DECK_TYPE)); + formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander", TableTableModel.COLUMN_DECK_TYPE)); } List> skillFilterList = new ArrayList<>(); diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java index fdd49bb6b41..05bc713a8b4 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanelRenderImpl.java @@ -63,6 +63,9 @@ public class CardPanelRenderImpl extends CardPanel { if (!a.getRules().equals(b.getRules())) { return false; } + if (a.getRarity() == null || b.getRarity() == null) { + return false; + } if (!a.getRarity().equals(b.getRarity())) { return false; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/beans/EventListenerList.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/beans/EventListenerList.java index e17eee6e69d..aaf87ff37f6 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/beans/EventListenerList.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/beans/EventListenerList.java @@ -1,39 +1,37 @@ /** * EventListenerList.java - * + * * Created on 08.04.2010 */ - package org.mage.plugins.card.dl.beans; - -import static java.util.Arrays.*; - -import java.util.ArrayList; -import java.util.EventListener; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - import com.google.common.base.Function; import com.google.common.collect.AbstractIterator; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - +import java.util.ArrayList; +import static java.util.Arrays.*; +import java.util.EventListener; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; /** * The class EventListenerList. - * + * * @version V0.0 08.04.2010 * @author Clemens Koza */ public class EventListenerList extends javax.swing.event.EventListenerList { + private static final long serialVersionUID = -7545754245081842909L; /** - * Returns an iterable over all listeners for the specified classes. the listener classes are in the specified - * order. for every class, listeners are in the reverse order of registering. A listener contained multiple - * times (for a single or multiple classes) is only returned the first time it occurs. + * Returns an iterable over all listeners for the specified classes. the + * listener classes are in the specified order. for every class, listeners + * are in the reverse order of registering. A listener contained multiple + * times (for a single or multiple classes) is only returned the first time + * it occurs. */ public Iterable getIterable(final Class... listenerClass) { //transform class -> iterable @@ -51,22 +49,30 @@ public class EventListenerList extends javax.swing.event.EventListenerList { } /** - * Returns an iterator over all listeners for the specified classes. the listener classes are in the specified - * order. for every class, listeners are in the reverse order of registering. A listener contained multiple - * times (for a single or multiple classes) is only returned the first time it occurs. + * Returns an iterator over all listeners for the specified classes. the + * listener classes are in the specified order. for every class, listeners + * are in the reverse order of registering. A listener contained multiple + * times (for a single or multiple classes) is only returned the first time + * it occurs. + * + * @param + * @param listenerClass + * @return */ public Iterator getIterator(Class... listenerClass) { return getIterable(listenerClass).iterator(); } /** - * Iterates backwards over the listeners registered for a class by using the original array. The Listener runs - * backwards, just as listener notification usually works. + * Iterates backwards over the listeners registered for a class by using the + * original array. The Listener runs backwards, just as listener + * notification usually works. */ private class ListenerIterator extends AbstractIterator { + private final Class listenerClass; - private Object[] listeners = listenerList; - private int index = listeners.length; + private Object[] listeners = listenerList; + private int index = listeners.length; private ListenerIterator(Class listenerClass) { this.listenerClass = listenerClass; @@ -75,8 +81,10 @@ public class EventListenerList extends javax.swing.event.EventListenerList { @Override @SuppressWarnings("unchecked") protected T computeNext() { - for(index -= 2; index >= 0; index -= 2) { - if(listenerClass == listeners[index]) return (T) listeners[index + 1]; + for (index -= 2; index >= 0; index -= 2) { + if (listenerClass == listeners[index]) { + return (T) listeners[index + 1]; + } } return endOfData(); } @@ -98,22 +106,25 @@ public class EventListenerList extends javax.swing.event.EventListenerList { } /** - * Filters the delegate iterator so that every but the first occurrence of every element is ignored. + * Filters the delegate iterator so that every but the first occurrence of + * every element is ignored. */ private static class SingletonIterator extends AbstractIterator { + private Iterator it; - private HashSet previous = new HashSet(); + private HashSet previous = new HashSet(); public SingletonIterator(Iterator it) { this.it = it; } - @Override protected T computeNext() { - while(it.hasNext()) { + while (it.hasNext()) { T next = it.next(); - if(previous.add(next)) return next; + if (previous.add(next)) { + return next; + } } return endOfData(); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 3784205acd3..34a2ede8113 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -42,7 +42,7 @@ public class CardImageUtils { return filePath; } } - log.warn("Token image file not found: " + card.getTokenSetCode() + " - " + card.getName()); + log.warn("Token image file not found: " + card.getSet() + " - " + card.getTokenSetCode() + " - " + card.getName()); return null; } @@ -117,7 +117,7 @@ public class CardImageUtils { return buildPath(imagesDir, set); } } - + public static String getImageBasePath() { String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); String imagesPath = useDefault.equals("true") ? Constants.IO.imageBaseDir : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); @@ -126,7 +126,7 @@ public class CardImageUtils { } return imagesPath; } - + public static String getTokenBasePath() { String imagesPath = getImageBasePath(); diff --git a/Mage.Client/src/main/resources/menu/about.png b/Mage.Client/src/main/resources/menu/about.png new file mode 100644 index 00000000000..f05319ae177 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/about.png differ diff --git a/Mage.Client/src/main/resources/menu/collection.png b/Mage.Client/src/main/resources/menu/collection.png new file mode 100644 index 00000000000..e6d3b4a6d36 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/collection.png differ diff --git a/Mage.Client/src/main/resources/menu/connect.png b/Mage.Client/src/main/resources/menu/connect.png new file mode 100644 index 00000000000..830f2a0e5c6 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/connect.png differ diff --git a/Mage.Client/src/main/resources/menu/deck_editor.png b/Mage.Client/src/main/resources/menu/deck_editor.png new file mode 100644 index 00000000000..b45da8919ec Binary files /dev/null and b/Mage.Client/src/main/resources/menu/deck_editor.png differ diff --git a/Mage.Client/src/main/resources/menu/feedback.png b/Mage.Client/src/main/resources/menu/feedback.png new file mode 100644 index 00000000000..449bb13db21 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/feedback.png differ diff --git a/Mage.Client/src/main/resources/menu/images.png b/Mage.Client/src/main/resources/menu/images.png new file mode 100644 index 00000000000..91b5df72437 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/images.png differ diff --git a/Mage.Client/src/main/resources/menu/memory.png b/Mage.Client/src/main/resources/menu/memory.png new file mode 100644 index 00000000000..0088a2e46de Binary files /dev/null and b/Mage.Client/src/main/resources/menu/memory.png differ diff --git a/Mage.Client/src/main/resources/menu/preferences.png b/Mage.Client/src/main/resources/menu/preferences.png new file mode 100644 index 00000000000..67de2c6ccbe Binary files /dev/null and b/Mage.Client/src/main/resources/menu/preferences.png differ diff --git a/Mage.Client/src/main/resources/menu/symbol.png b/Mage.Client/src/main/resources/menu/symbol.png new file mode 100644 index 00000000000..f54bbf4d2f6 Binary files /dev/null and b/Mage.Client/src/main/resources/menu/symbol.png differ diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 190c68bf016..5413d844ac5 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -45,6 +45,7 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.Counter; import mage.counters.CounterType; +import mage.designations.Designation; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; @@ -138,8 +139,7 @@ public class CardView extends SimpleCardView { this(card, game, false); this.id = cardId; } - - + public CardView(CardView cardView) { super(cardView.id, cardView.expansionSetCode, cardView.cardNumber, cardView.usesVariousArt, cardView.tokenSetCode, cardView.gameObject, cardView.tokenDescriptor); @@ -488,6 +488,20 @@ public class CardView extends SimpleCardView { this.rarity = Rarity.COMMON; } + public CardView(Designation designation, StackAbility stackAbility) { + this(true); + this.gameObject = true; + this.id = designation.getId(); + this.mageObjectType = MageObjectType.NULL; + this.name = designation.getName(); + this.displayName = name; + this.rules = new ArrayList<>(); + this.rules.add(stackAbility.getRule(designation.getName())); + this.frameStyle = FrameStyle.M15_NORMAL; + this.expansionSetCode = designation.getExpansionSetCodeForImage(); + this.rarity = Rarity.COMMON; + } + public CardView(boolean empty) { super(null, "", "0", false, "", ""); if (!empty) { diff --git a/Mage.Common/src/mage/view/GameView.java b/Mage.Common/src/mage/view/GameView.java index 775fd2e099c..bc12e6cb692 100644 --- a/Mage.Common/src/mage/view/GameView.java +++ b/Mage.Common/src/mage/view/GameView.java @@ -40,6 +40,7 @@ import mage.constants.CardType; import mage.constants.PhaseStep; import mage.constants.TurnPhase; import mage.constants.Zone; +import mage.designations.Designation; import mage.game.ExileZone; import mage.game.Game; import mage.game.GameState; @@ -143,6 +144,14 @@ public class GameView implements Serializable { stack.put(stackObject.getId(), new StackAbilityView(game, (StackAbility) stackObject, object.getName(), cardView)); checkPaid(stackObject.getId(), ((StackAbility) stackObject)); + } else if (object instanceof Designation) { + Designation designation = (Designation) game.getObject(object.getId()); + if (designation != null) { + stack.put(stackObject.getId(), new CardView(designation, (StackAbility) stackObject)); + } else { + LOGGER.fatal("Designation object not found: " + object.getName() + " " + object.toString() + " " + object.getClass().toString()); + } + } else if (object instanceof StackAbility) { StackAbility stackAbility = ((StackAbility) object); stackAbility.newId(); 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 261aafb75bb..1d35210ae5e 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 @@ -32,7 +32,9 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import mage.abilities.Ability; import mage.abilities.common.CanBeYourCommanderAbility; +import mage.abilities.costs.mana.ManaCost; import mage.abilities.keyword.PartnerAbility; import mage.cards.Card; import mage.cards.ExpansionSet; @@ -211,15 +213,22 @@ public class Commander extends Constructed { } int edhPowerLevel = 0; + int numberInfinitePieces = 0; + for (Card card : deck.getCards()) { int thisMaxPower = 0; // Examine rules to work out most egregious functions in edh boolean anyNumberOfTarget = false; + boolean annihilator = false; boolean buyback = false; boolean cascade = false; + boolean cantBe = false; boolean copy = false; + boolean costLessEach = false; + boolean createToken = false; + boolean dredge = false; boolean exile = false; boolean exileAll = false; boolean counter = false; @@ -227,56 +236,110 @@ public class Commander extends Constructed { boolean destroyAll = false; boolean each = false; boolean exalted = false; + boolean doesntUntap = false; boolean drawCards = false; + boolean evoke = false; boolean extraTurns = false; + boolean flicker = false; boolean gainControl = false; + boolean hexproof = false; boolean infect = false; boolean mayCastForFree = false; + boolean menace = false; boolean miracle = false; boolean overload = false; boolean persist = false; + boolean preventDamage = false; boolean proliferate = false; + boolean protection = false; + boolean putUnderYourControl = false; boolean retrace = false; + boolean returnFromYourGY = false; boolean sacrifice = false; + boolean shroud = false; boolean skip = false; boolean sliver = false; + boolean storm = false; + boolean trample = false; boolean tutor = false; + boolean tutorBasic = false; + boolean twiceAs = false; + boolean unblockable = false; boolean undying = false; + boolean untapTarget = false; boolean wheneverEnters = false; + boolean whenCounterThatSpell = false; + boolean xCost = false; boolean youControlTarget = false; for (String str : card.getRules()) { String s = str.toLowerCase(); + annihilator |= s.contains("annihilator"); anyNumberOfTarget |= s.contains("any number"); buyback |= s.contains("buyback"); + cantBe |= s.contains("can't be"); cascade |= s.contains("cascade"); copy |= s.contains("copy"); + costLessEach |= s.contains("cost") || s.contains("less") || s.contains("each"); counter |= s.contains("counter") && s.contains("target"); + createToken |= s.contains("create") && s.contains("token"); destroy |= s.contains("destroy"); destroyAll |= s.contains("destroy all"); + doesntUntap |= s.contains("doesn't untap"); + doesntUntap |= s.contains("don't untap"); drawCards |= s.contains("draw cards"); + dredge |= s.contains("dredge"); each |= s.contains("each"); + evoke |= s.contains("evoke"); exalted |= s.contains("exalted"); exile |= s.contains("exile"); exileAll |= s.contains("exile") && s.contains(" all "); extraTurns |= s.contains("extra turn"); + flicker |= s.contains("exile") && s.contains("return") && s.contains("to the battlefield under"); gainControl |= s.contains("gain control"); + hexproof |= s.contains("hexproof"); infect |= s.contains("infect"); mayCastForFree |= s.contains("may cast") && s.contains("without paying"); + menace |= s.contains("menace"); miracle |= s.contains("miracle"); overload |= s.contains("overload"); persist |= s.contains("persist"); - proliferate |= s.contains("proliferate"); + preventDamage |= s.contains("prevent") && s.contains("all") && s.contains("damage"); + proliferate |= s.contains("proliferate"); + protection |= s.contains("protection"); + putUnderYourControl |= s.contains("put") && s.contains("under your control"); retrace |= s.contains("retrace"); + returnFromYourGY |= s.contains("return") && s.contains("from your graveyard"); sacrifice |= s.contains("sacrifice"); - skip |= s.contains("skip") && s.contains("each"); + shroud |= s.contains("shroud"); + skip |= s.contains("skip"); sliver |= s.contains("sliver"); - tutor |= s.contains("search your library"); + storm |= s.contains("storm"); + trample |= s.contains("trample"); + tutor |= s.contains("search your library") && !s.contains("basic land"); + tutorBasic |= s.contains("search your library") && s.contains("basic land"); + twiceAs |= s.contains("twice that many") || s.contains("twice as much"); + unblockable |= s.contains("can't be blocked"); undying |= s.contains("undying"); + untapTarget |= s.contains("untap target"); + whenCounterThatSpell |= s.contains("when") && s.contains("counter that spell"); wheneverEnters |= s.contains("when") && s.contains("another") && s.contains("enters"); youControlTarget |= s.contains("you control target"); } + for (ManaCost cost : card.getManaCost()) { + if (cost.getText().contains("X")) { + xCost = true; + } + } + for (Ability a : card.getAbilities()) { + for (ManaCost cost : a.getManaCosts()) { + if (cost.getText().contains("X")) { + xCost = true; + } + } + } + if (extraTurns) { thisMaxPower = Math.max(thisMaxPower, 7); } @@ -286,54 +349,114 @@ public class Commander extends Constructed { if (tutor) { thisMaxPower = Math.max(thisMaxPower, 6); } + if (annihilator) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (costLessEach) { + thisMaxPower = Math.max(thisMaxPower, 5); + } if (infect) { thisMaxPower = Math.max(thisMaxPower, 5); } if (overload) { thisMaxPower = Math.max(thisMaxPower, 5); } + if (twiceAs) { + thisMaxPower = Math.max(thisMaxPower, 5); + } if (cascade) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (doesntUntap) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (each) { thisMaxPower = Math.max(thisMaxPower, 4); } if (exileAll) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (flicker) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (gainControl) { thisMaxPower = Math.max(thisMaxPower, 4); } if (mayCastForFree) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (preventDamage) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (proliferate) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (protection) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (putUnderYourControl) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (returnFromYourGY) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (skip) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (storm) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (unblockable) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (whenCounterThatSpell) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (wheneverEnters) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (xCost) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (youControlTarget) { thisMaxPower = Math.max(thisMaxPower, 4); } if (anyNumberOfTarget) { thisMaxPower = Math.max(thisMaxPower, 3); } + if (createToken) { + thisMaxPower = Math.max(thisMaxPower, 3); + } if (destroyAll) { thisMaxPower = Math.max(thisMaxPower, 3); } + if (dredge) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (hexproof) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (shroud) { + thisMaxPower = Math.max(thisMaxPower, 3); + } if (undying) { thisMaxPower = Math.max(thisMaxPower, 3); } if (persist) { thisMaxPower = Math.max(thisMaxPower, 3); } + if (cantBe) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (evoke) { + thisMaxPower = Math.max(thisMaxPower, 2); + } if (exile) { thisMaxPower = Math.max(thisMaxPower, 2); } + if (menace) { + thisMaxPower = Math.max(thisMaxPower, 2); + } if (miracle) { thisMaxPower = Math.max(thisMaxPower, 2); } @@ -343,6 +466,9 @@ public class Commander extends Constructed { if (sacrifice) { thisMaxPower = Math.max(thisMaxPower, 2); } + if (untapTarget) { + thisMaxPower = Math.max(thisMaxPower, 2); + } if (copy) { thisMaxPower = Math.max(thisMaxPower, 1); } @@ -361,13 +487,22 @@ public class Commander extends Constructed { if (retrace) { thisMaxPower = Math.max(thisMaxPower, 1); } + if (trample) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (tutorBasic) { + thisMaxPower = Math.max(thisMaxPower, 1); + } // Planeswalkers if (card.getCardType().contains(CardType.PLANESWALKER)) { if (card.getName().toLowerCase().equals("jace, the mind sculptor")) { + thisMaxPower = Math.max(thisMaxPower, 6); + } + if (card.getName().toLowerCase().equals("ugin, the spirit dragon")) { thisMaxPower = Math.max(thisMaxPower, 5); } - thisMaxPower = Math.max(thisMaxPower, 3); + thisMaxPower = Math.max(thisMaxPower, 4); } if (card.getCardType().contains(CardType.LAND)) { @@ -401,6 +536,7 @@ public class Commander extends Constructed { || cn.equals("edric, spymaster of trest") || cn.equals("elesh norn, grand cenobite") || cn.equals("entomb") + || cn.equals("force of will") || cn.equals("food chain") || cn.equals("gaddock teeg") || cn.equals("gaea's cradle") @@ -446,7 +582,6 @@ public class Commander extends Constructed { || cn.equals("strip mine") || cn.equals("the tabernacle at pendrell vale") || cn.equals("tinker") - || cn.equals("tolarian academy") || cn.equals("treasure cruise") || cn.equals("urabrask the hidden") || cn.equals("vorinclex, voice of hunger") @@ -456,17 +591,20 @@ public class Commander extends Constructed { } // Parts of infinite combos - if (cn.equals("animate artifact") || cn.equals("archaeomancer") + if (cn.equals("animate artifact") || cn.equals("animar, soul of element") + || cn.equals("archaeomancer") || cn.equals("ashnod's altar") || cn.equals("azami, lady of scrolls") || cn.equals("basalt monolith") || cn.equals("brago, king eternal") || cn.equals("candelabra of tawnos") || cn.equals("cephalid aristocrat") || cn.equals("cephalid illusionist") || cn.equals("changeling berserker") + || cn.equals("the chain veil") || cn.equals("cinderhaze wretch") || cn.equals("cryptic gateway") || cn.equals("deadeye navigator") || cn.equals("derevi, empyrial tactician") || cn.equals("doubling season") || cn.equals("dross scorpion") || cn.equals("earthcraft") || cn.equals("erratic portal") || cn.equals("enter the infinite") || cn.equals("omniscience") || cn.equals("exquisite blood") || cn.equals("future sight") + || cn.equals("ghave, guru of spores") || cn.equals("grave titan") || cn.equals("great whale") || cn.equals("grim monolith") || cn.equals("gush") || cn.equals("hellkite charger") || cn.equals("intruder alarm") @@ -483,6 +621,7 @@ public class Commander extends Constructed { || cn.equals("myr turbine") || cn.equals("narset, enlightened master") || cn.equals("nekusar, the mindrazer") || cn.equals("norin the wary") || cn.equals("opalescence") || cn.equals("ornithopter") + || cn.equals("peregrine drake") || cn.equals("palinchron") || cn.equals("planar portal") || cn.equals("power artifact") || cn.equals("rings of brighthearth") || cn.equals("rite of replication") || cn.equals("sanguine bond") || cn.equals("sensei's divining top") @@ -497,7 +636,8 @@ public class Commander extends Constructed { || cn.equals("workhorse") || cn.equals("worldgorger dragon") || cn.equals("worthy cause") || cn.equals("yawgmoth's will") || cn.equals("zealous conscripts")) { - thisMaxPower = Math.max(thisMaxPower, 6); + thisMaxPower = Math.max(thisMaxPower, 7); + numberInfinitePieces++; } edhPowerLevel += thisMaxPower; } @@ -507,54 +647,56 @@ public class Commander extends Constructed { String cn = commander.getName().toLowerCase(); // Least fun commanders - if (cn.equals("azami, lady of scrolls") - || cn.equals("braids, cabal minion") - || cn.equals("child of alara") - || cn.equals("derevi, empyrial tactician") - || cn.equals("edric, spymaster of trest") - || cn.equals("gaddock teeg") - || cn.equals("grand arbiter augustin iv") - || cn.equals("hokori, dust drinker") - || cn.equals("iona, shield of emeria") - || cn.equals("jin-gitaxias, core augur") - || cn.equals("karador, ghost chieftain") - || cn.equals("leovold, emissary of trest") - || cn.equals("linvala, keeper of silence") - || cn.equals("llawan, cephalid empress") - || cn.equals("memnarch") - || cn.equals("meren of clan nel toth") - || cn.equals("michiko konda, truth seeker") - || cn.equals("narset, enlightened master") - || cn.equals("nekusar, the mindrazer") - || cn.equals("norin the wary") - || cn.equals("numot, the devastator") - || cn.equals("sheoldred, whispering one") - || cn.equals("teferi, mage of zhalfir") - || cn.equals("zur the enchanter")) { - thisMaxPower = Math.max(thisMaxPower, 15); + if (cn.equals("animar, soul of element") + || cn.equals("azami, lady of scrolls") + || cn.equals("braids, cabal minion") + || cn.equals("child of alara") + || cn.equals("derevi, empyrial tactician") + || cn.equals("edric, spymaster of trest") + || cn.equals("gaddock teeg") + || cn.equals("grand arbiter augustin iv") + || cn.equals("hokori, dust drinker") + || cn.equals("iona, shield of emeria") + || cn.equals("jin-gitaxias, core augur") + || cn.equals("karador, ghost chieftain") + || cn.equals("leovold, emissary of trest") + || cn.equals("linvala, keeper of silence") + || cn.equals("llawan, cephalid empress") + || cn.equals("memnarch") + || cn.equals("meren of clan nel toth") + || cn.equals("michiko konda, truth seeker") + || cn.equals("narset, enlightened master") + || cn.equals("nekusar, the mindrazer") + || cn.equals("norin the wary") + || cn.equals("numot, the devastator") + || cn.equals("sheoldred, whispering one") + || cn.equals("teferi, mage of zhalfir") + || cn.equals("zur the enchanter")) { + thisMaxPower = Math.max(thisMaxPower, 25); } // Next least fun commanders if (cn.equals("anafenza, the foremost") - || cn.equals("arcum dagsson") - || cn.equals("azusa, lost but seeking") - || cn.equals("brago, king eternal") - || cn.equals("captain sisay") - || cn.equals("elesh norn, grand cenobite") - || cn.equals("malfegor") - || cn.equals("maelstrom wanderer") - || cn.equals("mikaeus the unhallowed") - || cn.equals("nath of the gilt-leaf") - || cn.equals("purphoros, god of the forge") - || cn.equals("sen triplets") - || cn.equals("urabrask the hidden") - || cn.equals("vorinclex, voice of hunger")) { - thisMaxPower = Math.max(thisMaxPower, 10); + || cn.equals("arcum dagsson") + || cn.equals("azusa, lost but seeking") + || cn.equals("brago, king eternal") + || cn.equals("captain sisay") + || cn.equals("elesh norn, grand cenobite") + || cn.equals("malfegor") + || cn.equals("maelstrom wanderer") + || cn.equals("mikaeus the unhallowed") + || cn.equals("nath of the gilt-leaf") + || cn.equals("purphoros, god of the forge") + || cn.equals("sen triplets") + || cn.equals("urabrask the hidden") + || cn.equals("vorinclex, voice of hunger")) { + thisMaxPower = Math.max(thisMaxPower, 15); } edhPowerLevel += thisMaxPower; } - edhPowerLevel = (int) Math.round(edhPowerLevel / 2.5); + edhPowerLevel += numberInfinitePieces * 10; + edhPowerLevel = (int) Math.round(edhPowerLevel / 4.5); if (edhPowerLevel > 100) { edhPowerLevel = 100; } 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 f26b96a4b4c..f3a4fcae963 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 @@ -921,7 +921,10 @@ public class HumanPlayer extends PlayerImpl { FilterCreatureForCombat filter = filterCreatureForCombat.copy(); filter.add(new ControllerIdPredicate(attackingPlayerId)); while (!abort) { - + if (passedAllTurns || passedUntilEndStepBeforeMyTurn + || (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedTurnSkipStack || passedUntilEndOfTurn || passedUntilNextMain))) { + return; + } Map options = new HashMap<>(); List possibleAttackers = new ArrayList<>(); @@ -933,12 +936,6 @@ public class HumanPlayer extends PlayerImpl { options.put(Constants.Option.POSSIBLE_ATTACKERS, (Serializable) possibleAttackers); if (possibleAttackers.size() > 0) { options.put(Constants.Option.SPECIAL_BUTTON, (Serializable) "All attack"); - if (getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction()) { - resetPlayerPassedActions(); - } - } else if (passedAllTurns || passedUntilEndStepBeforeMyTurn - || (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedTurnSkipStack || passedUntilEndOfTurn || passedUntilNextMain))) { - return; } game.fireSelectEvent(playerId, "Select attackers", options); diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeNovember2016.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeNovember2016.java new file mode 100644 index 00000000000..4e18c21ff9c --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeNovember2016.java @@ -0,0 +1,583 @@ +/* + * 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.tournament.cubes; + +import mage.game.draft.DraftCube; + +/** + * + * @author fireshoes + */ +public class VintageCubeNovember2016 extends DraftCube { + + public VintageCubeNovember2016() { + super("MTGO Vintage Cube November 2016"); + + cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", "")); + cubeCards.add(new DraftCube.CardIdentity("Abrupt Decay", "")); + cubeCards.add(new DraftCube.CardIdentity("Academy Rector", "")); + cubeCards.add(new DraftCube.CardIdentity("Academy Ruins", "")); + cubeCards.add(new DraftCube.CardIdentity("Acidic Slime", "")); + cubeCards.add(new DraftCube.CardIdentity("Ajani Vengeant", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancestral Recall", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancestral Vision", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancient Grudge", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancient Tomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Angel of Serenity", "")); + cubeCards.add(new DraftCube.CardIdentity("Anguished Unmaking", "")); + cubeCards.add(new DraftCube.CardIdentity("Animate Dead", "")); + cubeCards.add(new DraftCube.CardIdentity("Anticipate", "")); + cubeCards.add(new DraftCube.CardIdentity("Arbor Elf", "")); + cubeCards.add(new DraftCube.CardIdentity("Archangel of Thune", "")); + cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", "")); + cubeCards.add(new DraftCube.CardIdentity("Armageddon", "")); + cubeCards.add(new DraftCube.CardIdentity("Ashiok, Nightmare Weaver", "")); + cubeCards.add(new DraftCube.CardIdentity("Avacyn's Pilgrim", "")); + cubeCards.add(new DraftCube.CardIdentity("Avalanche Riders", "")); + cubeCards.add(new DraftCube.CardIdentity("Avenger of Zendikar", "")); + cubeCards.add(new DraftCube.CardIdentity("Awakening Zone", "")); + cubeCards.add(new DraftCube.CardIdentity("Azorius Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Badlands", "")); + cubeCards.add(new DraftCube.CardIdentity("Balance", "")); + cubeCards.add(new DraftCube.CardIdentity("Baleful Strix", "")); + cubeCards.add(new DraftCube.CardIdentity("Baneslayer Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Banisher Priest", "")); + cubeCards.add(new DraftCube.CardIdentity("Banishing Light", "")); + cubeCards.add(new DraftCube.CardIdentity("Basalt Monolith", "")); + cubeCards.add(new DraftCube.CardIdentity("Batterskull", "")); + cubeCards.add(new DraftCube.CardIdentity("Bayou", "")); + cubeCards.add(new DraftCube.CardIdentity("Bazaar of Baghdad", "")); + cubeCards.add(new DraftCube.CardIdentity("Beast Within", "")); + cubeCards.add(new DraftCube.CardIdentity("Birds of Paradise", "")); + cubeCards.add(new DraftCube.CardIdentity("Birthing Pod", "")); + cubeCards.add(new DraftCube.CardIdentity("Bitterblossom", "")); + cubeCards.add(new DraftCube.CardIdentity("Black Lotus", "")); + cubeCards.add(new DraftCube.CardIdentity("Blade Splicer", "")); + cubeCards.add(new DraftCube.CardIdentity("Blightsteel Colossus", "")); + cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", "")); + cubeCards.add(new DraftCube.CardIdentity("Bloodbraid Elf", "")); + cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", "")); + cubeCards.add(new DraftCube.CardIdentity("Bone Shredder", "")); + cubeCards.add(new DraftCube.CardIdentity("Bonfire of the Damned", "")); + cubeCards.add(new DraftCube.CardIdentity("Boros Charm", "")); + cubeCards.add(new DraftCube.CardIdentity("Boros Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Braids, Cabal Minion", "")); + cubeCards.add(new DraftCube.CardIdentity("Brain Freeze", "")); + cubeCards.add(new DraftCube.CardIdentity("Brain Maggot", "")); + cubeCards.add(new DraftCube.CardIdentity("Brainstorm", "")); + cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", "")); + cubeCards.add(new DraftCube.CardIdentity("Bribery", "")); + cubeCards.add(new DraftCube.CardIdentity("Brimaz, King of Oreskos", "")); + cubeCards.add(new DraftCube.CardIdentity("Brimstone Volley", "")); + cubeCards.add(new DraftCube.CardIdentity("Bring to Light", "")); + cubeCards.add(new DraftCube.CardIdentity("Buried Alive", "")); + cubeCards.add(new DraftCube.CardIdentity("Burning of Xinye", "")); + cubeCards.add(new DraftCube.CardIdentity("Burst Lightning", "")); + cubeCards.add(new DraftCube.CardIdentity("Cabal Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Careful Study", "")); + cubeCards.add(new DraftCube.CardIdentity("Celestial Colonnade", "")); + cubeCards.add(new DraftCube.CardIdentity("Chain Lightning", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Flamecaller", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Pyromaster", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Torch of Defiance", "")); + cubeCards.add(new DraftCube.CardIdentity("Channel", "")); + cubeCards.add(new DraftCube.CardIdentity("Char", "")); + cubeCards.add(new DraftCube.CardIdentity("Chrome Mox", "")); + cubeCards.add(new DraftCube.CardIdentity("Coalition Relic", "")); + cubeCards.add(new DraftCube.CardIdentity("Coercive Portal", "")); + cubeCards.add(new DraftCube.CardIdentity("Compulsive Research", "")); + cubeCards.add(new DraftCube.CardIdentity("Conclave Naturalists", "")); + cubeCards.add(new DraftCube.CardIdentity("Consecrated Sphinx", "")); + cubeCards.add(new DraftCube.CardIdentity("Control Magic", "")); + cubeCards.add(new DraftCube.CardIdentity("Corpse Dance", "")); + cubeCards.add(new DraftCube.CardIdentity("Council's Judgment", "")); + cubeCards.add(new DraftCube.CardIdentity("Counterspell", "")); + cubeCards.add(new DraftCube.CardIdentity("Courser of Kruphix", "")); + cubeCards.add(new DraftCube.CardIdentity("Crater's Claws", "")); + cubeCards.add(new DraftCube.CardIdentity("Craterhoof Behemoth", "")); + cubeCards.add(new DraftCube.CardIdentity("Creeping Tar Pit", "")); + cubeCards.add(new DraftCube.CardIdentity("Crucible of Worlds", "")); + cubeCards.add(new DraftCube.CardIdentity("Cryptic Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Dack Fayden", "")); + cubeCards.add(new DraftCube.CardIdentity("Damnation", "")); + cubeCards.add(new DraftCube.CardIdentity("Daretti, Scrap Savant", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Confidant", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Petition", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Day of Judgment", "")); + cubeCards.add(new DraftCube.CardIdentity("Daze", "")); + cubeCards.add(new DraftCube.CardIdentity("Deathrite Shaman", "")); + cubeCards.add(new DraftCube.CardIdentity("Deceiver Exarch", "")); + cubeCards.add(new DraftCube.CardIdentity("Declaration in Stone", "")); + cubeCards.add(new DraftCube.CardIdentity("Delver of Secrets", "")); + cubeCards.add(new DraftCube.CardIdentity("Demonic Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Den Protector", "")); + cubeCards.add(new DraftCube.CardIdentity("Deranged Hermit", "")); + cubeCards.add(new DraftCube.CardIdentity("Desecration Demon", "")); + cubeCards.add(new DraftCube.CardIdentity("Diabolic Edict", "")); + cubeCards.add(new DraftCube.CardIdentity("Dig Through Time", "")); + cubeCards.add(new DraftCube.CardIdentity("Dimir Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Disenchant", "")); + cubeCards.add(new DraftCube.CardIdentity("Disfigure", "")); + cubeCards.add(new DraftCube.CardIdentity("Dismember", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Atarka", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Dromoka", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Ojutai", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Silumgar", "")); + cubeCards.add(new DraftCube.CardIdentity("Dreadbore", "")); + cubeCards.add(new DraftCube.CardIdentity("Dromoka's Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Dualcaster Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Duplicant", "")); + cubeCards.add(new DraftCube.CardIdentity("Duress", "")); + cubeCards.add(new DraftCube.CardIdentity("Edric, Spymaster of Trest", "")); + cubeCards.add(new DraftCube.CardIdentity("Eidolon of the Great Revel", "")); + cubeCards.add(new DraftCube.CardIdentity("Electrolyze", "")); + cubeCards.add(new DraftCube.CardIdentity("Elesh Norn, Grand Cenobite", "")); + cubeCards.add(new DraftCube.CardIdentity("Elspeth, Knight-Errant", "")); + cubeCards.add(new DraftCube.CardIdentity("Elspeth, Sun's Champion", "")); + cubeCards.add(new DraftCube.CardIdentity("Elves of Deep Shadow", "")); + cubeCards.add(new DraftCube.CardIdentity("Elvish Mystic", "")); + cubeCards.add(new DraftCube.CardIdentity("Emeria Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Empty the Warrens", "")); + cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Aeons Torn", "")); + cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Promised End", "")); + cubeCards.add(new DraftCube.CardIdentity("Enlightened Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Entomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Eternal Witness", "")); + cubeCards.add(new DraftCube.CardIdentity("Eureka", "")); + cubeCards.add(new DraftCube.CardIdentity("Everflowing Chalice", "")); + cubeCards.add(new DraftCube.CardIdentity("Exalted Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Exquisite Firecraft", "")); + cubeCards.add(new DraftCube.CardIdentity("Exhume", "")); + cubeCards.add(new DraftCube.CardIdentity("Fact or Fiction", "")); + cubeCards.add(new DraftCube.CardIdentity("Faith's Fetters", "")); + cubeCards.add(new DraftCube.CardIdentity("Faithless Looting", "")); + cubeCards.add(new DraftCube.CardIdentity("Falkenrath Gorger", "")); + cubeCards.add(new DraftCube.CardIdentity("Fastbond", "")); + cubeCards.add(new DraftCube.CardIdentity("Fauna Shaman", "")); + cubeCards.add(new DraftCube.CardIdentity("Fiend Hunter", "")); + cubeCards.add(new DraftCube.CardIdentity("Fiery Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("Figure of Destiny", "")); + cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", "")); + cubeCards.add(new DraftCube.CardIdentity("Fireblast", "")); + cubeCards.add(new DraftCube.CardIdentity("Firebolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Firedrinker Satyr", "")); + cubeCards.add(new DraftCube.CardIdentity("Flametongue Kavu", "")); + cubeCards.add(new DraftCube.CardIdentity("Flickerwisp", "")); + cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", "")); + cubeCards.add(new DraftCube.CardIdentity("Force of Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Force Spike", "")); + cubeCards.add(new DraftCube.CardIdentity("Frantic Search", "")); + cubeCards.add(new DraftCube.CardIdentity("Freyalise, Llanowar's Fury", "")); + cubeCards.add(new DraftCube.CardIdentity("Frost Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Fyndhorn Elves", "")); + cubeCards.add(new DraftCube.CardIdentity("Gaea's Cradle", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk Relentless", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk Wildspeaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk, Apex Predator", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk, Primal Hunter", "")); + cubeCards.add(new DraftCube.CardIdentity("Geist of Saint Traft", "")); + cubeCards.add(new DraftCube.CardIdentity("Genesis Wave", "")); + cubeCards.add(new DraftCube.CardIdentity("Gideon Jura", "")); + cubeCards.add(new DraftCube.CardIdentity("Gideon, Ally of Zendikar", "")); + cubeCards.add(new DraftCube.CardIdentity("Gifts Ungiven", "")); + cubeCards.add(new DraftCube.CardIdentity("Gilded Lotus", "")); + cubeCards.add(new DraftCube.CardIdentity("Gitaxian Probe", "")); + cubeCards.add(new DraftCube.CardIdentity("Glen Elendra Archmage", "")); + cubeCards.add(new DraftCube.CardIdentity("Go for the Throat", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Dark-Dwellers", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Guide", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Welder", "")); + cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", "")); + cubeCards.add(new DraftCube.CardIdentity("Golgari Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Grave Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Green Sun's Zenith", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Lavamancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Monolith", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Griselbrand", "")); + cubeCards.add(new DraftCube.CardIdentity("Gruul Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Gurmag Angler", "")); + cubeCards.add(new DraftCube.CardIdentity("Gush", "")); + cubeCards.add(new DraftCube.CardIdentity("Guttersnipe", "")); + cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", "")); + cubeCards.add(new DraftCube.CardIdentity("Hangarback Walker", "")); + cubeCards.add(new DraftCube.CardIdentity("Harmonize", "")); + cubeCards.add(new DraftCube.CardIdentity("Heartbeat of Spring", "")); + cubeCards.add(new DraftCube.CardIdentity("Hedron Archive", "")); + cubeCards.add(new DraftCube.CardIdentity("Hellrider", "")); + cubeCards.add(new DraftCube.CardIdentity("Hero of Bladehold", "")); + cubeCards.add(new DraftCube.CardIdentity("Hero's Downfall", "")); + cubeCards.add(new DraftCube.CardIdentity("High Tide", "")); + cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", "")); + cubeCards.add(new DraftCube.CardIdentity("Honor of the Pure", "")); + cubeCards.add(new DraftCube.CardIdentity("Huntmaster of the Fells", "")); + cubeCards.add(new DraftCube.CardIdentity("Hymn to Tourach", "")); + cubeCards.add(new DraftCube.CardIdentity("Hypnotic Specter", "")); + cubeCards.add(new DraftCube.CardIdentity("Imperial Recruiter", "")); + cubeCards.add(new DraftCube.CardIdentity("Imperial Seal", "")); + cubeCards.add(new DraftCube.CardIdentity("Impulse", "")); + cubeCards.add(new DraftCube.CardIdentity("Incinerate", "")); + cubeCards.add(new DraftCube.CardIdentity("Inferno Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Inkwell Leviathan", "")); + cubeCards.add(new DraftCube.CardIdentity("Inquisition of Kozilek", "")); + cubeCards.add(new DraftCube.CardIdentity("Iona, Shield of Emeria", "")); + cubeCards.add(new DraftCube.CardIdentity("Isochron Scepter", "")); + cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", "")); + cubeCards.add(new DraftCube.CardIdentity("Izzet Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace Beleren", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, Architect of Thought", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, the Mind Sculptor", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, Vryn's Prodigy", "")); + cubeCards.add(new DraftCube.CardIdentity("Jackal Pup", "")); + cubeCards.add(new DraftCube.CardIdentity("Joraga Treespeaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Kalitas, Traitor of Ghet", "")); + cubeCards.add(new DraftCube.CardIdentity("Karakas", "")); + cubeCards.add(new DraftCube.CardIdentity("Kargan Dragonlord", "")); + cubeCards.add(new DraftCube.CardIdentity("Karn Liberated", "")); + cubeCards.add(new DraftCube.CardIdentity("Kiki-Jiki, Mirror Breaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Kitchen Finks", "")); + cubeCards.add(new DraftCube.CardIdentity("Knight of the White Orchid", "")); + cubeCards.add(new DraftCube.CardIdentity("Kolaghan's Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Koth of the Hammer", "")); + cubeCards.add(new DraftCube.CardIdentity("Kozilek, Butcher of Truth", "")); + cubeCards.add(new DraftCube.CardIdentity("Kuldotha Forgemaster", "")); + cubeCards.add(new DraftCube.CardIdentity("Kytheon, Hero of Akros", "")); + cubeCards.add(new DraftCube.CardIdentity("Land Tax", "")); + cubeCards.add(new DraftCube.CardIdentity("Lavaclaw Reaches", "")); + cubeCards.add(new DraftCube.CardIdentity("Leonin Relic-Warder", "")); + cubeCards.add(new DraftCube.CardIdentity("Leyline of Sanctity", "")); + cubeCards.add(new DraftCube.CardIdentity("Library of Alexandria", "")); + cubeCards.add(new DraftCube.CardIdentity("Lifebane Zombie", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Bolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Greaves", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Helix", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Mauler", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", "")); + cubeCards.add(new DraftCube.CardIdentity("Liliana of the Veil", "")); + cubeCards.add(new DraftCube.CardIdentity("Lingering Souls", "")); + cubeCards.add(new DraftCube.CardIdentity("Linvala, Keeper of Silence", "")); + cubeCards.add(new DraftCube.CardIdentity("Linvala, the Preserver", "")); + cubeCards.add(new DraftCube.CardIdentity("Lion's Eye Diamond", "")); + cubeCards.add(new DraftCube.CardIdentity("Living Death", "")); + cubeCards.add(new DraftCube.CardIdentity("Llanowar Elves", "")); + cubeCards.add(new DraftCube.CardIdentity("Lodestone Golem", "")); + cubeCards.add(new DraftCube.CardIdentity("Looter il-Kor", "")); + cubeCards.add(new DraftCube.CardIdentity("Lotus Bloom", "")); + cubeCards.add(new DraftCube.CardIdentity("Lotus Cobra", "")); + cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", "")); + cubeCards.add(new DraftCube.CardIdentity("Maelstrom Pulse", "")); + cubeCards.add(new DraftCube.CardIdentity("Magma Jet", "")); + cubeCards.add(new DraftCube.CardIdentity("Magus of the Moon", "")); + cubeCards.add(new DraftCube.CardIdentity("Magus of the Wheel", "")); + cubeCards.add(new DraftCube.CardIdentity("Magus of the Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Makeshift Mannequin", "")); + cubeCards.add(new DraftCube.CardIdentity("Managorger Hydra", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Crypt", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Drain", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Leak", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Tithe", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Vault", "")); + cubeCards.add(new DraftCube.CardIdentity("Manic Vandal", "")); + cubeCards.add(new DraftCube.CardIdentity("Mardu Woe-Reaper", "")); + cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", "")); + cubeCards.add(new DraftCube.CardIdentity("Massacre Wurm", "")); + cubeCards.add(new DraftCube.CardIdentity("Master of the Wild Hunt", "")); + cubeCards.add(new DraftCube.CardIdentity("Maze of Ith", "")); + cubeCards.add(new DraftCube.CardIdentity("Mental Misstep", "")); + cubeCards.add(new DraftCube.CardIdentity("Memory Jar", "")); + cubeCards.add(new DraftCube.CardIdentity("Mesmeric Fiend", "")); + cubeCards.add(new DraftCube.CardIdentity("Metalworker", "")); + cubeCards.add(new DraftCube.CardIdentity("Mind Twist", "")); + cubeCards.add(new DraftCube.CardIdentity("Mindslaver", "")); + cubeCards.add(new DraftCube.CardIdentity("Mind's Desire", "")); + cubeCards.add(new DraftCube.CardIdentity("Mirari's Wake", "")); + cubeCards.add(new DraftCube.CardIdentity("Mirran Crusader", "")); + cubeCards.add(new DraftCube.CardIdentity("Mishra's Factory", "")); + cubeCards.add(new DraftCube.CardIdentity("Mishra's Workshop", "")); + cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", "")); + cubeCards.add(new DraftCube.CardIdentity("Mizzium Mortars", "")); + cubeCards.add(new DraftCube.CardIdentity("Moat", "")); + cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", "")); + cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", "")); + cubeCards.add(new DraftCube.CardIdentity("Mother of Runes", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Diamond", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Emerald", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Jet", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Pearl", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Ruby", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Sapphire", "")); + cubeCards.add(new DraftCube.CardIdentity("Mulldrifter", "")); + cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", "")); + cubeCards.add(new DraftCube.CardIdentity("Mutavault", "")); + cubeCards.add(new DraftCube.CardIdentity("Myr Battlesphere", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystical Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystic Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", "")); + cubeCards.add(new DraftCube.CardIdentity("Nahiri, the Harbinger", "")); + cubeCards.add(new DraftCube.CardIdentity("Natural Order", "")); + cubeCards.add(new DraftCube.CardIdentity("Nature's Claim", "")); + cubeCards.add(new DraftCube.CardIdentity("Necromancy", "")); + cubeCards.add(new DraftCube.CardIdentity("Necropotence", "")); + cubeCards.add(new DraftCube.CardIdentity("Needle Spires", "")); + cubeCards.add(new DraftCube.CardIdentity("Nekrataal", "")); + cubeCards.add(new DraftCube.CardIdentity("Nevinyrral's Disk", "")); + cubeCards.add(new DraftCube.CardIdentity("Nezumi Graverobber", "")); + cubeCards.add(new DraftCube.CardIdentity("Nezumi Shortfang", "")); + cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, Planeswalker", "")); + cubeCards.add(new DraftCube.CardIdentity("Nissa, Worldwaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Noble Hierarch", "")); + cubeCards.add(new DraftCube.CardIdentity("Nykthos, Shrine to Nyx", "")); + cubeCards.add(new DraftCube.CardIdentity("Oath of Druids", "")); + cubeCards.add(new DraftCube.CardIdentity("Oath of Nissa", "")); + cubeCards.add(new DraftCube.CardIdentity("Oblivion Ring", "")); + cubeCards.add(new DraftCube.CardIdentity("Olivia Voldaren", "")); + cubeCards.add(new DraftCube.CardIdentity("Oona's Prowler", "")); + cubeCards.add(new DraftCube.CardIdentity("Ophiomancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Opposition", "")); + cubeCards.add(new DraftCube.CardIdentity("Oracle of Mul Daya", "")); + cubeCards.add(new DraftCube.CardIdentity("Orzhov Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Pack Rat", "")); + cubeCards.add(new DraftCube.CardIdentity("Painful Truths", "")); + cubeCards.add(new DraftCube.CardIdentity("Palinchron", "")); + cubeCards.add(new DraftCube.CardIdentity("Parallax Wave", "")); + cubeCards.add(new DraftCube.CardIdentity("Path to Exile", "")); + cubeCards.add(new DraftCube.CardIdentity("Pentad Prism", "")); + cubeCards.add(new DraftCube.CardIdentity("Pernicious Deed", "")); + cubeCards.add(new DraftCube.CardIdentity("Pestermite", "")); + cubeCards.add(new DraftCube.CardIdentity("Phantasmal Image", "")); + cubeCards.add(new DraftCube.CardIdentity("Phyrexian Metamorph", "")); + cubeCards.add(new DraftCube.CardIdentity("Phyrexian Revoker", "")); + cubeCards.add(new DraftCube.CardIdentity("Pithing Needle", "")); + cubeCards.add(new DraftCube.CardIdentity("Plateau", "")); + cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", "")); + cubeCards.add(new DraftCube.CardIdentity("Polukranos, World Eater", "")); + cubeCards.add(new DraftCube.CardIdentity("Ponder", "")); + cubeCards.add(new DraftCube.CardIdentity("Porcelain Legionnaire", "")); + cubeCards.add(new DraftCube.CardIdentity("Preordain", "")); + cubeCards.add(new DraftCube.CardIdentity("Primal Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Primeval Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Progenitus", "")); + cubeCards.add(new DraftCube.CardIdentity("Puppeteer Clique", "")); + cubeCards.add(new DraftCube.CardIdentity("Putrid Imp", "")); + cubeCards.add(new DraftCube.CardIdentity("Qasali Pridemage", "")); + cubeCards.add(new DraftCube.CardIdentity("Quicken", "")); + cubeCards.add(new DraftCube.CardIdentity("Raging Ravine", "")); + cubeCards.add(new DraftCube.CardIdentity("Rakdos Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Rakdos's Return", "")); + cubeCards.add(new DraftCube.CardIdentity("Ral Zarek", "")); + cubeCards.add(new DraftCube.CardIdentity("Ravages of War", "")); + cubeCards.add(new DraftCube.CardIdentity("Reanimate", "")); + cubeCards.add(new DraftCube.CardIdentity("Reckless Bushwhacker", "")); + cubeCards.add(new DraftCube.CardIdentity("Reclamation Sage", "")); + cubeCards.add(new DraftCube.CardIdentity("Recruiter of the Guard", "")); + cubeCards.add(new DraftCube.CardIdentity("Recurring Nightmare", "")); + cubeCards.add(new DraftCube.CardIdentity("Reflector Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Regrowth", "")); + cubeCards.add(new DraftCube.CardIdentity("Remand", "")); + cubeCards.add(new DraftCube.CardIdentity("Repeal", "")); + cubeCards.add(new DraftCube.CardIdentity("Restoration Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Reveillark", "")); + cubeCards.add(new DraftCube.CardIdentity("Rift Bolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Riftwing Cloudskate", "")); + cubeCards.add(new DraftCube.CardIdentity("Rishadan Port", "")); + cubeCards.add(new DraftCube.CardIdentity("Roast", "")); + cubeCards.add(new DraftCube.CardIdentity("Rofellos, Llanowar Emissary", "")); + cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", "")); + cubeCards.add(new DraftCube.CardIdentity("Sakura-Tribe Elder", "")); + cubeCards.add(new DraftCube.CardIdentity("Savannah", "")); + cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", "")); + cubeCards.add(new DraftCube.CardIdentity("Scavenging Ooze", "")); + cubeCards.add(new DraftCube.CardIdentity("Scroll Rack", "")); + cubeCards.add(new DraftCube.CardIdentity("Scrubland", "")); + cubeCards.add(new DraftCube.CardIdentity("Search for Tomorrow", "")); + cubeCards.add(new DraftCube.CardIdentity("Searing Blaze", "")); + cubeCards.add(new DraftCube.CardIdentity("Searing Spear", "")); + cubeCards.add(new DraftCube.CardIdentity("Seasons Past", "")); + cubeCards.add(new DraftCube.CardIdentity("Seeker of the Way", "")); + cubeCards.add(new DraftCube.CardIdentity("Seething Song", "")); + cubeCards.add(new DraftCube.CardIdentity("Selesnya Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Selfless Spirit", "")); + cubeCards.add(new DraftCube.CardIdentity("Sensei's Divining Top", "")); + cubeCards.add(new DraftCube.CardIdentity("Shadowmage Infiltrator", "")); + cubeCards.add(new DraftCube.CardIdentity("Shallow Grave", "")); + cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", "")); + cubeCards.add(new DraftCube.CardIdentity("Shardless Agent", "")); + cubeCards.add(new DraftCube.CardIdentity("Shelldock Isle", "")); + cubeCards.add(new DraftCube.CardIdentity("Sheoldred, Whispering One", "")); + cubeCards.add(new DraftCube.CardIdentity("Show and Tell", "")); + cubeCards.add(new DraftCube.CardIdentity("Shriekmaw", "")); + cubeCards.add(new DraftCube.CardIdentity("Shrine of Burning Rage", "")); + cubeCards.add(new DraftCube.CardIdentity("Sidisi, Undead Vizier", "")); + cubeCards.add(new DraftCube.CardIdentity("Siege-Gang Commander", "")); + cubeCards.add(new DraftCube.CardIdentity("Silverblade Paladin", "")); + cubeCards.add(new DraftCube.CardIdentity("Simic Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Skinrender", "")); + cubeCards.add(new DraftCube.CardIdentity("Skullclamp", "")); + cubeCards.add(new DraftCube.CardIdentity("Smash to Smithereens", "")); + cubeCards.add(new DraftCube.CardIdentity("Smokestack", "")); + cubeCards.add(new DraftCube.CardIdentity("Smuggler's Copter", "")); + cubeCards.add(new DraftCube.CardIdentity("Snapcaster Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Sneak Attack", "")); + cubeCards.add(new DraftCube.CardIdentity("Sol Ring", "")); + cubeCards.add(new DraftCube.CardIdentity("Soldier of the Pantheon", "")); + cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", "")); + cubeCards.add(new DraftCube.CardIdentity("Song of the Dryads", "")); + cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", "")); + cubeCards.add(new DraftCube.CardIdentity("Sower of Temptation", "")); + cubeCards.add(new DraftCube.CardIdentity("Spear of Heliod", "")); + cubeCards.add(new DraftCube.CardIdentity("Spectral Procession", "")); + cubeCards.add(new DraftCube.CardIdentity("Spell Pierce", "")); + cubeCards.add(new DraftCube.CardIdentity("Spellskite", "")); + cubeCards.add(new DraftCube.CardIdentity("Sphinx of the Steel Wind", "")); + cubeCards.add(new DraftCube.CardIdentity("Sphinx's Revelation", "")); + cubeCards.add(new DraftCube.CardIdentity("Spirit of the Labyrinth", "")); + cubeCards.add(new DraftCube.CardIdentity("Splinter Twin", "")); + cubeCards.add(new DraftCube.CardIdentity("Steam Vents", "")); + cubeCards.add(new DraftCube.CardIdentity("Stirring Wildwood", "")); + cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", "")); + cubeCards.add(new DraftCube.CardIdentity("Stoneforge Mystic", "")); + cubeCards.add(new DraftCube.CardIdentity("Stormbreath Dragon", "")); + cubeCards.add(new DraftCube.CardIdentity("Strip Mine", "")); + cubeCards.add(new DraftCube.CardIdentity("Student of Warfare", "")); + cubeCards.add(new DraftCube.CardIdentity("Sulfuric Vortex", "")); + cubeCards.add(new DraftCube.CardIdentity("Sun Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Sundering Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Supreme Verdict", "")); + cubeCards.add(new DraftCube.CardIdentity("Survival of the Fittest", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Body and Mind", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Feast and Famine", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Fire and Ice", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Light and Shadow", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of War and Peace", "")); + cubeCards.add(new DraftCube.CardIdentity("Swords to Plowshares", "")); + cubeCards.add(new DraftCube.CardIdentity("Sylvan Caryatid", "")); + cubeCards.add(new DraftCube.CardIdentity("Sylvan Library", "")); + cubeCards.add(new DraftCube.CardIdentity("Taiga", "")); + cubeCards.add(new DraftCube.CardIdentity("Tamiyo, the Moon Sage", "")); + cubeCards.add(new DraftCube.CardIdentity("Tangle Wire", "")); + cubeCards.add(new DraftCube.CardIdentity("Tarmogoyf", "")); + cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple Garden", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Abandon", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Deceit", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Enlightenment", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Epiphany", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Malady", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Malice", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Mystery", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Plenty", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Silence", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple of Triumph", "")); + cubeCards.add(new DraftCube.CardIdentity("Tendrils of Agony", "")); + cubeCards.add(new DraftCube.CardIdentity("Terastodon", "")); + cubeCards.add(new DraftCube.CardIdentity("Terminate", "")); + cubeCards.add(new DraftCube.CardIdentity("Tezzeret the Seeker", "")); + cubeCards.add(new DraftCube.CardIdentity("Tezzeret, Agent of Bolas", "")); + cubeCards.add(new DraftCube.CardIdentity("Thada Adel, Acquisitor", "")); + cubeCards.add(new DraftCube.CardIdentity("Thalia, Guardian of Thraben", "")); + cubeCards.add(new DraftCube.CardIdentity("The Abyss", "")); + cubeCards.add(new DraftCube.CardIdentity("Thing in the Ice", "")); + cubeCards.add(new DraftCube.CardIdentity("Thirst for Knowledge", "")); + cubeCards.add(new DraftCube.CardIdentity("Thoughtseize", "")); + cubeCards.add(new DraftCube.CardIdentity("Thragtusk", "")); + cubeCards.add(new DraftCube.CardIdentity("Thran Dynamo", "")); + cubeCards.add(new DraftCube.CardIdentity("Through the Breach", "")); + cubeCards.add(new DraftCube.CardIdentity("Thrun, the Last Troll", "")); + cubeCards.add(new DraftCube.CardIdentity("Thundermaw Hellkite", "")); + cubeCards.add(new DraftCube.CardIdentity("Tidehollow Sculler", "")); + cubeCards.add(new DraftCube.CardIdentity("Time Spiral", "")); + cubeCards.add(new DraftCube.CardIdentity("Time Walk", "")); + cubeCards.add(new DraftCube.CardIdentity("Timely Reinforcements", "")); + cubeCards.add(new DraftCube.CardIdentity("Timetwister", "")); + cubeCards.add(new DraftCube.CardIdentity("Tinker", "")); + cubeCards.add(new DraftCube.CardIdentity("Tolarian Academy", "")); + cubeCards.add(new DraftCube.CardIdentity("Tooth and Nail", "")); + cubeCards.add(new DraftCube.CardIdentity("Torch Fiend", "")); + cubeCards.add(new DraftCube.CardIdentity("Torrential Gearhulk", "")); + cubeCards.add(new DraftCube.CardIdentity("Toxic Deluge", "")); + cubeCards.add(new DraftCube.CardIdentity("Traverse the Ulvenwald", "")); + cubeCards.add(new DraftCube.CardIdentity("Treachery", "")); + cubeCards.add(new DraftCube.CardIdentity("Treasure Cruise", "")); + cubeCards.add(new DraftCube.CardIdentity("Trinket Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Tropical Island", "")); + cubeCards.add(new DraftCube.CardIdentity("True-Name Nemesis", "")); + cubeCards.add(new DraftCube.CardIdentity("Trygon Predator", "")); + cubeCards.add(new DraftCube.CardIdentity("Tundra", "")); + cubeCards.add(new DraftCube.CardIdentity("Turnabout", "")); + cubeCards.add(new DraftCube.CardIdentity("Ugin, the Spirit Dragon", "")); + cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Ceaseless Hunger", "")); + cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Infinite Gyre", "")); + cubeCards.add(new DraftCube.CardIdentity("Ultimate Price", "")); + cubeCards.add(new DraftCube.CardIdentity("Umezawa's Jitte", "")); + cubeCards.add(new DraftCube.CardIdentity("Unburial Rites", "")); + cubeCards.add(new DraftCube.CardIdentity("Underground Sea", "")); + cubeCards.add(new DraftCube.CardIdentity("Unexpectedly Absent", "")); + cubeCards.add(new DraftCube.CardIdentity("Upheaval", "")); + cubeCards.add(new DraftCube.CardIdentity("Urborg, Tomb of Yawgmoth", "")); + cubeCards.add(new DraftCube.CardIdentity("Vampire Nighthawk", "")); + cubeCards.add(new DraftCube.CardIdentity("Vampiric Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Vedalken Shackles", "")); + cubeCards.add(new DraftCube.CardIdentity("Vendilion Clique", "")); + cubeCards.add(new DraftCube.CardIdentity("Venser, Shaper Savant", "")); + cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", "")); + cubeCards.add(new DraftCube.CardIdentity("Verdurous Gearhulk", "")); + cubeCards.add(new DraftCube.CardIdentity("Villainous Wealth", "")); + cubeCards.add(new DraftCube.CardIdentity("Vindicate", "")); + cubeCards.add(new DraftCube.CardIdentity("Voice of Resurgence", "")); + cubeCards.add(new DraftCube.CardIdentity("Volcanic Island", "")); + cubeCards.add(new DraftCube.CardIdentity("Vryn Wingmare", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Blossoms", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Roots", "")); + cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", "")); + cubeCards.add(new DraftCube.CardIdentity("War Priest of Thune", "")); + cubeCards.add(new DraftCube.CardIdentity("Wasteland", "")); + cubeCards.add(new DraftCube.CardIdentity("Watery Grave", "")); + cubeCards.add(new DraftCube.CardIdentity("Westvale Abbey", "")); + cubeCards.add(new DraftCube.CardIdentity("Wheel of Fortune", "")); + cubeCards.add(new DraftCube.CardIdentity("Wildfire", "")); + cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", "")); + cubeCards.add(new DraftCube.CardIdentity("Winter Orb", "")); + cubeCards.add(new DraftCube.CardIdentity("Wolfir Silverheart", "")); + cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", "")); + cubeCards.add(new DraftCube.CardIdentity("Woodfall Primus", "")); + cubeCards.add(new DraftCube.CardIdentity("Worn Powerstone", "")); + cubeCards.add(new DraftCube.CardIdentity("Wrath of God", "")); + cubeCards.add(new DraftCube.CardIdentity("Wurmcoil Engine", "")); + cubeCards.add(new DraftCube.CardIdentity("Xenagos, the Reveler", "")); + cubeCards.add(new DraftCube.CardIdentity("Yavimaya Elder", "")); + cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Bargain", "")); + cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Young Pyromancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Zealous Conscripts", "")); + cubeCards.add(new DraftCube.CardIdentity("Zurgo Bellstriker", "")); + } +} diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 6f249ddd287..fd41c97a47c 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -114,6 +114,7 @@ + diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml index 35123a13dd7..0f2c1d167eb 100644 --- a/Mage.Server/release/config/config.xml +++ b/Mage.Server/release/config/config.xml @@ -111,6 +111,7 @@ + diff --git a/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java b/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java new file mode 100644 index 00000000000..bc530cba2c6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AjaniUnyielding.java @@ -0,0 +1,97 @@ +/* + * 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 mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; +import mage.abilities.effects.common.SwordsToPlowsharesEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterPermanentCard; +import mage.filter.common.FilterPlaneswalkerPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author JRHerlehy + */ +public class AjaniUnyielding extends CardImpl { + + private static final FilterPermanentCard nonlandPermanentFilter = new FilterPermanentCard("nonland permanent card"); + private static final FilterCreaturePermanent creatureFilter = new FilterCreaturePermanent("creature you control"); + private static final FilterPlaneswalkerPermanent planeswalkerFilter = new FilterPlaneswalkerPermanent("other planeswalker you control"); + + static { + nonlandPermanentFilter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + creatureFilter.add(new ControllerPredicate(TargetController.YOU)); + planeswalkerFilter.add(new ControllerPredicate(TargetController.YOU)); + planeswalkerFilter.add(new AnotherPredicate()); + } + + public AjaniUnyielding(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{G}{W}"); + this.subtype.add("Ajani"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +2: Reveal the top three cards of your library. Put all nonland permanent cards revealed this way into your hand and the rest on the bottom of your library in any order. + this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(3, nonlandPermanentFilter, true), 2)); + + // -2: Exile target creature. Its controller gains life equal to its power. + LoyaltyAbility ajaniAbility2 = new LoyaltyAbility(new SwordsToPlowsharesEffect(), -2); + ajaniAbility2.addEffect(new ExileTargetEffect()); + ajaniAbility2.addTarget(new TargetCreaturePermanent()); + this.addAbility(ajaniAbility2); + + // -9: Put five +1/+1 counters on each creature you control and five loyalty counters on each other planeswalker you control. + LoyaltyAbility ajaniAbility3 = new LoyaltyAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(5), creatureFilter), -9); + ajaniAbility3.addEffect(new AddCountersAllEffect(CounterType.LOYALTY.createInstance(5), planeswalkerFilter)); + this.addAbility(ajaniAbility3); + } + + public AjaniUnyielding(final AjaniUnyielding card) { + super(card); + } + + @Override + public AjaniUnyielding copy() { + return new AjaniUnyielding(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java new file mode 100644 index 00000000000..0389e582081 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.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.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.dynamicvalue.common.ControllerLifeCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.counters.CounterType; +import mage.filter.common.FilterCreatureCard; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Styxo + */ +public class AjaniValiantProtector extends CardImpl { + + public AjaniValiantProtector(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{G}{W}"); + this.subtype.add("Ajani"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +2: Put two +1/+1 counters on up to one target creature. + Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + + // +1: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order. + this.addAbility(new LoyaltyAbility(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard()), 1)); + + // -11: Put X +1/+1 counters on target creature, where X is your life total. That creature gains trample until end of turn. + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), new ControllerLifeCount()); + effect.setText("Put X +1/+1 counters on target creature, where X is your life total."); + ability = new LoyaltyAbility(effect, -11); + effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText("That creature gains trample until end of turn"); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public AjaniValiantProtector(final AjaniValiantProtector card) { + super(card); + } + + @Override + public AjaniValiantProtector copy() { + return new AjaniValiantProtector(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java b/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java new file mode 100644 index 00000000000..73519045280 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BorderlandExplorer.java @@ -0,0 +1,168 @@ +/* + * 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.HashMap; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.filter.common.FilterBasicLandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetDiscard; + +/** + * + * @author fireshoes + */ +public class BorderlandExplorer extends CardImpl { + + public BorderlandExplorer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Elf"); + this.subtype.add("Scout"); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When Borderland Explorer enters the battlefield, each player may discard a card. Each player who discarded a card this way may search his or her library + // for a basic land card, reveal it, put it into his or her hand, then shuffle his or her library. + this.addAbility(new EntersBattlefieldTriggeredAbility(new BorderlandExplorerEffect())); + } + + public BorderlandExplorer(final BorderlandExplorer card) { + super(card); + } + + @Override + public BorderlandExplorer copy() { + return new BorderlandExplorer(this); + } +} + +class BorderlandExplorerEffect extends OneShotEffect { + + public BorderlandExplorerEffect() { + super(Outcome.Neutral); + this.staticText = "each player may discard a card. Each player who discarded a card this way may search his or her library " + + "for a basic land card, reveal it, put it into his or her hand, then shuffle his or her library"; + } + + public BorderlandExplorerEffect(final BorderlandExplorerEffect effect) { + super(effect); + } + + @Override + public BorderlandExplorerEffect copy() { + return new BorderlandExplorerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + // Store for each player the cards to discard, that's important because all discard shall happen at the same time + HashMap cardsToDiscard = new HashMap<>(); + // Store for each player the lands to reveal, that's important because all reveals shall happen at the same time + HashMap cardsToReveal = new HashMap<>(); + if (controller != null) { + // choose cards to discard + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cards = new CardsImpl(); + Target target = new TargetDiscard(0, 1, new FilterCard(), playerId); + player.chooseTarget(outcome, target, source, game); + cards.addAll(target.getTargets()); + cardsToDiscard.put(playerId, cards); + } + } + // discard all chosen cards + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cardsPlayer = cardsToDiscard.get(playerId); + if (cardsPlayer != null) { + for (UUID cardId : cardsPlayer) { + Card card = game.getCard(cardId); + if (card != null) { + player.discard(card, source, game); + } + } + } + } + } + // search for a land for each player that discarded + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cardsPlayer = cardsToDiscard.get(playerId); + if (cardsPlayer != null) { + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, new FilterBasicLandCard()); + if (player.searchLibrary(target, game)) { + if (target.getTargets().size() > 0) { + Cards cards = new CardsImpl(target.getTargets()); + cards.addAll(target.getTargets()); + cardsToReveal.put(playerId, cards); + } + } + } + } + } + // reveal the searched lands, put in hands, and shuffle + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cardsPlayer = cardsToReveal.get(playerId); + if (cardsPlayer != null) { + for (UUID cardId : cardsPlayer) { + Cards cards = new CardsImpl(game.getCard(cardId)); + Card card = game.getCard(cardId); + player.revealCards(card.getIdName() + " (" + player.getName() + ")", cards, game); + player.moveCardToHandWithInfo(card, source.getSourceId(), game); + player.shuffleLibrary(source, game); + } + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CapitalPunishment.java b/Mage.Sets/src/mage/cards/c/CapitalPunishment.java new file mode 100644 index 00000000000..9d3352938b0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CapitalPunishment.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.c; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author JRHerlehy + */ +public class CapitalPunishment extends CardImpl { + + public CapitalPunishment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{B}"); + + + // Council's dilemma — Starting with you, each player votes for death or taxes. Each opponent sacrifices a creature for each death vote and discards a card for each taxes vote. + this.getSpellAbility().addEffect(new CapitalPunishmentDilemmaEffect()); + } + + public CapitalPunishment(final CapitalPunishment card) { + super(card); + } + + @Override + public CapitalPunishment copy() { + return new CapitalPunishment(this); + } +} + +class CapitalPunishmentDilemmaEffect extends OneShotEffect { + + public CapitalPunishmentDilemmaEffect() { + super(Outcome.Detriment); + this.staticText = "Council's dilemma — Starting with you, each player votes for death or taxes. Each opponent sacrifices a creature for each death vote and discards a card for each taxes vote"; + } + + public CapitalPunishmentDilemmaEffect(final CapitalPunishmentDilemmaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + //If no controller, exit out here and do not vote. + if (controller == null) return false; + + int deathCount = 0, taxesCount = 0; + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.Detriment, "Choose death?", source, game)) { + deathCount++; + game.informPlayers(player.getName() + " has voted for death"); + } else { + taxesCount++; + game.informPlayers(player.getName() + " has voted for taxes"); + } + } + } + + if (deathCount > 0) { + Effect sacraficeEffect = new SacrificeOpponentsEffect(deathCount, new FilterControlledCreaturePermanent()); + sacraficeEffect.apply(game, source); + } + + if (taxesCount > 0) { + Effect discardEffect = new DiscardEachPlayerEffect(new StaticValue(taxesCount), false, TargetController.OPPONENT); + discardEffect.apply(game, source); + } + + return true; + } + + @Override + public CapitalPunishmentDilemmaEffect copy() { + return new CapitalPunishmentDilemmaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java new file mode 100644 index 00000000000..d1fd6e37a19 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java @@ -0,0 +1,192 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SkipDrawStepEffect; +import mage.abilities.effects.common.continuous.CantCastMoreThanOneSpellEffect; +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.TargetController; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author Styxo + */ +public class ColfenorsPlans extends CardImpl { + + public ColfenorsPlans(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); + + // When Colfenor's Plans enters the battlefield, exile the top seven cards of your library face down. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ColfenorsPlansExileEffect(), false)); + + // You may look at and play cards exiled with Colfenor's Plans. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ColfenorsPlansPlayCardEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ColfenorsPlansLookAtCardEffect())); + + // Skip your draw step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect())); + + // You can't cast more than one spell each turn. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantCastMoreThanOneSpellEffect(TargetController.YOU))); + + } + + public ColfenorsPlans(final ColfenorsPlans card) { + super(card); + } + + @Override + public ColfenorsPlans copy() { + return new ColfenorsPlans(this); + } +} + +class ColfenorsPlansExileEffect extends OneShotEffect { + + public ColfenorsPlansExileEffect() { + super(Outcome.DrawCard); + staticText = "exile the top seven cards of your library face down"; + } + + public ColfenorsPlansExileEffect(final ColfenorsPlansExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (player != null && sourceObject != null) { + for (int i = 0; i < 7; i++) { + Card card = player.getLibrary().removeFromTop(game); + if (card != null) { + if (player.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true)) { + card.setFaceDown(true, game); + } + } + } + return true; + } + return false; + } + + @Override + public ColfenorsPlansExileEffect copy() { + return new ColfenorsPlansExileEffect(this); + } +} + +class ColfenorsPlansPlayCardEffect extends AsThoughEffectImpl { + + public ColfenorsPlansPlayCardEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "You may play cards exiled with {this}"; + } + + public ColfenorsPlansPlayCardEffect(final ColfenorsPlansPlayCardEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ColfenorsPlansPlayCardEffect copy() { + return new ColfenorsPlansPlayCardEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(objectId); + if (affectedControllerId.equals(source.getControllerId()) && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); + return zone != null && zone.contains(card.getId()); + } + return false; + } +} + +class ColfenorsPlansLookAtCardEffect extends AsThoughEffectImpl { + + public ColfenorsPlansLookAtCardEffect() { + super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit); + staticText = "You may look at cards exiled with {this}"; + } + + public ColfenorsPlansLookAtCardEffect(final ColfenorsPlansLookAtCardEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ColfenorsPlansLookAtCardEffect copy() { + return new ColfenorsPlansLookAtCardEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (affectedControllerId.equals(source.getControllerId())) { + Card card = game.getCard(objectId); + if (card != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject == null) { + return false; + } + UUID exileId = CardUtil.getCardExileZoneId(game, source); + ExileZone exile = game.getExile().getExileZone(exileId); + return exile != null && exile.contains(objectId); + } + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java b/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java new file mode 100644 index 00000000000..0c477bc253c --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ColfenorsUrn.java @@ -0,0 +1,138 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ToughnessPredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author Styxo + */ +public class ColfenorsUrn extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature with toughness 4 or greater"); + + static { + filter.add(new ToughnessPredicate(Filter.ComparisonType.GreaterThan, 3)); + } + + public ColfenorsUrn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + // Whenever a creature with toughness 4 or greater is put into your graveyard from the battlefield, you may exile it. + this.addAbility(new DiesCreatureTriggeredAbility(new ExileTargetForSourceEffect(), true, filter, true)); + + // At the beginning of the end step, if three or more cards have been exiled with Colfenor's Urn, sacrifice it. If you do, return those cards to the battlefield under their owner's control. + this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ColfenorsUrnEffect(), TargetController.ANY, new ColfenorsUrnCondition(), false)); + } + + public ColfenorsUrn(final ColfenorsUrn card) { + super(card); + } + + @Override + public ColfenorsUrn copy() { + return new ColfenorsUrn(this); + } +} + +class ColfenorsUrnEffect extends OneShotEffect { + + public ColfenorsUrnEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "If you do, return those cards to the battlefield under their owner's control"; + } + + public ColfenorsUrnEffect(final ColfenorsUrnEffect effect) { + super(effect); + } + + @Override + public ColfenorsUrnEffect copy() { + return new ColfenorsUrnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game); + if (controller != null && permanent != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + ExileZone exile = game.getExile().getExileZone(exileId); + if (permanent.sacrifice(source.getSourceId(), game)) { + controller.moveCards(exile.getCards(game), Zone.BATTLEFIELD, source, game); + } + return true; + + } + return false; + } +} + +class ColfenorsUrnCondition implements Condition { + + @Override + public final boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null) { + return exile.size() > 2; + } + } + return false; + } + + @Override + public String toString() { + return "if three or more cards have been exiled with Colfenor's Urn, sacrifice it."; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java b/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java new file mode 100644 index 00000000000..bc66c7ed776 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrownOfTheAges.java @@ -0,0 +1,172 @@ +/* + * 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.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +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.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author spjspj + */ +public class CrownOfTheAges extends CardImpl { + + private static final FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("Aura attached to a creature"); + + static { + filter.add(new AttachmentAttachedToCardTypePredicate(CardType.CREATURE)); + filter.add(new SubtypePredicate("Aura")); + } + + public CrownOfTheAges(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // {4}, {tap}: Attach target Aura attached to a creature to another creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CrownOfTheAgesEffect(), new GenericManaCost(4)); + ability.addTarget(new TargetPermanent(filter)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public CrownOfTheAges(final CrownOfTheAges card) { + super(card); + } + + @Override + public CrownOfTheAges copy() { + return new CrownOfTheAges(this); + } +} + +class AttachmentAttachedToCardTypePredicate implements Predicate { + + private final CardType cardType; + + public AttachmentAttachedToCardTypePredicate(CardType cardType) { + this.cardType = cardType; + } + + @Override + public boolean apply(Permanent input, Game game) { + if (input.getAttachedTo() != null) { + Permanent attachedTo = game.getPermanent(input.getAttachedTo()); + if (attachedTo != null && attachedTo.getCardType().contains(cardType)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "AttachmentAttachedToCardType(" + cardType + ')'; + } +} + +class CrownOfTheAgesEffect extends OneShotEffect { + + public CrownOfTheAgesEffect() { + super(Outcome.BoostCreature); + this.staticText = "Attach target Aura attached to a creature to another creature"; + } + + public CrownOfTheAgesEffect(final CrownOfTheAgesEffect effect) { + super(effect); + } + + @Override + public CrownOfTheAgesEffect copy() { + return new CrownOfTheAgesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID auraId = getTargetPointer().getFirst(game, source); + Permanent aura = game.getPermanent(auraId); + Permanent fromPermanent = game.getPermanent(aura.getAttachedTo()); + Player controller = game.getPlayer(source.getControllerId()); + if (fromPermanent != null && controller != null) { + Boolean passed = true; + FilterCreaturePermanent filterChoice = new FilterCreaturePermanent("another creature"); + filterChoice.add(Predicates.not(new PermanentIdPredicate(fromPermanent.getId()))); + + Target chosenCreatureToAttachAura = new TargetPermanent(filterChoice); + chosenCreatureToAttachAura.setNotTarget(true); + + if (chosenCreatureToAttachAura.canChoose(source.getSourceId(), source.getControllerId(), game) + && controller.choose(Outcome.Neutral, chosenCreatureToAttachAura, source.getSourceId(), game)) { + Permanent creatureToAttachAura = game.getPermanent(chosenCreatureToAttachAura.getFirstTarget()); + if (creatureToAttachAura != null) { + if (aura != null && passed) { + // Check the target filter + Target target = aura.getSpellAbility().getTargets().get(0); + if (target instanceof TargetPermanent) { + if (!target.getFilter().match(creatureToAttachAura, game)) { + passed = false; + } + } + // Check for protection + MageObject auraObject = game.getObject(auraId); + if (creatureToAttachAura.cantBeAttachedBy(auraObject, game)) { + passed = false; + } + } + if (passed) { + fromPermanent.removeAttachment(aura.getId(), game); + creatureToAttachAura.addAttachment(aura.getId(), game); + return true; + } + } + } + return true; + } + + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CrushOfWurms.java b/Mage.Sets/src/mage/cards/c/CrushOfWurms.java new file mode 100644 index 00000000000..f6f671d191c --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrushOfWurms.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 mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TimingRule; +import mage.game.permanent.token.WurmToken; + +import java.util.UUID; + +/** + * @author JRHerlehy + */ +public class CrushOfWurms extends CardImpl { + + public CrushOfWurms(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{G}{G}{G}"); + + + // Put three 6/6 green Wurm creature tokens onto the battlefield. + this.getSpellAbility().addEffect(new CreateTokenEffect(new WurmToken(), 3)); + // Flashback {9}{G}{G}{G} + this.addAbility(new FlashbackAbility(new ManaCostsImpl("{9}{G}{G}{G}"), TimingRule.SORCERY)); + } + + public CrushOfWurms(final CrushOfWurms card) { + super(card); + } + + @Override + public CrushOfWurms copy() { + return new CrushOfWurms(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/Disallow.java b/Mage.Sets/src/mage/cards/d/Disallow.java new file mode 100644 index 00000000000..a938a69e69d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Disallow.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.d; + +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetStackObject; + +import java.util.UUID; + +/** + * @author JRHerlehy + */ +public class Disallow extends CardImpl { + + public Disallow(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}"); + + + // Counter target spell, activated ability, or triggered ability. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetStackObject()); + } + + public Disallow(final Disallow card) { + super(card); + } + + @Override + public Disallow copy() { + return new Disallow(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java b/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java index 4bbee99f28d..363b9184176 100644 --- a/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java +++ b/Mage.Sets/src/mage/cards/e/EpharaGodOfThePolis.java @@ -71,7 +71,7 @@ public class EpharaGodOfThePolis extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // At the beginning of each upkeep, if you had another creature enter the battlefield under your control last turn, draw a card. this.addAbility(new ConditionalTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), TargetController.ANY, false), + new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), TargetController.ANY, false, false), HadAnotherCreatureEnterTheBattlefieldCondition.getInstance(), "At the beginning of each upkeep, if you had another creature enter the battlefield under your control last turn, draw a card."), new PermanentsEnteredBattlefieldWatcher()); diff --git a/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java b/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java index c4628b8d6bf..a97a36e2e44 100644 --- a/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java +++ b/Mage.Sets/src/mage/cards/e/EvolutionaryLeap.java @@ -28,25 +28,17 @@ package mage.cards.e; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.players.Library; -import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; /** @@ -56,10 +48,10 @@ import mage.target.common.TargetControlledCreaturePermanent; public class EvolutionaryLeap extends CardImpl { public EvolutionaryLeap(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); // {G}, Sacrifice a creature: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EvolutionaryLeapEffect(), new ManaCostsImpl("{G}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard()), new ManaCostsImpl("{G}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature")))); this.addAbility(ability); } @@ -73,62 +65,3 @@ public class EvolutionaryLeap extends CardImpl { return new EvolutionaryLeap(this); } } - -class EvolutionaryLeapEffect extends OneShotEffect { - - private static final FilterCreatureCard filter = new FilterCreatureCard(); - - public EvolutionaryLeapEffect() { - super(Outcome.ReturnToHand); - this.staticText = "reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order"; - } - - public EvolutionaryLeapEffect(final EvolutionaryLeapEffect effect) { - super(effect); - } - - @Override - public EvolutionaryLeapEffect copy() { - return new EvolutionaryLeapEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null && controller.getLibrary().size() > 0) { - Cards cards = new CardsImpl(); - Library library = controller.getLibrary(); - Card card = null; - do { - card = library.removeFromTop(game); - if (card != null) { - cards.add(card); - } - } while (library.size() > 0 && card != null && !filter.match(card, game)); - // reveal cards - if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getIdName(), cards, game); - if (filter.match(card, game)) { - // put creature card in hand - controller.moveCards(card, Zone.HAND, source, game); - // remove it from revealed card list - cards.remove(card); - } - // Put the rest on the bottom of your library in a random order - Cards randomOrder = new CardsImpl(); - while (cards.size() > 0) { - card = cards.getRandom(game); - if (card != null) { - cards.remove(card); - randomOrder.add(card); - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.HAND, false, false); - } - } - controller.putCardsOnBottomOfLibrary(randomOrder, game, source, false); - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/e/Expropriate.java b/Mage.Sets/src/mage/cards/e/Expropriate.java new file mode 100644 index 00000000000..fefd82a3c53 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/Expropriate.java @@ -0,0 +1,191 @@ +/* + * 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 mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileSpellEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.predicate.other.OwnerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.turn.TurnMod; +import mage.players.Player; +import mage.players.Players; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author JRHerlehy + */ +public class Expropriate extends CardImpl { + + public Expropriate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{7}{U}{U}"); + + // Council's dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it. Exile Expropriate + this.getSpellAbility().addEffect(new ExpropriateDilemmaEffect()); + this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); + } + + public Expropriate(final Expropriate card) { + super(card); + } + + @Override + public Expropriate copy() { + return new Expropriate(this); + } +} + +class ExpropriateDilemmaEffect extends OneShotEffect { + + public ExpropriateDilemmaEffect() { + super(Outcome.Benefit); + this.staticText = "Council's dilemma — Starting with you, each player votes for time or money. For each time vote, take an extra turn after this one. For each money vote, choose a permanent owned by the voter and gain control of it."; + } + + public ExpropriateDilemmaEffect(final ExpropriateDilemmaEffect effect) { + super(effect); + } + + public ExpropriateDilemmaEffect(Outcome outcome) { + super(outcome); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + //If not controller, exit out here and do not vote. + if (controller == null) return false; + + int timeCount = 0, moneyCount = 0; + Players moneyVoters = new Players(); + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.Benefit, "Choose time?", source, game)) { + timeCount++; + game.informPlayers(player.getName() + " has voted for time"); + } else { + moneyCount++; + moneyVoters.addPlayer(player); + game.informPlayers(player.getName() + " has voted for money"); + } + } + } + + if (timeCount > 0) { + if (timeCount == 1) { + game.informPlayers(controller.getName() + " will take an extra turn"); + } else { + game.informPlayers(controller.getName() + " will take " + timeCount + " extra turns"); + } + + do { + game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false)); + timeCount--; + } while (timeCount > 0); + } + + if (moneyCount > 0) { + List chosenCards = new ArrayList<>(); + + for (UUID playerId : moneyVoters.keySet()) { + FilterPermanent filter = new FilterPermanent("permanent owned by " + game.getPlayer(playerId).getName()); + filter.add(new OwnerIdPredicate(playerId)); + + Target target = new TargetPermanent(filter); + target.setNotTarget(true); + + if (controller.choose(Outcome.GainControl, target, source.getSourceId(), game)) { + Permanent targetPermanent = game.getPermanent(target.getFirstTarget()); + + if (targetPermanent != null) chosenCards.add(targetPermanent); + } + } + + for (Permanent permanent : chosenCards) { + ContinuousEffect effect = new ExpropriateControlEffect(controller.getId()); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + game.informPlayers(controller.getName() + " gained control of " + permanent.getName() + " owned by " + game.getPlayer(permanent.getOwnerId()).getName()); + } + } //End moneyCount if statement + + return true; + } + + @Override + public ExpropriateDilemmaEffect copy() { + return new ExpropriateDilemmaEffect(this); + } + +} + +class ExpropriateControlEffect extends ContinuousEffectImpl { + + private UUID controllerId; + + public ExpropriateControlEffect(UUID controllerId) { + super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controllerId = controllerId; + } + + public ExpropriateControlEffect(final ExpropriateControlEffect effect) { + super(effect); + this.controllerId = effect.controllerId; + } + + @Override + public ExpropriateControlEffect copy() { + return new ExpropriateControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); + if (permanent != null && controllerId != null) { + return permanent.changeControllerId(controllerId, game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/j/JazalGoldmane.java b/Mage.Sets/src/mage/cards/j/JazalGoldmane.java index 7c4b17d9020..84a1a8f3112 100644 --- a/Mage.Sets/src/mage/cards/j/JazalGoldmane.java +++ b/Mage.Sets/src/mage/cards/j/JazalGoldmane.java @@ -49,7 +49,7 @@ import mage.filter.common.FilterAttackingCreature; public class JazalGoldmane extends CardImpl { public JazalGoldmane(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.supertype.add("Legendary"); this.subtype.add("Cat"); this.subtype.add("Warrior"); @@ -63,7 +63,7 @@ public class JazalGoldmane extends CardImpl { DynamicValue xValue = new AttackingCreatureCount("the number of attacking creatures"); this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, - new BoostControlledEffect(xValue, xValue , Duration.EndOfTurn, new FilterAttackingCreature("Attacking creatures"), false), + new BoostControlledEffect(xValue, xValue, Duration.EndOfTurn, new FilterAttackingCreature("Attacking creatures"), false, true), new ManaCostsImpl("{3}{W}{W}"))); } diff --git a/Mage.Sets/src/mage/cards/l/LieutenantsOfTheGuard.java b/Mage.Sets/src/mage/cards/l/LieutenantsOfTheGuard.java new file mode 100644 index 00000000000..9290e927f14 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LieutenantsOfTheGuard.java @@ -0,0 +1,126 @@ +/* + * 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 mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.SoldierToken; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author JRHerlehy + */ +public class LieutenantsOfTheGuard extends CardImpl { + + public LieutenantsOfTheGuard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}"); + + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Council's dilemma — When Lieutenants of the Guard enters the battlefield, starting with you, each player votes for strength or numbers. Put a +1/+1 counter on Lieutenants of the Guard for each strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LieutenantsOfTheGuardDilemmaEffect(), false, "Council's dilemma — ")); + } + + public LieutenantsOfTheGuard(final LieutenantsOfTheGuard card) { + super(card); + } + + @Override + public LieutenantsOfTheGuard copy() { + return new LieutenantsOfTheGuard(this); + } +} + +class LieutenantsOfTheGuardDilemmaEffect extends OneShotEffect { + public LieutenantsOfTheGuardDilemmaEffect() { + super(Outcome.Benefit); + this.staticText = "starting with you, each player votes for strength or numbers. Put a +1/+1 counter on {this} for each strength vote and put a 1/1 white Soldier creature token onto the battlefield for each numbers vote."; + } + + public LieutenantsOfTheGuardDilemmaEffect(final LieutenantsOfTheGuardDilemmaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + //If no controller, exit out here and do not vote. + if (controller == null) return false; + + int strengthCount = 0, numbersCount = 0; + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.BoostCreature, "Choose strength?", source, game)) { + strengthCount++; + game.informPlayers(player.getName() + " has voted for strength"); + } else { + numbersCount++; + game.informPlayers(player.getName() + " has voted for numbers"); + } + } + } + + Permanent permanent = game.getPermanent(source.getSourceId()); + + //If strength received zero votes or the permanent is no longer on the battlefield, do not attempt to put P1P1 counters on it. + if (strengthCount > 0 && permanent != null) permanent.addCounters(CounterType.P1P1.createInstance(strengthCount), game); + + //Create the appropriate number of tokens for the controller. + if (numbersCount > 0) { + Effect tokenEffect = new CreateTokenEffect(new SoldierToken(), numbersCount); + tokenEffect.apply(game, source); + } + + return true; + } + + @Override + public LieutenantsOfTheGuardDilemmaEffect copy() { + return new LieutenantsOfTheGuardDilemmaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MessengerJays.java b/Mage.Sets/src/mage/cards/m/MessengerJays.java new file mode 100644 index 00000000000..3cc5174e3d8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MessengerJays.java @@ -0,0 +1,128 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author JRHerlehy + */ +public class MessengerJays extends CardImpl { + + public MessengerJays(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add("Bird"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Council's dilemma — When Messenger Jays enters the battlefield, starting with you, each player votes for feather or quill. Put a +1/+1 counter on Messenger Jays for each feather vote and draw a card for each quill vote. For each card drawn this way, discard a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new MessengerJaysDilemmaEffect(), false, "Council's dilemma — ")); + } + + public MessengerJays(final MessengerJays card) { + super(card); + } + + @Override + public MessengerJays copy() { + return new MessengerJays(this); + } +} + +class MessengerJaysDilemmaEffect extends OneShotEffect { + + public MessengerJaysDilemmaEffect() { + super(Outcome.Benefit); + this.staticText = "starting with you, each player votes for feather or quill. Put a +1/+1 counter on {this} for each feather vote and draw a card for each quill vote. For each card drawn this way, discard a card."; + } + + public MessengerJaysDilemmaEffect(final MessengerJaysDilemmaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + //If no controller, exit out here and do not vote. + if (controller == null) return false; + + int featherCount = 0, quillCount = 0; + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.BoostCreature, "Choose feather?", source, game)) { + featherCount++; + game.informPlayers(player.getName() + " has voted for feather"); + } else { + quillCount++; + game.informPlayers(player.getName() + " has voted for quill"); + } + } + } + + Permanent permanent = game.getPermanent(source.getSourceId()); + + //If feathers received zero votes or the permanent is no longer on the battlefield, do not attempt to put P1P1 counter on it. + if (featherCount > 0 && permanent != null) permanent.addCounters(CounterType.P1P1.createInstance(featherCount), game); + + //Only let the controller loot the appropriate amount of cards if it was voted for. + if (quillCount > 0) { + Effect lootCardsEffect = new DrawDiscardControllerEffect(quillCount, quillCount); + lootCardsEffect.apply(game, source); + } + + return true; + } + + @Override + public MessengerJaysDilemmaEffect copy() { + return new MessengerJaysDilemmaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/ObNixilisUnshackled.java b/Mage.Sets/src/mage/cards/o/ObNixilisUnshackled.java index 68016bc1970..29c1344144e 100644 --- a/Mage.Sets/src/mage/cards/o/ObNixilisUnshackled.java +++ b/Mage.Sets/src/mage/cards/o/ObNixilisUnshackled.java @@ -47,7 +47,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.players.Player; -import mage.target.TargetPlayer; +import mage.target.targetpointer.FixedTarget; /** * @@ -110,8 +110,7 @@ class ObNixilisUnshackledTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Player controller = game.getPlayer(this.getControllerId()); if (controller != null && game.isOpponent(controller, event.getTargetId())) { - this.addTarget(new TargetPlayer()); - getTargets().get(0).add(event.getPlayerId(), game); + getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java b/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java index 1ace8136d5c..19a2581e677 100644 --- a/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java +++ b/Mage.Sets/src/mage/cards/o/ObzedatGhostCouncil.java @@ -49,7 +49,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -64,7 +63,7 @@ import mage.target.common.TargetOpponent; public class ObzedatGhostCouncil extends CardImpl { public ObzedatGhostCouncil(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}{B}{B}"); this.subtype.add("Spirit"); this.subtype.add("Advisor"); this.supertype.add("Legendary"); @@ -175,14 +174,15 @@ class ObzedatGhostCouncilReturnEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); if (card != null) { - ExileZone currentZone = game.getState().getExile().getExileZone(source.getSourceId()); - // return it only from the own exile zone - if (currentZone != null && currentZone.size() > 0) { + Zone zone = game.getState().getZone(source.getSourceId()); + // return it from every public zone - http://www.mtgsalvation.com/forums/magic-fundamentals/magic-rulings/magic-rulings-archives/513186-obzedat-gc-as-edh-commander + if (!zone.equals(Zone.BATTLEFIELD) && !zone.equals(Zone.LIBRARY) && !zone.equals(Zone.HAND)) { Player owner = game.getPlayer(card.getOwnerId()); - if (owner != null && owner.moveCards(card, Zone.BATTLEFIELD, source, game)) { - return true; + if (owner != null) { + owner.moveCards(card, Zone.BATTLEFIELD, source, game); } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/o/Ophiomancer.java b/Mage.Sets/src/mage/cards/o/Ophiomancer.java index ddf9e606cab..9cd6cab47d1 100644 --- a/Mage.Sets/src/mage/cards/o/Ophiomancer.java +++ b/Mage.Sets/src/mage/cards/o/Ophiomancer.java @@ -49,7 +49,7 @@ import mage.game.permanent.token.Token; public class Ophiomancer extends CardImpl { public Ophiomancer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); this.subtype.add("Human"); this.subtype.add("Shaman"); @@ -58,7 +58,7 @@ public class Ophiomancer extends CardImpl { // At the beginning of each upkeep, if you control no Snakes, create a 1/1 black Snake creature token with deathtouch. this.addAbility(new ConditionalTriggeredAbility( - new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new OphiomancerSnakeToken()), TargetController.ANY, false), + new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new OphiomancerSnakeToken()), TargetController.ANY, false, false), new PermanentsOnTheBattlefieldCondition(new FilterCreaturePermanent("Snake", "no Snakes"), PermanentsOnTheBattlefieldCondition.CountType.EQUAL_TO, 0), "At the beginning of each upkeep, if you control no Snakes, create a 1/1 black Snake creature token with deathtouch.")); } diff --git a/Mage.Sets/src/mage/cards/o/OrchardElemental.java b/Mage.Sets/src/mage/cards/o/OrchardElemental.java new file mode 100644 index 00000000000..2a4c3e4bc80 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OrchardElemental.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.o; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author JRHerlehy + */ +public class OrchardElemental extends CardImpl { + + public OrchardElemental(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); + + this.subtype.add("Elemental"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Council's dilemma &mdash When Orchard Elemental enters the battlefield, starting with you, each player votes for sprout or harvest. Put two +1/+1 counters on Orchard Elemental for each sprout vote. You gain 3 life for each harvest vote. + this.addAbility(new EntersBattlefieldTriggeredAbility(new OrchardElementalDilemmaEffect(), false, "Council's dilemma — ")); + } + + public OrchardElemental(final OrchardElemental card) { + super(card); + } + + @Override + public OrchardElemental copy() { + return new OrchardElemental(this); + } +} + +class OrchardElementalDilemmaEffect extends OneShotEffect { + + public OrchardElementalDilemmaEffect() { + super(Outcome.Benefit); + this.staticText = "starting with you, each player votes for sprout or harvest. Put two +1/+1 counters on Orchard Elemental for each sprout vote. You gain 3 life for each harvest vote"; + } + + public OrchardElementalDilemmaEffect(final OrchardElementalDilemmaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + if (controller == null) return false; + + int sproutCount = 0, harvestCount = 0; + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.BoostCreature, "Choose sprout?", source, game)) { + sproutCount++; + game.informPlayers(player.getName() + " has voted for sprout"); + } else { + harvestCount++; + game.informPlayers(player.getName() + " has voted for harvest"); + } + } + } + + Permanent permanent = game.getPermanent(source.getSourceId()); + + if (sproutCount > 0 && permanent != null) permanent.addCounters(CounterType.P1P1.createInstance(sproutCount * 2), game); + + if (harvestCount > 0) { + Effect gainLifeEffect = new GainLifeEffect(harvestCount * 3); + gainLifeEffect.apply(game, source); + } + + return true; + } + + @Override + public OrchardElementalDilemmaEffect copy() { + return new OrchardElementalDilemmaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OvalchaseDaredevil.java b/Mage.Sets/src/mage/cards/o/OvalchaseDaredevil.java index b3256b8ecd1..9d51943a0d6 100644 --- a/Mage.Sets/src/mage/cards/o/OvalchaseDaredevil.java +++ b/Mage.Sets/src/mage/cards/o/OvalchaseDaredevil.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterPermanent; @@ -53,14 +54,14 @@ public class OvalchaseDaredevil extends CardImpl { } public OvalchaseDaredevil(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); this.subtype.add("Human"); this.subtype.add("Pilot"); this.power = new MageInt(4); this.toughness = new MageInt(2); // Whenever an artifact enters the battlefield under your control, you may return Ovalchase Daredevil from your graveyard to your hand. - this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), filter, true)); + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), filter, true, SetTargetPointer.NONE, null, true)); } public OvalchaseDaredevil(final OvalchaseDaredevil card) { diff --git a/Mage.Sets/src/mage/cards/p/PiasRevolution.java b/Mage.Sets/src/mage/cards/p/PiasRevolution.java new file mode 100644 index 00000000000..b9d8c629a70 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiasRevolution.java @@ -0,0 +1,160 @@ +/* + * 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.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.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author Styxo + */ +public class PiasRevolution extends CardImpl { + + public PiasRevolution(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + + // Whenever a nontoken artifact is put into your graveyard from the battlefield, return that card to your hand unless target opponent has Pia's Revolution deal 3 damage to him or her. + Ability ability = new PiasRevolutionTriggeredAbility(); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public PiasRevolution(final PiasRevolution card) { + super(card); + } + + @Override + public PiasRevolution copy() { + return new PiasRevolution(this); + } +} + +class PiasRevolutionReturnEffect extends OneShotEffect { + + public PiasRevolutionReturnEffect() { + super(Outcome.Benefit); + this.staticText = "return that card to your hand unless target opponent has {this} deal 3 damage to him or her"; + } + + public PiasRevolutionReturnEffect(final PiasRevolutionReturnEffect effect) { + super(effect); + } + + @Override + public PiasRevolutionReturnEffect copy() { + return new PiasRevolutionReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + UUID permanentId = (UUID) this.getValue("permanentId"); + Permanent permanent = game.getPermanentOrLKIBattlefield(permanentId); + if (permanent != null) { + Player opponent = game.getPlayer(source.getFirstTarget()); + if (opponent != null) { + if (opponent.chooseUse(outcome, new StringBuilder("Have Pia's Revolution deal 3 damage to you to prevent that ").append(permanent.getLogName()).append(" returns to ").append(controller.getLogName()).append("'s hand?").toString(), source, game)) { + opponent.damage(3, source.getId(), game, false, true); + } else { + if (game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + controller.moveCards(game.getCard(permanentId), Zone.HAND, source, game); + } + } + } + } + return true; + } + return false; + } +} + +class PiasRevolutionTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterArtifactPermanent filter = new FilterArtifactPermanent(); + + static { + filter.add(Predicates.not(new TokenPredicate())); + } + + public PiasRevolutionTriggeredAbility() { + super(Zone.BATTLEFIELD, new PiasRevolutionReturnEffect(), false); + } + + public PiasRevolutionTriggeredAbility(PiasRevolutionTriggeredAbility ability) { + super(ability); + } + + @Override + public PiasRevolutionTriggeredAbility copy() { + return new PiasRevolutionTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone().equals(Zone.BATTLEFIELD) && zEvent.getToZone().equals(Zone.GRAVEYARD)) { + Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); + if (permanent != null && filter.match(permanent, sourceId, controllerId, game)) { + for (Effect effect : this.getEffects()) { + effect.setValue("permanentId", event.getTargetId()); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a nontoken artifact is put into your graveyard from the battlefield, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/cards/p/ProtectorOfTheCrown.java b/Mage.Sets/src/mage/cards/p/ProtectorOfTheCrown.java index e391d27a759..526e6d329b4 100644 --- a/Mage.Sets/src/mage/cards/p/ProtectorOfTheCrown.java +++ b/Mage.Sets/src/mage/cards/p/ProtectorOfTheCrown.java @@ -55,6 +55,7 @@ public class ProtectorOfTheCrown extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); this.subtype.add("Giant"); + this.subtype.add("Soldier"); this.power = new MageInt(2); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/s/Seance.java b/Mage.Sets/src/mage/cards/s/Seance.java index b612367fb7b..8a5794460dd 100644 --- a/Mage.Sets/src/mage/cards/s/Seance.java +++ b/Mage.Sets/src/mage/cards/s/Seance.java @@ -56,7 +56,7 @@ import mage.target.targetpointer.FixedTargets; public class Seance extends CardImpl { public Seance(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); // At the beginning of each upkeep, you may exile target creature card from your graveyard. If you do, create a token that's a copy of that card except it's a Spirit in addition to its other types. Exile it at the beginning of the next end step. Ability ability = new BeginningOfUpkeepTriggeredAbility(new SeanceEffect(), TargetController.ANY, true); @@ -95,16 +95,15 @@ class SeanceEffect extends OneShotEffect { Card card = game.getCard(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { - if (controller.moveCards(card, Zone.EXILED, source, game)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); - effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); - effect.setAdditionalSubType("Spirit"); - effect.apply(game, source); - ExileTargetEffect exileEffect = new ExileTargetEffect(); - exileEffect.setTargetPointer(new FixedTargets(effect.getAddedPermanent(), game)); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } + controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place + PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); + effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + effect.setAdditionalSubType("Spirit"); + effect.apply(game, source); + ExileTargetEffect exileEffect = new ExileTargetEffect(); + exileEffect.setTargetPointer(new FixedTargets(effect.getAddedPermanent(), game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); return true; } diff --git a/Mage.Sets/src/mage/cards/s/SelvalasStampede.java b/Mage.Sets/src/mage/cards/s/SelvalasStampede.java new file mode 100644 index 00000000000..f8a86470d97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SelvalasStampede.java @@ -0,0 +1,133 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterPermanentCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author JRHerlehy + */ +public class SelvalasStampede extends CardImpl { + + public SelvalasStampede(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}"); + + + // Council's dilemma &mdash Starting with you, each player votes for wild or free. Reveal cards from the top of your library until you reveal a creature card for each wild vote. Put those creature cards onto the battlefield, then shuffle the rest into your library. You may put a permanent card from your hand onto the battlefield for each free vote. + this.getSpellAbility().addEffect(new SelvalasStampedeDilemmaEffect()); + } + + public SelvalasStampede(final SelvalasStampede card) { + super(card); + } + + @Override + public SelvalasStampede copy() { + return new SelvalasStampede(this); + } +} + +class SelvalasStampedeDilemmaEffect extends OneShotEffect { + + public SelvalasStampedeDilemmaEffect() { + super(Outcome.Benefit); + this.staticText = "Council's dilemma — Starting with you, each player votes for wild or free. Reveal cards from the top of your library until you reveal a creature card for each wild vote. Put those creature cards onto the battlefield, then shuffle the rest into your library. You may put a permanent card from your hand onto the battlefield for each free vote"; + } + + public SelvalasStampedeDilemmaEffect(final SelvalasStampedeDilemmaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + + //If no controller, exit here and do not vote. + if (controller == null) return false; + + int wildCount = 0, freeCount = 0; + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.chooseUse(Outcome.Benefit, "Choose wild?", source, game)) { + wildCount++; + game.informPlayers(player.getName() + " has voted for wild"); + } else { + freeCount++; + game.informPlayers(player.getName() + " has voted for free"); + } + } + } + + if (wildCount > 0) { + Cards revealedCards = new CardsImpl(); + + while (wildCount > 0 && controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); + if (card.getCardType().contains(CardType.CREATURE)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + wildCount--; + } else { + revealedCards.add(card); + } + } + + controller.revealCards("Selvala's Stampede", revealedCards, game); + controller.moveCards(revealedCards, Zone.LIBRARY, source, game); + controller.shuffleLibrary(source, game); + } + + if (freeCount > 0) { + TargetCardInHand target = new TargetCardInHand(0, freeCount, new FilterPermanentCard("permanent cards")); + if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + controller.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); + } + } + + return true; + } + + @Override + public SelvalasStampedeDilemmaEffect copy() { + return new SelvalasStampedeDilemmaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpectersShroud.java b/Mage.Sets/src/mage/cards/s/SpectersShroud.java new file mode 100644 index 00000000000..532fd246442 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpectersShroud.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.s; + +import java.util.UUID; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; + + +/** + * + * @author Pete Rossi + */ +public class SpectersShroud extends CardImpl { + + public SpectersShroud(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.subtype.add("Equipment"); + + // Equipped creature gets +1/+0. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0))); + // Whenever equipped creature deals combat damage to a player, that player discards a card. + this.addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new DiscardTargetEffect(1), "equipped creature", false, true, true)); + // Equip {1} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(1))); + } + + public SpectersShroud(final SpectersShroud card) { + super(card); + } + + @Override + public SpectersShroud copy() { + return new SpectersShroud(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SwordsToPlowshares.java b/Mage.Sets/src/mage/cards/s/SwordsToPlowshares.java index c8dd2cd0cdc..d821b122739 100644 --- a/Mage.Sets/src/mage/cards/s/SwordsToPlowshares.java +++ b/Mage.Sets/src/mage/cards/s/SwordsToPlowshares.java @@ -27,19 +27,15 @@ */ package mage.cards.s; -import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.SwordsToPlowsharesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.constants.CardType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author jonubuu @@ -67,33 +63,3 @@ public class SwordsToPlowshares extends CardImpl { return new SwordsToPlowshares(this); } } - -class SwordsToPlowsharesEffect extends OneShotEffect { - - public SwordsToPlowsharesEffect() { - super(Outcome.GainLife); - staticText = "Its controller gains life equal to its power"; - } - - public SwordsToPlowsharesEffect(final SwordsToPlowsharesEffect effect) { - super(effect); - } - - @Override - public SwordsToPlowsharesEffect copy() { - return new SwordsToPlowsharesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - Player player = game.getPlayer(permanent.getControllerId()); - if (player != null) { - player.gainLife(permanent.getPower().getValue(), game); - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TezzeretMasterOfMetal.java b/Mage.Sets/src/mage/cards/t/TezzeretMasterOfMetal.java new file mode 100644 index 00000000000..9d5cfad6b40 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TezzeretMasterOfMetal.java @@ -0,0 +1,155 @@ +/* + * 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.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterArtifactCard; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author Styxo + */ +public class TezzeretMasterOfMetal extends CardImpl { + + public TezzeretMasterOfMetal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{U}{B}"); + this.subtype.add("Tezzeret"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); + + // +1: Reveal cards from the top of your library until you reveal an artifact card. Put that card into your hand and the rest on the bottom of your library in a random order. + this.addAbility(new LoyaltyAbility(new RevealCardsFromLibraryUntilEffect(new FilterArtifactCard()), 1)); + + // -3: Target opponent loses life equal to the number of artifacts you control. + Ability ability = new LoyaltyAbility(new LoseLifeTargetEffect(new PermanentsOnBattlefieldCount(new FilterControlledArtifactPermanent())), -3); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + + // -8: Gain control of all artifacts and creatures target opponent controls. + ability = new LoyaltyAbility(new TezzeretMasterOfMetalEffect(), -8); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public TezzeretMasterOfMetal(final TezzeretMasterOfMetal card) { + super(card); + } + + @Override + public TezzeretMasterOfMetal copy() { + return new TezzeretMasterOfMetal(this); + } +} + +class TezzeretMasterOfMetalEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent("artifacts and creatures"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ARTIFACT))); + } + + public TezzeretMasterOfMetalEffect() { + super(Outcome.GainControl); + this.staticText = "Gain control of all artifacts and creatures target opponent controls"; + } + + public TezzeretMasterOfMetalEffect(final TezzeretMasterOfMetalEffect effect) { + super(effect); + } + + @Override + public TezzeretMasterOfMetalEffect copy() { + return new TezzeretMasterOfMetalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = game.getBattlefield().getAllActivePermanents(filter, targetPointer.getFirst(game, source), game); + for (Permanent permanent : permanents) { + ContinuousEffect effect = new TibaltTheFiendBloodedControlEffect(source.getControllerId()); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); + } + return true; + } +} + +class TezzeretMasterOfMetalControlEffect extends ContinuousEffectImpl { + + private final UUID controllerId; + + public TezzeretMasterOfMetalControlEffect(UUID controllerId) { + super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controllerId = controllerId; + } + + public TezzeretMasterOfMetalControlEffect(final TezzeretMasterOfMetalControlEffect effect) { + super(effect); + this.controllerId = effect.controllerId; + } + + @Override + public TezzeretMasterOfMetalControlEffect copy() { + return new TezzeretMasterOfMetalControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); + if (permanent != null && controllerId != null) { + return permanent.changeControllerId(controllerId, game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TrenchWurm.java b/Mage.Sets/src/mage/cards/t/TrenchWurm.java index 9d86f4cdc59..5b1cc8c497d 100644 --- a/Mage.Sets/src/mage/cards/t/TrenchWurm.java +++ b/Mage.Sets/src/mage/cards/t/TrenchWurm.java @@ -27,10 +27,10 @@ */ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; @@ -39,6 +39,8 @@ import mage.constants.CardType; import mage.constants.Zone; import mage.target.common.TargetNonBasicLandPermanent; +import java.util.UUID; + /** * * @author michael.napoleon@gmail.com @@ -54,6 +56,7 @@ public class TrenchWurm extends CardImpl { // {2}{R}, {tap}: Destroy target nonbasic land. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{R}")); ability.addTarget(new TargetNonBasicLandPermanent()); + ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TrophyMage.java b/Mage.Sets/src/mage/cards/t/TrophyMage.java new file mode 100644 index 00000000000..6345d5c5d22 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrophyMage.java @@ -0,0 +1,79 @@ +/* + * 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.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.SearchEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.Filter; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author Styxo + */ +public class TrophyMage extends CardImpl { + + private static final FilterCard filter = new FilterCard("an artifact card with converted mana cost 3"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, 3)); + } + + public TrophyMage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(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. + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + SearchEffect effect = new SearchLibraryPutInHandEffect(target, true, true); + this.addAbility(new EntersBattlefieldTriggeredAbility(effect, true)); + } + + public TrophyMage(final TrophyMage card) { + super(card); + } + + @Override + public TrophyMage copy() { + return new TrophyMage(this); + } +} diff --git a/Mage.Sets/src/mage/cards/y/YaheenisExpertise.java b/Mage.Sets/src/mage/cards/y/YaheenisExpertise.java new file mode 100644 index 00000000000..0c21a325020 --- /dev/null +++ b/Mage.Sets/src/mage/cards/y/YaheenisExpertise.java @@ -0,0 +1,124 @@ +/* + * 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.y; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.Filter; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInHand; + +/** + * + * @author fireshoes + */ +public class YaheenisExpertise extends CardImpl { + + public YaheenisExpertise(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); + + + // All creatures get -3/-3 until end of turn. + getSpellAbility().addEffect(new BoostAllEffect(-3, -3, Duration.EndOfTurn)); + + // You may cast a card with converted mana cost 3 or less from your hand without paying its mana cost. + getSpellAbility().addEffect(new YaheenisExpertiseCastEffect()); + } + + public YaheenisExpertise(final YaheenisExpertise card) { + super(card); + } + + @Override + public YaheenisExpertise copy() { + return new YaheenisExpertise(this); + } +} + +class YaheenisExpertiseCastEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("card with converted mana cost 3 or less from your hand"); + + static { + filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, 4)); + } + + public YaheenisExpertiseCastEffect() { + super(Outcome.PlayForFree); + this.staticText = "you may cast a card with converted mana cost 3 or less from your hand without paying its mana cost"; + } + + public YaheenisExpertiseCastEffect(final YaheenisExpertiseCastEffect effect) { + super(effect); + } + + @Override + public YaheenisExpertiseCastEffect copy() { + return new YaheenisExpertiseCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Target target = new TargetCardInHand(filter); + if (target.canChoose(source.getSourceId(), controller.getId(), game) && + controller.chooseUse(outcome, "Cast a card with converted mana cost 3 or less from your hand without paying its mana cost?", source, game)) { + Card cardToCast = null; + boolean cancel = false; + while (controller.canRespond() && !cancel) { + if (controller.chooseTarget(outcome, target, source, game)) { + cardToCast = game.getCard(target.getFirstTarget()); + if (cardToCast != null && cardToCast.getSpellAbility().canChooseTarget(game)) { + cancel = true; + } + } else { + cancel = true; + } + } + if (cardToCast != null) { + controller.cast(cardToCast.getSpellAbility(), game, true); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/AetherRevolt.java b/Mage.Sets/src/mage/sets/AetherRevolt.java index 6f3887a87d4..31e627366af 100644 --- a/Mage.Sets/src/mage/sets/AetherRevolt.java +++ b/Mage.Sets/src/mage/sets/AetherRevolt.java @@ -27,14 +27,16 @@ */ package mage.sets; -import java.util.ArrayList; -import java.util.List; 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; +import java.util.ArrayList; +import java.util.List; + /** * * @author fireshoes @@ -59,11 +61,16 @@ public class AetherRevolt extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; - /* The Masterpiece Series will exist at a rarity higher than mythic rare. For example, in Kaladesh, you will open a Kaladesh Inventions card roughly - 1 out of every 144 boosters. (Technically, the Kaladesh booster pack says the ratio is 1:2,160 cards.) This is slightly more often than opening a - premium mythic rare. These ratios may change for future sets. */ + this.maxCardNumberInBooster = 184; this.ratioBoosterSpecialLand = 144; this.parentSet = Kaladesh.getInstance(); + cards.add(new SetCardInfo("Ajani Unyielding", 127, Rarity.MYTHIC, mage.cards.a.AjaniUnyielding.class)); + cards.add(new SetCardInfo("Ajani, Valiant Protector", 185, Rarity.MYTHIC, mage.cards.a.AjaniValiantProtector.class)); + cards.add(new SetCardInfo("Disallow", 31, Rarity.RARE, mage.cards.d.Disallow.class)); + cards.add(new SetCardInfo("Tezzeret, Master of Metal", 190, Rarity.MYTHIC, mage.cards.t.TezzeretMasterOfMetal.class)); + cards.add(new SetCardInfo("Pia's Revolution", 91, Rarity.RARE, mage.cards.p.PiasRevolution.class)); + cards.add(new SetCardInfo("Trophy Mage", 48, Rarity.UNCOMMON, mage.cards.t.TrophyMage.class)); + cards.add(new SetCardInfo("Yaheeni's Expertise", 75, Rarity.RARE, mage.cards.y.YaheenisExpertise.class)); } @Override diff --git a/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java b/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java index f95cfadd065..cfec1c9f36e 100644 --- a/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java +++ b/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java @@ -1,234 +1,241 @@ -/* -* 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.SetType; -import mage.constants.Rarity; - -/** - * - * @author fireshoes - */ - -public class ConspiracyTakeTheCrown extends ExpansionSet { - - private static final ConspiracyTakeTheCrown fINSTANCE = new ConspiracyTakeTheCrown(); - - public static ConspiracyTakeTheCrown getInstance() { - return fINSTANCE; - } - - private ConspiracyTakeTheCrown() { - super("Conspiracy: Take the Crown", "CN2", ExpansionSet.buildDate(2016, 8, 26), SetType.SUPPLEMENTAL); - this.blockName = "Conspiracy"; - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Absorb Vis", 126, Rarity.COMMON, mage.cards.a.AbsorbVis.class)); - cards.add(new SetCardInfo("Adriana, Captain of the Guard", 73, Rarity.RARE, mage.cards.a.AdrianaCaptainOfTheGuard.class)); - cards.add(new SetCardInfo("Affa Guard Hound", 81, Rarity.UNCOMMON, mage.cards.a.AffaGuardHound.class)); - cards.add(new SetCardInfo("Akroan Hoplite", 197, Rarity.UNCOMMON, mage.cards.a.AkroanHoplite.class)); - cards.add(new SetCardInfo("Altar's Reap", 127, Rarity.COMMON, mage.cards.a.AltarsReap.class)); - cards.add(new SetCardInfo("Ascended Lawmage", 198, Rarity.UNCOMMON, mage.cards.a.AscendedLawmage.class)); - cards.add(new SetCardInfo("Avatar of Woe", 128, Rarity.MYTHIC, mage.cards.a.AvatarOfWoe.class)); - cards.add(new SetCardInfo("Beast Within", 174, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); - cards.add(new SetCardInfo("Berserk", 175, Rarity.MYTHIC, mage.cards.b.Berserk.class)); - cards.add(new SetCardInfo("Birds of Paradise", 176, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); - cards.add(new SetCardInfo("Blood-Toll Harpy", 129, Rarity.COMMON, mage.cards.b.BloodTollHarpy.class)); - cards.add(new SetCardInfo("Bonds of Quicksilver", 102, Rarity.COMMON, mage.cards.b.BondsOfQuicksilver.class)); - cards.add(new SetCardInfo("Bronze Sable", 208, Rarity.COMMON, mage.cards.b.BronzeSable.class)); - cards.add(new SetCardInfo("Brushstrider", 177, Rarity.UNCOMMON, mage.cards.b.Brushstrider.class)); - cards.add(new SetCardInfo("Burgeoning", 178, Rarity.RARE, mage.cards.b.Burgeoning.class)); - cards.add(new SetCardInfo("Burn Away", 151, Rarity.UNCOMMON, mage.cards.b.BurnAway.class)); - cards.add(new SetCardInfo("Burning Wish", 152, Rarity.RARE, mage.cards.b.BurningWish.class)); - cards.add(new SetCardInfo("Caller of Gales", 103, Rarity.COMMON, mage.cards.c.CallerOfGales.class)); - cards.add(new SetCardInfo("Canal Courier", 28, Rarity.COMMON, mage.cards.c.CanalCourier.class)); - cards.add(new SetCardInfo("Carnage Gladiator", 199, Rarity.UNCOMMON, mage.cards.c.CarnageGladiator.class)); - cards.add(new SetCardInfo("Charmbreaker Devils", 153, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class)); - cards.add(new SetCardInfo("Child of Night", 130, Rarity.COMMON, mage.cards.c.ChildOfNight.class)); - cards.add(new SetCardInfo("Cloaked Siren", 104, Rarity.COMMON, mage.cards.c.CloakedSiren.class)); - cards.add(new SetCardInfo("Coiling Oracle", 200, Rarity.UNCOMMON, mage.cards.c.CoilingOracle.class)); - cards.add(new SetCardInfo("Coordinated Assault", 154, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class)); - cards.add(new SetCardInfo("Copperhorn Scout", 179, Rarity.COMMON, mage.cards.c.CopperhornScout.class)); - cards.add(new SetCardInfo("Covenant of Minds", 105, Rarity.RARE, mage.cards.c.CovenantOfMinds.class)); - cards.add(new SetCardInfo("Crown-Hunter Hireling", 50, Rarity.COMMON, mage.cards.c.CrownHunterHireling.class)); - cards.add(new SetCardInfo("Custodi Lich", 41, Rarity.RARE, mage.cards.c.CustodiLich.class)); - cards.add(new SetCardInfo("Daretti, Ingenious Iconoclast", 74, Rarity.MYTHIC, mage.cards.d.DarettiIngeniousIconoclast.class)); - cards.add(new SetCardInfo("Death Wind", 131, Rarity.COMMON, mage.cards.d.DeathWind.class)); - cards.add(new SetCardInfo("Deceiver Exarch", 106, Rarity.UNCOMMON, mage.cards.d.DeceiverExarch.class)); - cards.add(new SetCardInfo("Deputized Protester", 51, Rarity.COMMON, mage.cards.d.DeputizedProtester.class)); - cards.add(new SetCardInfo("Desertion", 107, Rarity.RARE, mage.cards.d.Desertion.class)); - cards.add(new SetCardInfo("Diabolic Tutor", 132, Rarity.UNCOMMON, mage.cards.d.DiabolicTutor.class)); - cards.add(new SetCardInfo("Disenchant", 82, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Dismiss", 108, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); - cards.add(new SetCardInfo("Divination", 109, Rarity.COMMON, mage.cards.d.Divination.class)); - cards.add(new SetCardInfo("Domesticated Hydra", 63, Rarity.UNCOMMON, mage.cards.d.DomesticatedHydra.class)); - cards.add(new SetCardInfo("Doomed Traveler", 83, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); - cards.add(new SetCardInfo("Dragonlair Spider", 201, Rarity.RARE, mage.cards.d.DragonlairSpider.class)); - cards.add(new SetCardInfo("Dread Statuary", 217, Rarity.UNCOMMON, mage.cards.d.DreadStatuary.class)); - cards.add(new SetCardInfo("Driver of the Dead", 133, Rarity.COMMON, mage.cards.d.DriverOfTheDead.class)); - cards.add(new SetCardInfo("Duskmantle Seer", 202, Rarity.RARE, mage.cards.d.DuskmantleSeer.class)); - cards.add(new SetCardInfo("Ember Beast", 155, Rarity.COMMON, mage.cards.e.EmberBeast.class)); - cards.add(new SetCardInfo("Entourage of Trest", 64, Rarity.COMMON, mage.cards.e.EntourageOfTrest.class)); - cards.add(new SetCardInfo("Evolving Wilds", 218, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); - cards.add(new SetCardInfo("Exotic Orchard", 219, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); - cards.add(new SetCardInfo("Explosive Vegetation", 180, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); - cards.add(new SetCardInfo("Fade into Antiquity", 181, Rarity.COMMON, mage.cards.f.FadeIntoAntiquity.class)); - cards.add(new SetCardInfo("Faith's Reward", 84, Rarity.RARE, mage.cards.f.FaithsReward.class)); - cards.add(new SetCardInfo("Farbog Boneflinger", 134, Rarity.UNCOMMON, mage.cards.f.FarbogBoneflinger.class)); - cards.add(new SetCardInfo("Festergloom", 135, Rarity.COMMON, mage.cards.f.Festergloom.class)); - cards.add(new SetCardInfo("Fiery Fall", 156, Rarity.COMMON, mage.cards.f.FieryFall.class)); - cards.add(new SetCardInfo("Flame Slash", 157, Rarity.COMMON, mage.cards.f.FlameSlash.class)); - cards.add(new SetCardInfo("Fleeting Distraction", 110, Rarity.COMMON, mage.cards.f.FleetingDistraction.class)); - cards.add(new SetCardInfo("Fleshbag Marauder", 136, Rarity.UNCOMMON, mage.cards.f.FleshbagMarauder.class)); - cards.add(new SetCardInfo("Followed Footsteps", 111, Rarity.RARE, mage.cards.f.FollowedFootsteps.class)); - cards.add(new SetCardInfo("Forgotten Ancient", 182, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); - cards.add(new SetCardInfo("Gang of Devils", 158, Rarity.UNCOMMON, mage.cards.g.GangOfDevils.class)); - cards.add(new SetCardInfo("Garrulous Sycophant", 43, Rarity.COMMON, mage.cards.g.GarrulousSycophant.class)); - cards.add(new SetCardInfo("Ghostly Possession", 85, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); - cards.add(new SetCardInfo("Ghostly Prison", 86, Rarity.UNCOMMON, mage.cards.g.GhostlyPrison.class)); - cards.add(new SetCardInfo("Gleam of Resistance", 87, Rarity.COMMON, mage.cards.g.GleamOfResistance.class)); - cards.add(new SetCardInfo("Goblin Balloon Brigade", 159, Rarity.COMMON, mage.cards.g.GoblinBalloonBrigade.class)); - cards.add(new SetCardInfo("Goblin Tunneler", 160, Rarity.COMMON, mage.cards.g.GoblinTunneler.class)); - cards.add(new SetCardInfo("Gods Willing", 88, Rarity.COMMON, mage.cards.g.GodsWilling.class)); - cards.add(new SetCardInfo("Gratuitous Violence", 161, Rarity.RARE, mage.cards.g.GratuitousViolence.class)); - cards.add(new SetCardInfo("Gruul War Chant", 203, Rarity.UNCOMMON, mage.cards.g.GruulWarChant.class)); - cards.add(new SetCardInfo("Guardian of the Gateless", 89, Rarity.UNCOMMON, mage.cards.g.GuardianOfTheGateless.class)); - cards.add(new SetCardInfo("Guttersnipe", 162, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class)); - cards.add(new SetCardInfo("Guul Draz Specter", 137, Rarity.RARE, mage.cards.g.GuulDrazSpecter.class)); - cards.add(new SetCardInfo("Hail of Arrows", 90, Rarity.UNCOMMON, mage.cards.h.HailOfArrows.class)); - cards.add(new SetCardInfo("Hallowed Burial", 91, Rarity.RARE, mage.cards.h.HallowedBurial.class)); - cards.add(new SetCardInfo("Hamletback Goliath", 163, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); - cards.add(new SetCardInfo("Harvester of Souls", 138, Rarity.RARE, mage.cards.h.HarvesterOfSouls.class)); - cards.add(new SetCardInfo("Havengul Vampire", 164, Rarity.UNCOMMON, mage.cards.h.HavengulVampire.class)); - cards.add(new SetCardInfo("Hedron Matrix", 209, Rarity.RARE, mage.cards.h.HedronMatrix.class)); - cards.add(new SetCardInfo("Hexplate Golem", 210, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); - cards.add(new SetCardInfo("Hollowhenge Spirit", 92, Rarity.UNCOMMON, mage.cards.h.HollowhengeSpirit.class)); - cards.add(new SetCardInfo("Horn of Greed", 211, Rarity.RARE, mage.cards.h.HornOfGreed.class)); - cards.add(new SetCardInfo("Hundred-Handed One", 93, Rarity.RARE, mage.cards.h.HundredHandedOne.class)); - cards.add(new SetCardInfo("Hurly-Burly", 165, Rarity.COMMON, mage.cards.h.HurlyBurly.class)); - cards.add(new SetCardInfo("Ill-Tempered Cyclops", 166, Rarity.COMMON, mage.cards.i.IllTemperedCyclops.class)); - cards.add(new SetCardInfo("Infest", 139, Rarity.UNCOMMON, mage.cards.i.Infest.class)); - cards.add(new SetCardInfo("Inquisition of Kozilek", 140, Rarity.RARE, mage.cards.i.InquisitionOfKozilek.class)); - cards.add(new SetCardInfo("Into the Void", 112, Rarity.UNCOMMON, mage.cards.i.IntoTheVoid.class)); - cards.add(new SetCardInfo("Irresistible Prey", 183, Rarity.UNCOMMON, mage.cards.i.IrresistiblePrey.class)); - cards.add(new SetCardInfo("Juniper Order Ranger", 204, Rarity.UNCOMMON, mage.cards.j.JuniperOrderRanger.class)); - cards.add(new SetCardInfo("Kami of the Crescent Moon", 113, Rarity.RARE, mage.cards.k.KamiOfTheCrescentMoon.class)); - cards.add(new SetCardInfo("Kaya, Ghost Assassin", 75, Rarity.MYTHIC, mage.cards.k.KayaGhostAssassin.class)); - cards.add(new SetCardInfo("Keeper of Keys", 34, Rarity.RARE, mage.cards.k.KeeperOfKeys.class)); - cards.add(new SetCardInfo("Keepsake Gorgon", 141, Rarity.UNCOMMON, mage.cards.k.KeepsakeGorgon.class)); - cards.add(new SetCardInfo("Kill Shot", 94, Rarity.COMMON, mage.cards.k.KillShot.class)); - cards.add(new SetCardInfo("Kiln Fiend", 167, Rarity.COMMON, mage.cards.k.KilnFiend.class)); - cards.add(new SetCardInfo("Kitesail", 212, Rarity.COMMON, mage.cards.k.Kitesail.class)); - cards.add(new SetCardInfo("Knights of the Black Rose", 76, Rarity.UNCOMMON, mage.cards.k.KnightsOfTheBlackRose.class)); - cards.add(new SetCardInfo("Lace with Moonglove", 184, Rarity.COMMON, mage.cards.l.LaceWithMoonglove.class)); - cards.add(new SetCardInfo("Lay of the Land", 185, Rarity.COMMON, mage.cards.l.LayOfTheLand.class)); - cards.add(new SetCardInfo("Leovold, Emissary of Trest", 77, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); - cards.add(new SetCardInfo("Manaplasm", 186, Rarity.UNCOMMON, mage.cards.m.Manaplasm.class)); - cards.add(new SetCardInfo("Marchesa's Decree", 44, Rarity.UNCOMMON, mage.cards.m.MarchesasDecree.class)); - cards.add(new SetCardInfo("Menagerie Liberator", 67, Rarity.COMMON, mage.cards.m.MenagerieLiberator.class)); - cards.add(new SetCardInfo("Merfolk Looter", 114, Rarity.UNCOMMON, mage.cards.m.MerfolkLooter.class)); - cards.add(new SetCardInfo("Merfolk Skyscout", 115, Rarity.UNCOMMON, mage.cards.m.MerfolkSkyscout.class)); - cards.add(new SetCardInfo("Mnemonic Wall", 116, Rarity.COMMON, mage.cards.m.MnemonicWall.class)); - cards.add(new SetCardInfo("Murder", 143, Rarity.COMMON, mage.cards.m.Murder.class)); - cards.add(new SetCardInfo("Negate", 117, Rarity.COMMON, mage.cards.n.Negate.class)); - cards.add(new SetCardInfo("Nessian Asp", 187, Rarity.COMMON, mage.cards.n.NessianAsp.class)); - cards.add(new SetCardInfo("Netcaster Spider", 188, Rarity.COMMON, mage.cards.n.NetcasterSpider.class)); - cards.add(new SetCardInfo("Ogre Sentry", 168, Rarity.COMMON, mage.cards.o.OgreSentry.class)); - cards.add(new SetCardInfo("Omenspeaker", 118, Rarity.COMMON, mage.cards.o.Omenspeaker.class)); - cards.add(new SetCardInfo("Opaline Unicorn", 213, Rarity.COMMON, mage.cards.o.OpalineUnicorn.class)); - cards.add(new SetCardInfo("Overrun", 189, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); - cards.add(new SetCardInfo("Palace Jailer", 18, Rarity.UNCOMMON, mage.cards.p.PalaceJailer.class)); - cards.add(new SetCardInfo("Palace Sentinels", 19, Rarity.COMMON, mage.cards.p.PalaceSentinels.class)); - cards.add(new SetCardInfo("Pariah", 95, Rarity.RARE, mage.cards.p.Pariah.class)); - cards.add(new SetCardInfo("Pharika's Mender", 205, Rarity.UNCOMMON, mage.cards.p.PharikasMender.class)); - cards.add(new SetCardInfo("Phyrexian Arena", 144, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); - cards.add(new SetCardInfo("Platinum Angel", 214, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class)); - cards.add(new SetCardInfo("Plummet", 190, Rarity.COMMON, mage.cards.p.Plummet.class)); - cards.add(new SetCardInfo("Prey Upon", 191, Rarity.COMMON, mage.cards.p.PreyUpon.class)); - cards.add(new SetCardInfo("Protector of the Crown", 21, Rarity.RARE, mage.cards.p.ProtectorOfTheCrown.class)); - cards.add(new SetCardInfo("Psychosis Crawler", 215, Rarity.RARE, mage.cards.p.PsychosisCrawler.class)); - cards.add(new SetCardInfo("Public Execution", 145, Rarity.UNCOMMON, mage.cards.p.PublicExecution.class)); - cards.add(new SetCardInfo("Queen Marchesa", 78, Rarity.MYTHIC, mage.cards.q.QueenMarchesa.class)); - cards.add(new SetCardInfo("Raise Dead", 146, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Raise the Alarm", 96, Rarity.COMMON, mage.cards.r.RaiseTheAlarm.class)); - cards.add(new SetCardInfo("Ravenous Leucrocota", 192, Rarity.COMMON, mage.cards.r.RavenousLeucrocota.class)); - cards.add(new SetCardInfo("Recruiter of the Guard", 22, Rarity.RARE, mage.cards.r.RecruiterOfTheGuard.class)); - cards.add(new SetCardInfo("Regal Behemoth", 69, Rarity.RARE, mage.cards.r.RegalBehemoth.class)); - cards.add(new SetCardInfo("Repulse", 119, Rarity.COMMON, mage.cards.r.Repulse.class)); - cards.add(new SetCardInfo("Reviving Dose", 97, Rarity.COMMON, mage.cards.r.RevivingDose.class)); - cards.add(new SetCardInfo("Rogue's Passage", 220, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); - cards.add(new SetCardInfo("Runed Servitor", 216, Rarity.UNCOMMON, mage.cards.r.RunedServitor.class)); - cards.add(new SetCardInfo("Sanctum Prelate", 23, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); - cards.add(new SetCardInfo("Sangromancer", 147, Rarity.RARE, mage.cards.s.Sangromancer.class)); - cards.add(new SetCardInfo("Selvala, Heart of the Wilds", 70, Rarity.MYTHIC, mage.cards.s.SelvalaHeartOfTheWilds.class)); - cards.add(new SetCardInfo("Serum Visions", 120, Rarity.UNCOMMON, mage.cards.s.SerumVisions.class)); - cards.add(new SetCardInfo("Shambling Goblin", 148, Rarity.COMMON, mage.cards.s.ShamblingGoblin.class)); - cards.add(new SetCardInfo("Shimmering Grotto", 221, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class)); - cards.add(new SetCardInfo("Shipwreck Singer", 206, Rarity.UNCOMMON, mage.cards.s.ShipwreckSinger.class)); - cards.add(new SetCardInfo("Show and Tell", 121, Rarity.MYTHIC, mage.cards.s.ShowAndTell.class)); - cards.add(new SetCardInfo("Sinuous Vermin", 46, Rarity.COMMON, mage.cards.s.SinuousVermin.class)); - cards.add(new SetCardInfo("Skittering Crustacean", 36, Rarity.COMMON, mage.cards.s.SkitteringCrustacean.class)); - cards.add(new SetCardInfo("Skyline Despot", 57, Rarity.RARE, mage.cards.s.SkylineDespot.class)); - cards.add(new SetCardInfo("Spectral Grasp", 24, Rarity.UNCOMMON, mage.cards.s.SpectralGrasp.class)); - cards.add(new SetCardInfo("Sphinx of Magosi", 122, Rarity.RARE, mage.cards.s.SphinxOfMagosi.class)); - cards.add(new SetCardInfo("Spirit of the Hearth", 98, Rarity.RARE, mage.cards.s.SpiritOfTheHearth.class)); - cards.add(new SetCardInfo("Splitting Slime", 72, Rarity.RARE, mage.cards.s.SplittingSlime.class)); - cards.add(new SetCardInfo("Stoneshock Giant", 169, Rarity.UNCOMMON, mage.cards.s.StoneshockGiant.class)); - cards.add(new SetCardInfo("Stormchaser Chimera", 207, Rarity.UNCOMMON, mage.cards.s.StormchaserChimera.class)); - cards.add(new SetCardInfo("Strength in Numbers", 193, Rarity.COMMON, mage.cards.s.StrengthInNumbers.class)); - cards.add(new SetCardInfo("Stromkirk Patrol", 149, Rarity.COMMON, mage.cards.s.StromkirkPatrol.class)); - cards.add(new SetCardInfo("Stunt Double", 38, Rarity.RARE, mage.cards.s.StuntDouble.class)); - cards.add(new SetCardInfo("Subterranean Tremors", 58, Rarity.MYTHIC, mage.cards.s.SubterraneanTremors.class)); - cards.add(new SetCardInfo("Sulfurous Blast", 170, Rarity.UNCOMMON, mage.cards.s.SulfurousBlast.class)); - cards.add(new SetCardInfo("Sylvan Bounty", 194, Rarity.COMMON, mage.cards.s.SylvanBounty.class)); - cards.add(new SetCardInfo("Thorn of the Black Rose", 48, Rarity.COMMON, mage.cards.t.ThornOfTheBlackRose.class)); - cards.add(new SetCardInfo("Throne Warden", 25, Rarity.COMMON, mage.cards.t.ThroneWarden.class)); - cards.add(new SetCardInfo("Throne of the High City", 80, Rarity.RARE, mage.cards.t.ThroneOfTheHighCity.class)); - cards.add(new SetCardInfo("Tormenting Voice", 171, Rarity.COMMON, mage.cards.t.TormentingVoice.class)); - cards.add(new SetCardInfo("Traumatic Visions", 123, Rarity.COMMON, mage.cards.t.TraumaticVisions.class)); - cards.add(new SetCardInfo("Trumpet Blast", 172, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); - cards.add(new SetCardInfo("Twin Bolt", 173, Rarity.COMMON, mage.cards.t.TwinBolt.class)); - cards.add(new SetCardInfo("Unnerve", 150, Rarity.COMMON, mage.cards.u.Unnerve.class)); - cards.add(new SetCardInfo("Vaporkin", 124, Rarity.COMMON, mage.cards.v.Vaporkin.class)); - cards.add(new SetCardInfo("Vertigo Spawn", 125, Rarity.UNCOMMON, mage.cards.v.VertigoSpawn.class)); - cards.add(new SetCardInfo("Voyaging Satyr", 195, Rarity.COMMON, mage.cards.v.VoyagingSatyr.class)); - cards.add(new SetCardInfo("Wild Griffin", 99, Rarity.COMMON, mage.cards.w.WildGriffin.class)); - cards.add(new SetCardInfo("Wild Pair", 196, Rarity.RARE, mage.cards.w.WildPair.class)); - cards.add(new SetCardInfo("Windborne Charge", 100, Rarity.UNCOMMON, mage.cards.w.WindborneCharge.class)); - cards.add(new SetCardInfo("Wings of the Guard", 26, Rarity.COMMON, mage.cards.w.WingsOfTheGuard.class)); - cards.add(new SetCardInfo("Zealous Strike", 101, Rarity.COMMON, mage.cards.z.ZealousStrike.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.ExpansionSet; +import mage.constants.SetType; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ + +public class ConspiracyTakeTheCrown extends ExpansionSet { + + private static final ConspiracyTakeTheCrown fINSTANCE = new ConspiracyTakeTheCrown(); + + public static ConspiracyTakeTheCrown getInstance() { + return fINSTANCE; + } + + private ConspiracyTakeTheCrown() { + super("Conspiracy: Take the Crown", "CN2", ExpansionSet.buildDate(2016, 8, 26), SetType.SUPPLEMENTAL); + this.blockName = "Conspiracy"; + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Absorb Vis", 126, Rarity.COMMON, mage.cards.a.AbsorbVis.class)); + cards.add(new SetCardInfo("Adriana, Captain of the Guard", 73, Rarity.RARE, mage.cards.a.AdrianaCaptainOfTheGuard.class)); + cards.add(new SetCardInfo("Affa Guard Hound", 81, Rarity.UNCOMMON, mage.cards.a.AffaGuardHound.class)); + cards.add(new SetCardInfo("Akroan Hoplite", 197, Rarity.UNCOMMON, mage.cards.a.AkroanHoplite.class)); + cards.add(new SetCardInfo("Altar's Reap", 127, Rarity.COMMON, mage.cards.a.AltarsReap.class)); + cards.add(new SetCardInfo("Ascended Lawmage", 198, Rarity.UNCOMMON, mage.cards.a.AscendedLawmage.class)); + cards.add(new SetCardInfo("Avatar of Woe", 128, Rarity.MYTHIC, mage.cards.a.AvatarOfWoe.class)); + cards.add(new SetCardInfo("Beast Within", 174, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); + cards.add(new SetCardInfo("Berserk", 175, Rarity.MYTHIC, mage.cards.b.Berserk.class)); + cards.add(new SetCardInfo("Birds of Paradise", 176, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); + cards.add(new SetCardInfo("Blood-Toll Harpy", 129, Rarity.COMMON, mage.cards.b.BloodTollHarpy.class)); + cards.add(new SetCardInfo("Bonds of Quicksilver", 102, Rarity.COMMON, mage.cards.b.BondsOfQuicksilver.class)); + cards.add(new SetCardInfo("Borderland Explorer", 61, Rarity.COMMON, mage.cards.b.BorderlandExplorer.class)); + cards.add(new SetCardInfo("Bronze Sable", 208, Rarity.COMMON, mage.cards.b.BronzeSable.class)); + cards.add(new SetCardInfo("Brushstrider", 177, Rarity.UNCOMMON, mage.cards.b.Brushstrider.class)); + cards.add(new SetCardInfo("Burgeoning", 178, Rarity.RARE, mage.cards.b.Burgeoning.class)); + cards.add(new SetCardInfo("Burn Away", 151, Rarity.UNCOMMON, mage.cards.b.BurnAway.class)); + cards.add(new SetCardInfo("Burning Wish", 152, Rarity.RARE, mage.cards.b.BurningWish.class)); + cards.add(new SetCardInfo("Caller of Gales", 103, Rarity.COMMON, mage.cards.c.CallerOfGales.class)); + cards.add(new SetCardInfo("Canal Courier", 28, Rarity.COMMON, mage.cards.c.CanalCourier.class)); + cards.add(new SetCardInfo("Capital Punishment", 40, Rarity.RARE, mage.cards.c.CapitalPunishment.class)); + cards.add(new SetCardInfo("Carnage Gladiator", 199, Rarity.UNCOMMON, mage.cards.c.CarnageGladiator.class)); + cards.add(new SetCardInfo("Charmbreaker Devils", 153, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class)); + cards.add(new SetCardInfo("Child of Night", 130, Rarity.COMMON, mage.cards.c.ChildOfNight.class)); + cards.add(new SetCardInfo("Cloaked Siren", 104, Rarity.COMMON, mage.cards.c.CloakedSiren.class)); + cards.add(new SetCardInfo("Coiling Oracle", 200, Rarity.UNCOMMON, mage.cards.c.CoilingOracle.class)); + cards.add(new SetCardInfo("Coordinated Assault", 154, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class)); + cards.add(new SetCardInfo("Copperhorn Scout", 179, Rarity.COMMON, mage.cards.c.CopperhornScout.class)); + cards.add(new SetCardInfo("Covenant of Minds", 105, Rarity.RARE, mage.cards.c.CovenantOfMinds.class)); + cards.add(new SetCardInfo("Crown-Hunter Hireling", 50, Rarity.COMMON, mage.cards.c.CrownHunterHireling.class)); + cards.add(new SetCardInfo("Custodi Lich", 41, Rarity.RARE, mage.cards.c.CustodiLich.class)); + cards.add(new SetCardInfo("Daretti, Ingenious Iconoclast", 74, Rarity.MYTHIC, mage.cards.d.DarettiIngeniousIconoclast.class)); + cards.add(new SetCardInfo("Death Wind", 131, Rarity.COMMON, mage.cards.d.DeathWind.class)); + cards.add(new SetCardInfo("Deceiver Exarch", 106, Rarity.UNCOMMON, mage.cards.d.DeceiverExarch.class)); + cards.add(new SetCardInfo("Deputized Protester", 51, Rarity.COMMON, mage.cards.d.DeputizedProtester.class)); + cards.add(new SetCardInfo("Desertion", 107, Rarity.RARE, mage.cards.d.Desertion.class)); + cards.add(new SetCardInfo("Diabolic Tutor", 132, Rarity.UNCOMMON, mage.cards.d.DiabolicTutor.class)); + cards.add(new SetCardInfo("Disenchant", 82, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Dismiss", 108, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); + cards.add(new SetCardInfo("Divination", 109, Rarity.COMMON, mage.cards.d.Divination.class)); + cards.add(new SetCardInfo("Domesticated Hydra", 63, Rarity.UNCOMMON, mage.cards.d.DomesticatedHydra.class)); + cards.add(new SetCardInfo("Doomed Traveler", 83, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); + cards.add(new SetCardInfo("Dragonlair Spider", 201, Rarity.RARE, mage.cards.d.DragonlairSpider.class)); + cards.add(new SetCardInfo("Dread Statuary", 217, Rarity.UNCOMMON, mage.cards.d.DreadStatuary.class)); + cards.add(new SetCardInfo("Driver of the Dead", 133, Rarity.COMMON, mage.cards.d.DriverOfTheDead.class)); + cards.add(new SetCardInfo("Duskmantle Seer", 202, Rarity.RARE, mage.cards.d.DuskmantleSeer.class)); + cards.add(new SetCardInfo("Ember Beast", 155, Rarity.COMMON, mage.cards.e.EmberBeast.class)); + cards.add(new SetCardInfo("Entourage of Trest", 64, Rarity.COMMON, mage.cards.e.EntourageOfTrest.class)); + cards.add(new SetCardInfo("Evolving Wilds", 218, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); + cards.add(new SetCardInfo("Exotic Orchard", 219, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); + cards.add(new SetCardInfo("Explosive Vegetation", 180, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); + cards.add(new SetCardInfo("Expropriate", 30, Rarity.MYTHIC, mage.cards.e.Expropriate.class)); + cards.add(new SetCardInfo("Fade into Antiquity", 181, Rarity.COMMON, mage.cards.f.FadeIntoAntiquity.class)); + cards.add(new SetCardInfo("Faith's Reward", 84, Rarity.RARE, mage.cards.f.FaithsReward.class)); + cards.add(new SetCardInfo("Farbog Boneflinger", 134, Rarity.UNCOMMON, mage.cards.f.FarbogBoneflinger.class)); + cards.add(new SetCardInfo("Festergloom", 135, Rarity.COMMON, mage.cards.f.Festergloom.class)); + cards.add(new SetCardInfo("Fiery Fall", 156, Rarity.COMMON, mage.cards.f.FieryFall.class)); + cards.add(new SetCardInfo("Flame Slash", 157, Rarity.COMMON, mage.cards.f.FlameSlash.class)); + cards.add(new SetCardInfo("Fleeting Distraction", 110, Rarity.COMMON, mage.cards.f.FleetingDistraction.class)); + cards.add(new SetCardInfo("Fleshbag Marauder", 136, Rarity.UNCOMMON, mage.cards.f.FleshbagMarauder.class)); + cards.add(new SetCardInfo("Followed Footsteps", 111, Rarity.RARE, mage.cards.f.FollowedFootsteps.class)); + cards.add(new SetCardInfo("Forgotten Ancient", 182, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); + cards.add(new SetCardInfo("Gang of Devils", 158, Rarity.UNCOMMON, mage.cards.g.GangOfDevils.class)); + cards.add(new SetCardInfo("Garrulous Sycophant", 43, Rarity.COMMON, mage.cards.g.GarrulousSycophant.class)); + cards.add(new SetCardInfo("Ghostly Possession", 85, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); + cards.add(new SetCardInfo("Ghostly Prison", 86, Rarity.UNCOMMON, mage.cards.g.GhostlyPrison.class)); + cards.add(new SetCardInfo("Gleam of Resistance", 87, Rarity.COMMON, mage.cards.g.GleamOfResistance.class)); + cards.add(new SetCardInfo("Goblin Balloon Brigade", 159, Rarity.COMMON, mage.cards.g.GoblinBalloonBrigade.class)); + cards.add(new SetCardInfo("Goblin Tunneler", 160, Rarity.COMMON, mage.cards.g.GoblinTunneler.class)); + cards.add(new SetCardInfo("Gods Willing", 88, Rarity.COMMON, mage.cards.g.GodsWilling.class)); + cards.add(new SetCardInfo("Gratuitous Violence", 161, Rarity.RARE, mage.cards.g.GratuitousViolence.class)); + cards.add(new SetCardInfo("Gruul War Chant", 203, Rarity.UNCOMMON, mage.cards.g.GruulWarChant.class)); + cards.add(new SetCardInfo("Guardian of the Gateless", 89, Rarity.UNCOMMON, mage.cards.g.GuardianOfTheGateless.class)); + cards.add(new SetCardInfo("Guttersnipe", 162, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class)); + cards.add(new SetCardInfo("Guul Draz Specter", 137, Rarity.RARE, mage.cards.g.GuulDrazSpecter.class)); + cards.add(new SetCardInfo("Hail of Arrows", 90, Rarity.UNCOMMON, mage.cards.h.HailOfArrows.class)); + cards.add(new SetCardInfo("Hallowed Burial", 91, Rarity.RARE, mage.cards.h.HallowedBurial.class)); + cards.add(new SetCardInfo("Hamletback Goliath", 163, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); + cards.add(new SetCardInfo("Harvester of Souls", 138, Rarity.RARE, mage.cards.h.HarvesterOfSouls.class)); + cards.add(new SetCardInfo("Havengul Vampire", 164, Rarity.UNCOMMON, mage.cards.h.HavengulVampire.class)); + cards.add(new SetCardInfo("Hedron Matrix", 209, Rarity.RARE, mage.cards.h.HedronMatrix.class)); + cards.add(new SetCardInfo("Hexplate Golem", 210, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); + cards.add(new SetCardInfo("Hollowhenge Spirit", 92, Rarity.UNCOMMON, mage.cards.h.HollowhengeSpirit.class)); + cards.add(new SetCardInfo("Horn of Greed", 211, Rarity.RARE, mage.cards.h.HornOfGreed.class)); + cards.add(new SetCardInfo("Hundred-Handed One", 93, Rarity.RARE, mage.cards.h.HundredHandedOne.class)); + cards.add(new SetCardInfo("Hurly-Burly", 165, Rarity.COMMON, mage.cards.h.HurlyBurly.class)); + cards.add(new SetCardInfo("Ill-Tempered Cyclops", 166, Rarity.COMMON, mage.cards.i.IllTemperedCyclops.class)); + cards.add(new SetCardInfo("Infest", 139, Rarity.UNCOMMON, mage.cards.i.Infest.class)); + cards.add(new SetCardInfo("Inquisition of Kozilek", 140, Rarity.RARE, mage.cards.i.InquisitionOfKozilek.class)); + cards.add(new SetCardInfo("Into the Void", 112, Rarity.UNCOMMON, mage.cards.i.IntoTheVoid.class)); + cards.add(new SetCardInfo("Irresistible Prey", 183, Rarity.UNCOMMON, mage.cards.i.IrresistiblePrey.class)); + cards.add(new SetCardInfo("Juniper Order Ranger", 204, Rarity.UNCOMMON, mage.cards.j.JuniperOrderRanger.class)); + cards.add(new SetCardInfo("Kami of the Crescent Moon", 113, Rarity.RARE, mage.cards.k.KamiOfTheCrescentMoon.class)); + cards.add(new SetCardInfo("Kaya, Ghost Assassin", 75, Rarity.MYTHIC, mage.cards.k.KayaGhostAssassin.class)); + cards.add(new SetCardInfo("Keeper of Keys", 34, Rarity.RARE, mage.cards.k.KeeperOfKeys.class)); + cards.add(new SetCardInfo("Keepsake Gorgon", 141, Rarity.UNCOMMON, mage.cards.k.KeepsakeGorgon.class)); + cards.add(new SetCardInfo("Kill Shot", 94, Rarity.COMMON, mage.cards.k.KillShot.class)); + cards.add(new SetCardInfo("Kiln Fiend", 167, Rarity.COMMON, mage.cards.k.KilnFiend.class)); + cards.add(new SetCardInfo("Kitesail", 212, Rarity.COMMON, mage.cards.k.Kitesail.class)); + cards.add(new SetCardInfo("Knights of the Black Rose", 76, Rarity.UNCOMMON, mage.cards.k.KnightsOfTheBlackRose.class)); + cards.add(new SetCardInfo("Lace with Moonglove", 184, Rarity.COMMON, mage.cards.l.LaceWithMoonglove.class)); + cards.add(new SetCardInfo("Lay of the Land", 185, Rarity.COMMON, mage.cards.l.LayOfTheLand.class)); + cards.add(new SetCardInfo("Leovold, Emissary of Trest", 77, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); + cards.add(new SetCardInfo("Lieutenants of the Guard", 16, Rarity.COMMON, mage.cards.l.LieutenantsOfTheGuard.class)); + cards.add(new SetCardInfo("Manaplasm", 186, Rarity.UNCOMMON, mage.cards.m.Manaplasm.class)); + cards.add(new SetCardInfo("Marchesa's Decree", 44, Rarity.UNCOMMON, mage.cards.m.MarchesasDecree.class)); + cards.add(new SetCardInfo("Menagerie Liberator", 67, Rarity.COMMON, mage.cards.m.MenagerieLiberator.class)); + cards.add(new SetCardInfo("Merfolk Looter", 114, Rarity.UNCOMMON, mage.cards.m.MerfolkLooter.class)); + cards.add(new SetCardInfo("Merfolk Skyscout", 115, Rarity.UNCOMMON, mage.cards.m.MerfolkSkyscout.class)); + cards.add(new SetCardInfo("Messenger Jays", 35, Rarity.COMMON, mage.cards.m.MessengerJays.class)); + cards.add(new SetCardInfo("Mnemonic Wall", 116, Rarity.COMMON, mage.cards.m.MnemonicWall.class)); + cards.add(new SetCardInfo("Murder", 143, Rarity.COMMON, mage.cards.m.Murder.class)); + cards.add(new SetCardInfo("Negate", 117, Rarity.COMMON, mage.cards.n.Negate.class)); + cards.add(new SetCardInfo("Nessian Asp", 187, Rarity.COMMON, mage.cards.n.NessianAsp.class)); + cards.add(new SetCardInfo("Netcaster Spider", 188, Rarity.COMMON, mage.cards.n.NetcasterSpider.class)); + cards.add(new SetCardInfo("Ogre Sentry", 168, Rarity.COMMON, mage.cards.o.OgreSentry.class)); + cards.add(new SetCardInfo("Omenspeaker", 118, Rarity.COMMON, mage.cards.o.Omenspeaker.class)); + cards.add(new SetCardInfo("Opaline Unicorn", 213, Rarity.COMMON, mage.cards.o.OpalineUnicorn.class)); + cards.add(new SetCardInfo("Orchard Elemental", 68, Rarity.COMMON, mage.cards.o.OrchardElemental.class)); + cards.add(new SetCardInfo("Overrun", 189, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); + cards.add(new SetCardInfo("Palace Jailer", 18, Rarity.UNCOMMON, mage.cards.p.PalaceJailer.class)); + cards.add(new SetCardInfo("Palace Sentinels", 19, Rarity.COMMON, mage.cards.p.PalaceSentinels.class)); + cards.add(new SetCardInfo("Pariah", 95, Rarity.RARE, mage.cards.p.Pariah.class)); + cards.add(new SetCardInfo("Pharika's Mender", 205, Rarity.UNCOMMON, mage.cards.p.PharikasMender.class)); + cards.add(new SetCardInfo("Phyrexian Arena", 144, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); + cards.add(new SetCardInfo("Platinum Angel", 214, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class)); + cards.add(new SetCardInfo("Plummet", 190, Rarity.COMMON, mage.cards.p.Plummet.class)); + cards.add(new SetCardInfo("Prey Upon", 191, Rarity.COMMON, mage.cards.p.PreyUpon.class)); + cards.add(new SetCardInfo("Protector of the Crown", 21, Rarity.RARE, mage.cards.p.ProtectorOfTheCrown.class)); + cards.add(new SetCardInfo("Psychosis Crawler", 215, Rarity.RARE, mage.cards.p.PsychosisCrawler.class)); + cards.add(new SetCardInfo("Public Execution", 145, Rarity.UNCOMMON, mage.cards.p.PublicExecution.class)); + cards.add(new SetCardInfo("Queen Marchesa", 78, Rarity.MYTHIC, mage.cards.q.QueenMarchesa.class)); + cards.add(new SetCardInfo("Raise Dead", 146, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Raise the Alarm", 96, Rarity.COMMON, mage.cards.r.RaiseTheAlarm.class)); + cards.add(new SetCardInfo("Ravenous Leucrocota", 192, Rarity.COMMON, mage.cards.r.RavenousLeucrocota.class)); + cards.add(new SetCardInfo("Recruiter of the Guard", 22, Rarity.RARE, mage.cards.r.RecruiterOfTheGuard.class)); + cards.add(new SetCardInfo("Regal Behemoth", 69, Rarity.RARE, mage.cards.r.RegalBehemoth.class)); + cards.add(new SetCardInfo("Repulse", 119, Rarity.COMMON, mage.cards.r.Repulse.class)); + cards.add(new SetCardInfo("Reviving Dose", 97, Rarity.COMMON, mage.cards.r.RevivingDose.class)); + cards.add(new SetCardInfo("Rogue's Passage", 220, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); + cards.add(new SetCardInfo("Runed Servitor", 216, Rarity.UNCOMMON, mage.cards.r.RunedServitor.class)); + cards.add(new SetCardInfo("Sanctum Prelate", 23, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); + cards.add(new SetCardInfo("Sangromancer", 147, Rarity.RARE, mage.cards.s.Sangromancer.class)); + cards.add(new SetCardInfo("Selvala's Stampede", 71, Rarity.RARE, mage.cards.s.SelvalasStampede.class)); + cards.add(new SetCardInfo("Selvala, Heart of the Wilds", 70, Rarity.MYTHIC, mage.cards.s.SelvalaHeartOfTheWilds.class)); + cards.add(new SetCardInfo("Serum Visions", 120, Rarity.UNCOMMON, mage.cards.s.SerumVisions.class)); + cards.add(new SetCardInfo("Shambling Goblin", 148, Rarity.COMMON, mage.cards.s.ShamblingGoblin.class)); + cards.add(new SetCardInfo("Shimmering Grotto", 221, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class)); + cards.add(new SetCardInfo("Shipwreck Singer", 206, Rarity.UNCOMMON, mage.cards.s.ShipwreckSinger.class)); + cards.add(new SetCardInfo("Show and Tell", 121, Rarity.MYTHIC, mage.cards.s.ShowAndTell.class)); + cards.add(new SetCardInfo("Sinuous Vermin", 46, Rarity.COMMON, mage.cards.s.SinuousVermin.class)); + cards.add(new SetCardInfo("Skittering Crustacean", 36, Rarity.COMMON, mage.cards.s.SkitteringCrustacean.class)); + cards.add(new SetCardInfo("Skyline Despot", 57, Rarity.RARE, mage.cards.s.SkylineDespot.class)); + cards.add(new SetCardInfo("Spectral Grasp", 24, Rarity.UNCOMMON, mage.cards.s.SpectralGrasp.class)); + cards.add(new SetCardInfo("Sphinx of Magosi", 122, Rarity.RARE, mage.cards.s.SphinxOfMagosi.class)); + cards.add(new SetCardInfo("Spirit of the Hearth", 98, Rarity.RARE, mage.cards.s.SpiritOfTheHearth.class)); + cards.add(new SetCardInfo("Splitting Slime", 72, Rarity.RARE, mage.cards.s.SplittingSlime.class)); + cards.add(new SetCardInfo("Stoneshock Giant", 169, Rarity.UNCOMMON, mage.cards.s.StoneshockGiant.class)); + cards.add(new SetCardInfo("Stormchaser Chimera", 207, Rarity.UNCOMMON, mage.cards.s.StormchaserChimera.class)); + cards.add(new SetCardInfo("Strength in Numbers", 193, Rarity.COMMON, mage.cards.s.StrengthInNumbers.class)); + cards.add(new SetCardInfo("Stromkirk Patrol", 149, Rarity.COMMON, mage.cards.s.StromkirkPatrol.class)); + cards.add(new SetCardInfo("Stunt Double", 38, Rarity.RARE, mage.cards.s.StuntDouble.class)); + cards.add(new SetCardInfo("Subterranean Tremors", 58, Rarity.MYTHIC, mage.cards.s.SubterraneanTremors.class)); + cards.add(new SetCardInfo("Sulfurous Blast", 170, Rarity.UNCOMMON, mage.cards.s.SulfurousBlast.class)); + cards.add(new SetCardInfo("Sylvan Bounty", 194, Rarity.COMMON, mage.cards.s.SylvanBounty.class)); + cards.add(new SetCardInfo("Thorn of the Black Rose", 48, Rarity.COMMON, mage.cards.t.ThornOfTheBlackRose.class)); + cards.add(new SetCardInfo("Throne Warden", 25, Rarity.COMMON, mage.cards.t.ThroneWarden.class)); + cards.add(new SetCardInfo("Throne of the High City", 80, Rarity.RARE, mage.cards.t.ThroneOfTheHighCity.class)); + cards.add(new SetCardInfo("Tormenting Voice", 171, Rarity.COMMON, mage.cards.t.TormentingVoice.class)); + cards.add(new SetCardInfo("Traumatic Visions", 123, Rarity.COMMON, mage.cards.t.TraumaticVisions.class)); + cards.add(new SetCardInfo("Trumpet Blast", 172, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); + cards.add(new SetCardInfo("Twin Bolt", 173, Rarity.COMMON, mage.cards.t.TwinBolt.class)); + cards.add(new SetCardInfo("Unnerve", 150, Rarity.COMMON, mage.cards.u.Unnerve.class)); + cards.add(new SetCardInfo("Vaporkin", 124, Rarity.COMMON, mage.cards.v.Vaporkin.class)); + cards.add(new SetCardInfo("Vertigo Spawn", 125, Rarity.UNCOMMON, mage.cards.v.VertigoSpawn.class)); + cards.add(new SetCardInfo("Voyaging Satyr", 195, Rarity.COMMON, mage.cards.v.VoyagingSatyr.class)); + cards.add(new SetCardInfo("Wild Griffin", 99, Rarity.COMMON, mage.cards.w.WildGriffin.class)); + cards.add(new SetCardInfo("Wild Pair", 196, Rarity.RARE, mage.cards.w.WildPair.class)); + cards.add(new SetCardInfo("Windborne Charge", 100, Rarity.UNCOMMON, mage.cards.w.WindborneCharge.class)); + cards.add(new SetCardInfo("Wings of the Guard", 26, Rarity.COMMON, mage.cards.w.WingsOfTheGuard.class)); + cards.add(new SetCardInfo("Zealous Strike", 101, Rarity.COMMON, mage.cards.z.ZealousStrike.class)); + } + +} diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index 441baeeb03c..4c7c880dee5 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -138,6 +138,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Slobad, Goblin Tinkerer", 69, Rarity.RARE, mage.cards.s.SlobadGoblinTinkerer.class)); cards.add(new SetCardInfo("Soulscour", 14, Rarity.RARE, mage.cards.s.Soulscour.class)); cards.add(new SetCardInfo("Spawning Pit", 141, Rarity.UNCOMMON, mage.cards.s.SpawningPit.class)); + cards.add(new SetCardInfo("Specter's Shroud", 142, Rarity.UNCOMMON, mage.cards.s.SpectersShroud.class)); cards.add(new SetCardInfo("Spellbinder", 143, Rarity.RARE, mage.cards.s.Spellbinder.class)); cards.add(new SetCardInfo("Spincrusher", 144, Rarity.UNCOMMON, mage.cards.s.Spincrusher.class)); cards.add(new SetCardInfo("Spire Golem", 145, Rarity.COMMON, mage.cards.s.SpireGolem.class)); diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java index 33bd237509f..467b517593f 100644 --- a/Mage.Sets/src/mage/sets/FifthEdition.java +++ b/Mage.Sets/src/mage/sets/FifthEdition.java @@ -103,6 +103,7 @@ public class FifthEdition extends ExpansionSet { cards.add(new SetCardInfo("Craw Giant", 147, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class)); cards.add(new SetCardInfo("Craw Wurm", 148, Rarity.COMMON, mage.cards.c.CrawWurm.class)); cards.add(new SetCardInfo("Crimson Manticore", 217, Rarity.RARE, mage.cards.c.CrimsonManticore.class)); + cards.add(new SetCardInfo("Crown of the Ages", 360, Rarity.RARE, mage.cards.c.CrownOfTheAges.class)); cards.add(new SetCardInfo("Crumble", 149, Rarity.UNCOMMON, mage.cards.c.Crumble.class)); cards.add(new SetCardInfo("Crusade", 298, Rarity.RARE, mage.cards.c.Crusade.class)); cards.add(new SetCardInfo("Crystal Rod", 361, Rarity.UNCOMMON, mage.cards.c.CrystalRod.class)); diff --git a/Mage.Sets/src/mage/sets/FridayNightMagic.java b/Mage.Sets/src/mage/sets/FridayNightMagic.java index a191757366d..2db6bee6f05 100644 --- a/Mage.Sets/src/mage/sets/FridayNightMagic.java +++ b/Mage.Sets/src/mage/sets/FridayNightMagic.java @@ -126,6 +126,7 @@ public class FridayNightMagic extends ExpansionSet { cards.add(new SetCardInfo("Forbid", 27, Rarity.UNCOMMON, mage.cards.f.Forbid.class)); cards.add(new SetCardInfo("Forbidden Alchemy", 146, Rarity.COMMON, mage.cards.f.ForbiddenAlchemy.class)); cards.add(new SetCardInfo("Force Spike", 91, Rarity.COMMON, mage.cards.f.ForceSpike.class)); + cards.add(new SetCardInfo("Fortune's Favor", 201, Rarity.COMMON, mage.cards.f.FortunesFavor.class)); cards.add(new SetCardInfo("Frenzied Goblin", 176, Rarity.UNCOMMON, mage.cards.f.FrenziedGoblin.class)); cards.add(new SetCardInfo("Frost Walker", 181, Rarity.UNCOMMON, mage.cards.f.FrostWalker.class)); cards.add(new SetCardInfo("Gatekeeper of Malakir", 126, Rarity.UNCOMMON, mage.cards.g.GatekeeperOfMalakir.class)); diff --git a/Mage.Sets/src/mage/sets/GameDay.java b/Mage.Sets/src/mage/sets/GameDay.java index 587358823ef..06f22c782f4 100644 --- a/Mage.Sets/src/mage/sets/GameDay.java +++ b/Mage.Sets/src/mage/sets/GameDay.java @@ -99,9 +99,11 @@ public class GameDay extends ExpansionSet { cards.add(new SetCardInfo("Tempered Steel", 5, Rarity.RARE, mage.cards.t.TemperedSteel.class)); cards.add(new SetCardInfo("Thunderbreak Regent", 43, Rarity.RARE, mage.cards.t.ThunderbreakRegent.class)); cards.add(new SetCardInfo("Treasure Mage", 6, Rarity.UNCOMMON, mage.cards.t.TreasureMage.class)); + cards.add(new SetCardInfo("Trophy Mage", 57, Rarity.UNCOMMON, mage.cards.t.TrophyMage.class)); cards.add(new SetCardInfo("Trostani's Summoner", 27, Rarity.UNCOMMON, mage.cards.t.TrostanisSummoner.class)); cards.add(new SetCardInfo("Unsubstantiate", 53, Rarity.UNCOMMON, mage.cards.u.Unsubstantiate.class)); cards.add(new SetCardInfo("Utter End", 38, Rarity.RARE, mage.cards.u.UtterEnd.class)); + cards.add(new SetCardInfo("Yaheeni's Expertise", 58, Rarity.RARE, mage.cards.y.YaheenisExpertise.class)); cards.add(new SetCardInfo("Zameck Guildmage", 25, Rarity.UNCOMMON, mage.cards.z.ZameckGuildmage.class)); cards.add(new SetCardInfo("Zombie Apocalypse", 14, Rarity.RARE, mage.cards.z.ZombieApocalypse.class)); } diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 19c66b44fda..b8b5459f826 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -87,6 +87,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Cold Snap", 241, Rarity.UNCOMMON, mage.cards.c.ColdSnap.class)); cards.add(new SetCardInfo("Conquer", 180, Rarity.UNCOMMON, mage.cards.c.Conquer.class)); cards.add(new SetCardInfo("Counterspell", 64, Rarity.COMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Crown of the Ages", 290, Rarity.RARE, mage.cards.c.CrownOfTheAges.class)); cards.add(new SetCardInfo("Curse of Marit Lage", 181, Rarity.RARE, mage.cards.c.CurseOfMaritLage.class)); cards.add(new SetCardInfo("Dance of the Dead", 6, Rarity.UNCOMMON, mage.cards.d.DanceOfTheDead.class)); cards.add(new SetCardInfo("Dark Banishing", 7, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); diff --git a/Mage.Sets/src/mage/sets/Judgment.java b/Mage.Sets/src/mage/sets/Judgment.java index a4cd5ad2bd9..c9729947ef1 100644 --- a/Mage.Sets/src/mage/sets/Judgment.java +++ b/Mage.Sets/src/mage/sets/Judgment.java @@ -27,9 +27,9 @@ */ package mage.sets; -import mage.constants.SetType; import mage.cards.ExpansionSet; import mage.constants.Rarity; +import mage.constants.SetType; /** * @@ -78,6 +78,7 @@ public class Judgment extends ExpansionSet { cards.add(new SetCardInfo("Cephalid Constable", 35, Rarity.RARE, mage.cards.c.CephalidConstable.class)); cards.add(new SetCardInfo("Chastise", 8, Rarity.UNCOMMON, mage.cards.c.Chastise.class)); cards.add(new SetCardInfo("Commander Eesha", 9, Rarity.RARE, mage.cards.c.CommanderEesha.class)); + cards.add(new SetCardInfo("Crush of Wurms", 110, Rarity.RARE, mage.cards.c.CrushOfWurms.class)); cards.add(new SetCardInfo("Cunning Wish", 37, Rarity.RARE, mage.cards.c.CunningWish.class)); cards.add(new SetCardInfo("Death Wish", 64, Rarity.RARE, mage.cards.d.DeathWish.class)); cards.add(new SetCardInfo("Defy Gravity", 38, Rarity.COMMON, mage.cards.d.DefyGravity.class)); diff --git a/Mage.Sets/src/mage/sets/Lorwyn.java b/Mage.Sets/src/mage/sets/Lorwyn.java index a911d9f488b..89aac18df37 100644 --- a/Mage.Sets/src/mage/sets/Lorwyn.java +++ b/Mage.Sets/src/mage/sets/Lorwyn.java @@ -97,6 +97,8 @@ public class Lorwyn extends ExpansionSet { cards.add(new SetCardInfo("Cloudcrown Oak", 201, Rarity.COMMON, mage.cards.c.CloudcrownOak.class)); cards.add(new SetCardInfo("Cloudgoat Ranger", 10, Rarity.UNCOMMON, mage.cards.c.CloudgoatRanger.class)); cards.add(new SetCardInfo("Cloudthresher", 202, Rarity.RARE, mage.cards.c.Cloudthresher.class)); + cards.add(new SetCardInfo("Colfenor's Plans", 106, Rarity.RARE, mage.cards.c.ColfenorsPlans.class)); + cards.add(new SetCardInfo("Colfenor's Urn", 254, Rarity.RARE, mage.cards.c.ColfenorsUrn.class)); cards.add(new SetCardInfo("Consuming Bonfire", 161, Rarity.COMMON, mage.cards.c.ConsumingBonfire.class)); cards.add(new SetCardInfo("Crib Swap", 11, Rarity.UNCOMMON, mage.cards.c.CribSwap.class)); cards.add(new SetCardInfo("Crush Underfoot", 162, Rarity.UNCOMMON, mage.cards.c.CrushUnderfoot.class)); diff --git a/Mage/src/main/java/mage/MageInt.java b/Mage/src/main/java/mage/MageInt.java index bb0fb75f820..73954ede007 100644 --- a/Mage/src/main/java/mage/MageInt.java +++ b/Mage/src/main/java/mage/MageInt.java @@ -32,7 +32,7 @@ import mage.util.Copyable; public class MageInt implements Serializable, Copyable { - public static MageInt EmptyMageInt = new MageInt(Integer.MIN_VALUE, null) { + public static MageInt EmptyMageInt = new MageInt(Integer.MIN_VALUE, "") { private static final String exceptionMessage = "MageInt.EmptyMageInt can't be modified."; diff --git a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java index 967b22938e4..b9f6a179c0f 100644 --- a/Mage/src/main/java/mage/abilities/TriggeredAbilities.java +++ b/Mage/src/main/java/mage/abilities/TriggeredAbilities.java @@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentHashMap; import mage.MageObject; import mage.cards.Card; import mage.constants.Zone; +import mage.designations.Designation; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.NumberOfTriggersEvent; @@ -146,6 +147,8 @@ public class TriggeredAbilities extends ConcurrentHashMap uuidList = new LinkedList<>(); @@ -190,8 +193,14 @@ public class TriggeredAbilities extends ConcurrentHashMap keysToRemove = new ArrayList<>(); + Abilities: for (Entry entry : this.entrySet()) { if (game.getObject(entry.getValue().getSourceId()) == null) { + for (Designation designation : game.getState().getDesignations()) { + if (designation.getId().equals(entry.getValue().getSourceId())) { + continue Abilities; + } + } keysToRemove.add(entry.getKey()); } } diff --git a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java index 43f94d113cc..c13f59afbbd 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerTriggeredAbility.java @@ -29,7 +29,6 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; -import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; diff --git a/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java b/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java index e94fa838f98..a7c6910f3b3 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/MonarchIsSourceControllerCondition.java @@ -1,7 +1,29 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. +* 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.condition.common; diff --git a/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java new file mode 100644 index 00000000000..d4fe9ebeb68 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class BecomesMonarchTargetEffect extends OneShotEffect { + + public BecomesMonarchTargetEffect() { + super(Outcome.Benefit); + staticText = "target player becomes the monarch"; + } + + public BecomesMonarchTargetEffect(final BecomesMonarchTargetEffect effect) { + super(effect); + } + + @Override + public BecomesMonarchTargetEffect copy() { + return new BecomesMonarchTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + game.setMonarchId(source, targetPlayer.getId()); + return true; + } + return false; + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/RevealCardsFromLibraryUntilEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RevealCardsFromLibraryUntilEffect.java new file mode 100644 index 00000000000..91f696dbef0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/RevealCardsFromLibraryUntilEffect.java @@ -0,0 +1,106 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Library; +import mage.players.Player; + +/** + * + * @author Styxo + */ +public class RevealCardsFromLibraryUntilEffect extends OneShotEffect { + + private FilterCard filter; + + public RevealCardsFromLibraryUntilEffect(FilterCard filter) { + super(Outcome.ReturnToHand); + this.filter = filter; + this.staticText = "reveal cards from the top of your library until you reveal a " + filter.getMessage() + ". Put that card into your hand and the rest on the bottom of your library in a random order"; + } + + public RevealCardsFromLibraryUntilEffect(final RevealCardsFromLibraryUntilEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public RevealCardsFromLibraryUntilEffect copy() { + return new RevealCardsFromLibraryUntilEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && controller.getLibrary().size() > 0) { + Cards cards = new CardsImpl(); + Library library = controller.getLibrary(); + Card card = null; + do { + card = library.removeFromTop(game); + if (card != null) { + cards.add(card); + } + } while (library.size() > 0 && card != null && !filter.match(card, game)); + // reveal cards + if (!cards.isEmpty()) { + controller.revealCards(sourceObject.getIdName(), cards, game); + if (filter.match(card, game)) { + // put creature card in hand + controller.moveCards(card, Zone.HAND, source, game); + // remove it from revealed card list + cards.remove(card); + } + // Put the rest on the bottom of your library in a random order + Cards randomOrder = new CardsImpl(); + while (cards.size() > 0) { + card = cards.getRandom(game); + if (card != null) { + cards.remove(card); + randomOrder.add(card); + controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.HAND, false, false); + } + } + controller.putCardsOnBottomOfLibrary(randomOrder, game, source, false); + } + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SwordsToPlowsharesEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SwordsToPlowsharesEffect.java new file mode 100644 index 00000000000..7cd7f595295 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SwordsToPlowsharesEffect.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * @author JRHerlehy + */ +public class SwordsToPlowsharesEffect extends OneShotEffect { + + public SwordsToPlowsharesEffect() { + super(Outcome.GainLife); + staticText = "Its controller gains life equal to its power"; + } + + public SwordsToPlowsharesEffect(final SwordsToPlowsharesEffect effect) { + super(effect); + } + + @Override + public SwordsToPlowsharesEffect copy() { + return new SwordsToPlowsharesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + Player player = game.getPlayer(permanent.getControllerId()); + if (player != null) { + player.gainLife(permanent.getPower().getValue(), game); + } + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/cards/FrameStyle.java b/Mage/src/main/java/mage/cards/FrameStyle.java index 3a006b61cc3..add2795cc52 100644 --- a/Mage/src/main/java/mage/cards/FrameStyle.java +++ b/Mage/src/main/java/mage/cards/FrameStyle.java @@ -14,27 +14,22 @@ public enum FrameStyle { * The default card frame, normal M15 card frames */ M15_NORMAL(BorderType.M15, false), - /** * Battle for Zendkiar full art basic lands */ BFZ_FULL_ART_BASIC(BorderType.M15, true), - /** * Kaladesh block Inventions */ KLD_INVENTION(BorderType.M15, false), - /** * Zenkikar full art lands */ ZEN_FULL_ART_BASIC(BorderType.MOD, true), - /** * Unhinged full art lands */ UNH_FULL_ART_BASIC(BorderType.SPC, true), - /** * Unglued full art lands */ @@ -45,30 +40,26 @@ public enum FrameStyle { */ public enum BorderType { /** - * Various specialty borders - * EG: Unhinged, Unglued + * Various specialty borders EG: Unhinged, Unglued */ SPC, - /** * Old border cards */ OLD, - /** * Modern border cards (8th -> Theros) */ MOD, - /** * M15 border cards (M14 -> current) */ M15 } - - private BorderType borderType; - private boolean isFullArt; - + + private final BorderType borderType; + private final boolean isFullArt; + public BorderType getBorderType() { return borderType; } @@ -76,7 +67,7 @@ public enum FrameStyle { public boolean isFullArt() { return isFullArt; } - + FrameStyle(BorderType borderType, boolean isFullArt) { this.borderType = borderType; this.isFullArt = isFullArt; diff --git a/Mage/src/main/java/mage/designations/Designation.java b/Mage/src/main/java/mage/designations/Designation.java new file mode 100644 index 00000000000..ecf203ff47d --- /dev/null +++ b/Mage/src/main/java/mage/designations/Designation.java @@ -0,0 +1,212 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.designations; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.ObjectColor; +import mage.abilities.Abilities; +import mage.abilities.AbilitiesImpl; +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.cards.FrameStyle; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.events.ZoneChangeEvent; +import mage.util.GameLog; + +/** + * + * @author LevelX2 + */ +public abstract class Designation implements MageObject { + + private static List emptyList = new ArrayList(); + private static ObjectColor emptyColor = new ObjectColor(); + private static ManaCosts emptyCost = new ManaCostsImpl(); + + private String name; + private UUID id; + private FrameStyle frameStyle; + private Abilities abilites = new AbilitiesImpl<>(); + private String expansionSetCodeForImage; + + public Designation(String name, String expansionSetCode) { + this.name = name; + this.id = UUID.randomUUID(); + this.frameStyle = FrameStyle.M15_NORMAL; + this.expansionSetCodeForImage = expansionSetCode; + } + + public Designation(final Designation designation) { + this.id = designation.id; + this.name = designation.name; + this.frameStyle = designation.frameStyle; + this.abilites = designation.abilites.copy(); + } + + public abstract void start(Game game, UUID controllerId); + + @Override + public FrameStyle getFrameStyle() { + return frameStyle; + } + + public void assignNewId() { + this.id = UUID.randomUUID(); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getIdName() { + return getName() + " [" + getId().toString().substring(0, 3) + "]"; + } + + @Override + public String getImageName() { + return this.name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + public void addAbility(Ability ability) { + ability.setSourceId(id); + abilites.add(ability); + } + + @Override + public Abilities getAbilities() { + return abilites; + } + + @Override + public ObjectColor getFrameColor(Game game) { + return emptyColor; + } + + @Override + public UUID getId() { + return this.id; + } + + public void setExpansionSetCodeForImage(String expansionSetCodeForImage) { + this.expansionSetCodeForImage = expansionSetCodeForImage; + } + + public String getExpansionSetCodeForImage() { + return expansionSetCodeForImage; + } + + @Override + public String getLogName() { + return GameLog.getColoredObjectIdName(this); + } + + @Override + public List getCardType() { + return emptyList; + } + + @Override + public List getSubtype(Game game) { + return emptyList; + } + + @Override + public boolean hasSubtype(String subtype, Game game) { + return false; + } + + @Override + public List getSupertype() { + return emptyList; + } + + @Override + public boolean hasAbility(UUID abilityId, Game game) { + return abilites.containsKey(abilityId); + } + + @Override + public ObjectColor getColor(Game game) { + return emptyColor; + } + + @Override + public ManaCosts getManaCost() { + return emptyCost; + } + + @Override + public int getConvertedManaCost() { + return 0; + } + + @Override + public MageInt getPower() { + return MageInt.EmptyMageInt; + } + + @Override + public MageInt getToughness() { + return MageInt.EmptyMageInt; + } + + @Override + public int getStartingLoyalty() { + return 0; + } + + @Override + public void adjustCosts(Ability ability, Game game) { + } + + @Override + public void adjustTargets(Ability ability, Game game) { + } + + @Override + public void setCopy(boolean isCopy) { + } + + @Override + public boolean isCopy() { + return false; + } + + @Override + public Designation copy() { + return this; + } + + @Override + public int getZoneChangeCounter(Game game) { + return 1; // Emblems can't move zones until now so return always 1 + } + + @Override + public void updateZoneChangeCounter(Game game, ZoneChangeEvent event) { + throw new UnsupportedOperationException("Unsupported operation"); + } + + @Override + public void setZoneChangeCounter(int value, Game game) { + throw new UnsupportedOperationException("Unsupported operation"); + } + +} diff --git a/Mage/src/main/java/mage/designations/Monarch.java b/Mage/src/main/java/mage/designations/Monarch.java new file mode 100644 index 00000000000..1277945e439 --- /dev/null +++ b/Mage/src/main/java/mage/designations/Monarch.java @@ -0,0 +1,152 @@ +/* +* 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.designations; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.effects.common.BecomesMonarchTargetEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class Monarch extends Designation { + + public Monarch() { + super("The Monarch", "CN2"); + addAbility(new MonarchDrawTriggeredAbility()); + addAbility(new MonarchDealsCombatDamageToAPlayerTriggeredAbility()); + } + + /** + * + * @param game + * @param controllerId + */ + @Override + public void start(Game game, UUID controllerId) { + + } + +} + +// At the beginning of the monarch’s end step, that player draws a card +class MonarchDrawTriggeredAbility extends BeginningOfEndStepTriggeredAbility { + + public MonarchDrawTriggeredAbility() { + super(Zone.ALL, new DrawCardTargetEffect(1), TargetController.ANY, null, false); + } + + public MonarchDrawTriggeredAbility(final MonarchDrawTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getMonarchId() != null && event.getPlayerId().equals(game.getMonarchId())) { + setControllerId(game.getMonarchId()); + getEffects().get(0).setTargetPointer(new FixedTarget(game.getMonarchId())); + return true; + } + return false; + } + + @Override + public MonarchDrawTriggeredAbility copy() { + return new MonarchDrawTriggeredAbility(this); + } + + @Override + public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { + return true; + } + + @Override + public String getRule() { + return "At the beginning of the monarch’s end step, that player draws a card."; + } +} + +// Whenever a creature deals combat damage to the monarch, its controller becomes the monarch. +class MonarchDealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbilityImpl { + + public MonarchDealsCombatDamageToAPlayerTriggeredAbility() { + super(Zone.ALL, new BecomesMonarchTargetEffect(), false); + } + + public MonarchDealsCombatDamageToAPlayerTriggeredAbility(final MonarchDealsCombatDamageToAPlayerTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (((DamagedPlayerEvent) event).isCombatDamage()) { + MageObject damagingObject = game.getObject(event.getSourceId()); + if (damagingObject != null + && damagingObject instanceof Permanent + && damagingObject.getCardType().contains(CardType.CREATURE) + && event.getTargetId().equals(game.getMonarchId())) { + setControllerId(event.getPlayerId()); + getEffects().get(0).setTargetPointer(new FixedTarget(((Permanent) damagingObject).getControllerId())); + return true; + } + } + return false; + } + + @Override + public MonarchDealsCombatDamageToAPlayerTriggeredAbility copy() { + return new MonarchDealsCombatDamageToAPlayerTriggeredAbility(this); + } + + @Override + public boolean isInUseableZone(Game game, MageObject source, GameEvent event) { + return true; + } + + @Override + public String getRule() { + return "Whenever a creature deals combat damage to the monarch, its controller becomes the monarch."; + } +} diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index df561aea631..8425f4b4d4a 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -81,6 +81,8 @@ import mage.constants.SpellAbilityType; import mage.constants.Zone; import mage.counters.CounterType; import mage.counters.Counters; +import mage.designations.Designation; +import mage.designations.Monarch; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.FilterPermanent; @@ -385,11 +387,11 @@ public abstract class GameImpl implements Game, Serializable { object = getCard(objectId); if (object == null) { -// for (CommandObject commandObject : state.getCommand()) { -// if (commandObject.getId().equals(objectId)) { -// return commandObject; -// } -// } + for (Designation designation : state.getDesignations()) { + if (designation.getId().equals(objectId)) { + return designation; + } + } // can be an ability of a sacrificed Token trying to get it's source object object = getLastKnownInformation(objectId, Zone.BATTLEFIELD); } @@ -2916,6 +2918,9 @@ public abstract class GameImpl implements Game, Serializable { @Override public void setMonarchId(Ability source, UUID monarchId) { Player newMonarch = getPlayer(monarchId); + if (getMonarchId() == null) { + getState().addDesignation(new Monarch(), this, monarchId); + } if (newMonarch != null) { getState().setMonarchId(monarchId); informPlayers(newMonarch.getLogName() + " is the monarch"); diff --git a/Mage/src/main/java/mage/game/GameState.java b/Mage/src/main/java/mage/game/GameState.java index 47e113e3044..6b42e627eac 100644 --- a/Mage/src/main/java/mage/game/GameState.java +++ b/Mage/src/main/java/mage/game/GameState.java @@ -58,6 +58,7 @@ import mage.abilities.effects.Effect; import mage.cards.Card; import mage.cards.SplitCard; import mage.constants.Zone; +import mage.designations.Designation; import mage.game.combat.Combat; import mage.game.combat.CombatGroup; import mage.game.command.Command; @@ -113,6 +114,7 @@ public class GameState implements Serializable, Copyable { private UUID monarchId; // player that is the monarch private SpellStack stack; private Command command; + private List designations = new ArrayList<>(); private Exile exile; private Battlefield battlefield; private int turnNum = 1; @@ -170,6 +172,7 @@ public class GameState implements Serializable, Copyable { this.stack = state.stack.copy(); this.command = state.command.copy(); + this.designations.addAll(state.designations); this.exile = state.exile.copy(); this.battlefield = state.battlefield.copy(); this.turnNum = state.turnNum; @@ -219,6 +222,7 @@ public class GameState implements Serializable, Copyable { this.monarchId = state.monarchId; this.stack = state.stack; this.command = state.command; + this.designations = state.designations; this.exile = state.exile; this.battlefield = state.battlefield; this.turnNum = state.turnNum; @@ -461,6 +465,10 @@ public class GameState implements Serializable, Copyable { return exile; } + public List getDesignations() { + return designations; + } + public Command getCommand() { return command; } @@ -859,6 +867,14 @@ public class GameState implements Serializable, Copyable { } } + public void addDesignation(Designation designation, Game game, UUID controllerId) { + getDesignations().add(designation); + for (Ability ability : designation.getAbilities()) { + ability.setControllerId(controllerId); + addAbility(ability, designation.getId(), null); + } + } + public void addCommandObject(CommandObject commandObject) { getCommand().add(commandObject); setZone(commandObject.getId(), Zone.COMMAND); @@ -1026,6 +1042,7 @@ public class GameState implements Serializable, Copyable { stack.clear(); exile.clear(); command.clear(); + designations.clear(); revealed.clear(); lookedAt.clear(); turnNum = 0; diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java index c3afd1477bf..58c89c0b5b1 100644 --- a/Mage/src/main/java/mage/game/combat/Combat.java +++ b/Mage/src/main/java/mage/game/combat/Combat.java @@ -339,8 +339,17 @@ public class Combat implements Serializable, Copyable { // No need to attack a special defender if (defendersForcedToAttack.isEmpty()) { if (defendersForcedToAttack.isEmpty()) { - if (defendersCostlessAttackable.size() == 1) { - player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false); + if (defendersCostlessAttackable.size() >= 1) { + if (defenders.size() == 1) { + player.declareAttacker(creature.getId(), defenders.iterator().next(), game, false); + } else { + TargetDefender target = new TargetDefender(defenders, creature.getId()); + target.setRequired(true); + target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack"); + if (player.chooseTarget(Outcome.Damage, target, null, game)) { + player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false); + } + } } } else { TargetDefender target = new TargetDefender(defendersCostlessAttackable, creature.getId()); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index dd0ccecaa07..86f053fa9d0 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1231,14 +1231,14 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean triggerAbility(TriggeredAbility source, Game game) { - if (source == null) { + public boolean triggerAbility(TriggeredAbility triggeredAbility, Game game) { + if (triggeredAbility == null) { logger.warn("Null source in triggerAbility method"); throw new IllegalArgumentException("source TriggeredAbility must not be null"); } //20091005 - 603.3c, 603.3d int bookmark = game.bookmarkState(); - TriggeredAbility ability = source.copy(); + TriggeredAbility ability = triggeredAbility.copy(); MageObject sourceObject = ability.getSourceObject(game); if (sourceObject != null) { sourceObject.adjustTargets(ability, game); @@ -1260,7 +1260,7 @@ public abstract class PlayerImpl implements Player, Serializable { return true; } } - restoreState(bookmark, source.getRule(), game); // why restore is needed here? (to remove the triggered ability from the stack) + restoreState(bookmark, triggeredAbility.getRule(), game); // why restore is needed here? (to remove the triggered ability from the stack) return false; } @@ -1829,9 +1829,6 @@ public abstract class PlayerImpl implements Player, Serializable { if (sourceAbilities != null && sourceAbilities.containsKey(InfectAbility.getInstance().getId())) { addCounters(CounterType.POISON.createInstance(actualDamage), game); } else { - if (getId().equals(game.getMonarchId()) && sourceControllerId != null) { - game.setMonarchId(null, sourceControllerId); - } GameEvent damageToLifeLossEvent = new GameEvent(EventType.DAMAGE_CAUSES_LIFE_LOSS, playerId, sourceId, playerId, actualDamage, combatDamage); if (!game.replaceEvent(damageToLifeLossEvent)) { this.loseLife(damageToLifeLossEvent.getAmount(), game, combatDamage); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 2fb11353a84..c11d8329273 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -8089,6 +8089,7 @@ Rise from the Tides|Friday Night Magic|197|U|{5}{U}|Sorcery|||Create a tapped 2/ Fiery Temper|Friday Night Magic|198|U|{1}{R}{R}|Instant|||Fiery Temper deals 3 damage to target creature or player.$Madness {R} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)| Call the Bloodline|Friday Night Magic|199|Special|{1}{B}|Enchantment|||{1}, Discard a card: Create a 1/1 black Vampire Knight creature token with lifelink. Activate this ability only once each turn.| Noose Constrictor|Friday Night Magic|200|Special|{1}{G}|Creature - Snake|2|2|Reach$Discard a card: Noose Constrictor gets +1/+1 until end of turn.| +Fortune's Favor|Friday Night Magic|201|Special|{3}{U}|Instant|||Target opponent looks at the top four cards of your library and separates them into a face-down pile and a face-up pile. Put one pile into your hand and the other into your graveyard.| Akroma, Angel of Fury|From the Vault: Angels|1|M|{5}{R}{R}{R}|Legendary Creature - Angel|6|6|Akroma, Angel of Fury can't be countered.$Flying, trample, protection from white and from blue${R}: Akroma, Angel of Fury gets +1/+0 until end of turn.$Morph {3}{R}{R}{R} You may cast this card face downn as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)| Akroma, Angel of Wrath|From the Vault: Angels|2|M|{5}{W}{W}{W}|Legendary Creature - Angel|6|6|Flying, first strike, vigilance, trample, haste, protection from black and from red| Archangel of Strife|From the Vault: Angels|3|M|{5}{W}{W}|Creature - Angel|6|6|Flying$As Archangel of Strife enters the battlefield, each player chooses war or peace.$Creatures controlled by players who chose war get +3/+0.$Creatures controlled by players who chose peace get +0/+3.| @@ -10731,6 +10732,7 @@ Endbringer|Launch Party|34|R|{5}{C}|Creature - Eldrazi|5|5|Untap Endbringer duri Angel of Deliverance|Launch Party|35|R|{6}{W}{W}|Creature - Angel|6|6|Flying$Delirium — Whenever Angel of Deliverance deals damage, if there are four or more card types among cards in your graveyard, exile target creature an opponent controls.| 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.| 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.| @@ -28605,6 +28607,8 @@ Unsubstantiate|Game Day|53|U|{1}{U}|Instant|||Return target spell or creature to Heron's Grace Champion|Game Day|54|R|{2}{G}{W}|Creature - Human Knight|3|3|Flash$Lifelink$When Heron's Grace Champion enters the battlefield, other Humans you control get +1/+1 and gain lifelink until end of turn.| 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.| +Yaheeni's Expertise|Aether Revolt|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.| 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.$| @@ -28835,6 +28839,7 @@ Assembled Alphas|Media Inserts|160|R|{5}{R}|Creature - Wolf|5|5|Whenever Assembl Ulvenwald Observer|Media Inserts|161|R|{4}{G}{G}|Creature - Treefolk|6|6|Whenever a creature you control with toughness 4 or greater dies, draw a card.| 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.| 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. | @@ -30321,3 +30326,15 @@ Mountain|Commander 2016|348|L||Basic Land - Mountain|||| Forest|Commander 2016|349|L||Basic Land - Forest|||| Forest|Commander 2016|350|L||Basic Land - Forest|||| Forest|Commander 2016|351|L||Basic Land - Forest|||| +Disallow|Aether Revolt|31|R|{1}{U}{U}|Instant|||Counter target spell, activated ability, or triggered ability. (Mana abilities can't be targeted.)| +Trophy Mage|Aether Revolt|48|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.| +Battle at the Bridge|Aether Revolt|53|R|{X}{B}|Sorcery|||Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.)$Target creature gets -X/-X until end of turn. You gain X life.| +Yaheeni'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.| +Pia's Revolution|Aether Revolt|91|R|{2}{R}|Enchantment|||Whenever a nontoken artifact is put into your graveyard from the battlefield, return that card to your hand unless target opponent has Pia's Revolution deal 3 damage to him or her.| +Quicksmith Rebel|Aether Revolt|93|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.| +Ajani Unyielding|Aether Revolt|127|M|{4}{G}{W}|Planeswalker - Ajani|||+2: Reveal the top three cards of your library. Put all nonland permanent cards revealed this way into your hand and the rest on the bottom of your library in any order.$-2: Exile target creature. Its controller gains life equal to its power.$-9: Put five +1/+1 counters on each creature you control and five loyalty counters on each other planeswalker you control.| +Dark Intimations|Aether Revolt|128|R|{2}{U}{B}{R}|Sorcery|||Each opponent sacrifices a creature or planeswalker, then discards a card. You return a creature or planeswalker card from your graveyard to your hand, then draw a card.$When you cast a Bolas planeswalker spell, exile Dark Intimations from your graveyard. That planeswalker enters the battlefield with an additional loyalty counter on it.| +Heart of Kiran|Aether Revolt|153|M|{2}|Legendary Artifact - Vehicle|4|4|Flying, vigilance$Crew 3 (Tap any number of creatures you control with total power 3 or more: This Vehicle becomes an artifact creature until end of turn.)$You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost.| +Scrap Trawler|Aether Revolt|175|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.| +Ajani, Valiant Protector|Aether Revolt|185|M|{4}{G}{W}|Planeswalker - Ajani|||+2: Put two +1/+1 counters on up to one target creature.$+1: Reveal cards from the top of your library until you reveal a creature card. Put that card into your hand and the rest on the bottom of your library in a random order.$-11: Put X +1/+1 counters on target creature, where X is your life total. That creature gains trample until end of turn.| +Tezzeret, Master of Metal|Aether Revolt|190|M|{4}{U}{B}|Planeswalker - Tezzeret|||+1: Reveal cards from the top of your library until you reveal an artifact card. Put that card into your hand and the rest on the bottom of your library in a random order.$-3: Target opponent loses life equal to the number of artifacts you control.$-8: Gain control of all artifacts and creatures target opponent controls.| \ No newline at end of file