diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java index 287579efcb..d58a0942a2 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGeneratorDialog.java @@ -42,6 +42,7 @@ import mage.cards.decks.Deck; import mage.client.MageFrame; import mage.client.dialog.PreferencesDialog; import mage.client.util.gui.ColorsChooser; +import mage.client.util.gui.FastSearchUtil; import mage.client.util.sets.ConstructedFormats; /** @@ -106,21 +107,38 @@ public class DeckGeneratorDialog { c.weightx = 0.10; mainPanel.add(formatSetText, c); - // Format/set dropdown + // Format/set dropdown with search button + JPanel setPanel = new JPanel(); + setPanel.setLayout(new javax.swing.BoxLayout(setPanel, javax.swing.BoxLayout.LINE_AXIS)); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 1; c.gridy = 1; c.ipadx = 30; c.insets = new Insets(5, 10, 0, 10); - c.weightx = 0.90; + c.weightx = 0.80; + mainPanel.add(setPanel, c); + cbSets = new JComboBox<>(ConstructedFormats.getTypes()); cbSets.setSelectedIndex(0); - mainPanel.add(cbSets, c); + cbSets.setAlignmentX(0.0F); + setPanel.add(cbSets); String prefSet = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_DECK_GENERATOR_SET, null); if (prefSet != null) { cbSets.setSelectedItem(prefSet); } + + JButton btn = new JButton(); + btn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/search_32.png"))); + btn.setToolTipText(FastSearchUtil.DEFAULT_EXPANSION_TOOLTIP_MESSAGE); + btn.setAlignmentX(1.0F); + btn.setPreferredSize(new java.awt.Dimension(32, 32)); + btn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + FastSearchUtil.showFastSearchForStringComboBox(cbSets, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); + } + }); + //setPanel.add(btn, c); // TODO: can't show pickdialog here... need to replace standard modal dialog (JOptionPane) to internal mage dialog // Deck size label c.fill = GridBagConstraints.HORIZONTAL; diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java index a8ecb46622..d889a61e12 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -47,13 +47,12 @@ import mage.cards.Sets; import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; -import mage.choices.ChoiceImpl; import mage.client.MageFrame; import mage.client.cards.*; import mage.client.constants.Constants.SortBy; import mage.client.deckeditor.table.TableModel; -import mage.client.dialog.PickChoiceDialog; import mage.client.util.GUISizeHelper; +import mage.client.util.gui.FastSearchUtil; import mage.client.util.sets.ConstructedFormats; import mage.constants.CardType; import mage.filter.FilterCard; @@ -215,8 +214,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene this.cards.add(card); } filterCards(); - } - + } + public void loadCards(BigCard bigCard) { this.bigCard = bigCard; this.btnBooster.setVisible(true); @@ -226,40 +225,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene // cbExpansionSet.setModel(new DefaultComboBoxModel<>(ConstructedFormats.getTypes())); // Action event on Expansion set triggers loadCards method cbExpansionSet.setSelectedIndex(0); - } - - public void doFastExpansionSearch(){ - mage.choices.Choice choice = new ChoiceImpl(false); - - // collect data from expansion combobox (String) - DefaultComboBoxModel comboModel = (DefaultComboBoxModel)cbExpansionSet.getModel(); - Map choiceItems = new HashMap<>(comboModel.getSize()); - Map choiceSorting = new HashMap<>(comboModel.getSize()); - String item; - - for(int i = 0; i < comboModel.getSize() - 1; i++){ - item = (String)comboModel.getElementAt(i); - choiceItems.put(item, item); - choiceSorting.put(item, i); // need so sorting - } - - choice.setKeyChoices(choiceItems); - choice.setSortData(choiceSorting); - choice.setMessage("Select set or expansion"); - - // current selection value restore - String needSelectValue; - needSelectValue = (String)comboModel.getSelectedItem(); - - // ask for new value - PickChoiceDialog dlg = new PickChoiceDialog(); - dlg.setWindowSize(300, 500); - dlg.showDialog(choice, needSelectValue); - if(choice.isChosen()){ - item = choice.getChoiceKey(); - comboModel.setSelectedItem(item); - } - } + } private FilterCard buildFilter() { FilterCard filter = new FilterCard(); @@ -1255,7 +1221,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene }//GEN-LAST:event_chkRulesActionPerformed private void btnExpansionSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExpansionSearchActionPerformed - doFastExpansionSearch(); + FastSearchUtil.showFastSearchForStringComboBox(cbExpansionSet, "Select set or expansion"); }//GEN-LAST:event_btnExpansionSearchActionPerformed private void toggleViewMode() { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/CollectionViewerPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/CollectionViewerPanel.java index b90b11026e..296f85bead 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/CollectionViewerPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/CollectionViewerPanel.java @@ -44,6 +44,7 @@ import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.dialog.PreferencesDialog; import mage.client.plugins.impl.Plugins; +import mage.client.util.gui.FastSearchUtil; import mage.client.util.sets.ConstructedFormats; import org.apache.log4j.Logger; @@ -76,31 +77,56 @@ public final class CollectionViewerPanel extends JPanel { } public void initComponents() { - jPanel1 = new javax.swing.JPanel(); - jPanel1.setOpaque(false); + buttonsPanel = new javax.swing.JPanel(); + buttonsPanel.setOpaque(false); bigCard = new BigCard(); - BoxLayout boxlayout = new BoxLayout(jPanel1, BoxLayout.PAGE_AXIS); - jPanel1.setLayout(boxlayout); + BoxLayout boxlayout = new BoxLayout(buttonsPanel, BoxLayout.PAGE_AXIS); + buttonsPanel.setLayout(boxlayout); btnExit = new javax.swing.JButton(); btnExit.setAlignmentX(Component.LEFT_ALIGNMENT); - jPanel1.add(btnExit); + buttonsPanel.add(btnExit); JLabel label1 = new JLabel("Choose format:"); label1.setAlignmentX(Component.LEFT_ALIGNMENT); label1.setForeground(Color.white); - jPanel1.add(label1); + buttonsPanel.add(label1); + // SELECT SET + // panel + setPanel = new JPanel(); + setPanel.setLayout(new javax.swing.BoxLayout(setPanel, javax.swing.BoxLayout.LINE_AXIS)); + setPanel.setOpaque(false); + setPanel.setPreferredSize(new Dimension(200, 25)); + setPanel.setMaximumSize(new Dimension(200, 25)); + setPanel.setAlignmentX(Component.LEFT_ALIGNMENT); + buttonsPanel.add(setPanel); + // combo set formats = new JComboBox<>(ConstructedFormats.getTypes()); formats.setSelectedItem(ConstructedFormats.getDefault()); - formats.setPreferredSize(new Dimension(250, 25)); - formats.setMaximumSize(new Dimension(250, 25)); - formats.setAlignmentX(Component.LEFT_ALIGNMENT); - jPanel1.add(formats); + formats.setAlignmentX(0.0F); + formats.setMinimumSize(new Dimension(50, 25)); + formats.setPreferredSize(new Dimension(50, 25)); + formats.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25)); + setPanel.add(formats); + // search button + btnSetFastSearch = new JButton(); + btnSetFastSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/search_24.png"))); + btnSetFastSearch.setToolTipText(FastSearchUtil.DEFAULT_EXPANSION_TOOLTIP_MESSAGE); + btnSetFastSearch.setAlignmentX(1.0F); + btnSetFastSearch.setMinimumSize(new java.awt.Dimension(24, 24)); + btnSetFastSearch.setPreferredSize(new java.awt.Dimension(32, 32)); + btnSetFastSearch.setMaximumSize(new java.awt.Dimension(32, 32)); + btnSetFastSearch.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + FastSearchUtil.showFastSearchForStringComboBox(formats, FastSearchUtil.DEFAULT_EXPANSION_SEARCH_MESSAGE); + } + }); + setPanel.add(btnSetFastSearch); JLabel label2 = new JLabel("Choose size:"); label2.setAlignmentX(Component.LEFT_ALIGNMENT); label2.setForeground(Color.white); - jPanel1.add(label2); + buttonsPanel.add(label2); small3x3 = new JRadioButton("3x3"); small3x3.setForeground(Color.white); @@ -111,7 +137,7 @@ public final class CollectionViewerPanel extends JPanel { mageBook.updateSize(MageBook.LAYOUT_3x3); MageFrame.getPreferences().put(LAYOYT_CONFIG_KEY, MageBook.LAYOUT_3x3); }); - jPanel1.add(small3x3); + buttonsPanel.add(small3x3); big4x4 = new JRadioButton("4x4"); big4x4.setForeground(Color.white); @@ -121,19 +147,19 @@ public final class CollectionViewerPanel extends JPanel { mageBook.updateSize(MageBook.LAYOUT_4x4); MageFrame.getPreferences().put(LAYOYT_CONFIG_KEY, MageBook.LAYOUT_4x4); }); - jPanel1.add(big4x4); + buttonsPanel.add(big4x4); JLabel label3 = new JLabel("Switch tabs:"); label3.setAlignmentX(Component.LEFT_ALIGNMENT); label3.setForeground(Color.white); - jPanel1.add(label3); + buttonsPanel.add(label3); JPanel buttonPanel = new JPanel(); buttonPanel.setPreferredSize(new Dimension(200, 100)); buttonPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 100)); buttonPanel.setOpaque(false); buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - jPanel1.add(buttonPanel); + buttonsPanel.add(buttonPanel); JButton prev = new JButton("Prev"); prev.addActionListener(e -> mageBook.prev()); @@ -146,13 +172,13 @@ public final class CollectionViewerPanel extends JPanel { JLabel label4 = new JLabel("Show cards or tokens:"); label3.setAlignmentX(Component.LEFT_ALIGNMENT); label3.setForeground(Color.white); - jPanel1.add(label4); + buttonsPanel.add(label4); JCheckBox cardsOrTokens = new JCheckBox("Display Cards"); cardsOrTokens.setSelected(true); cardsOrTokens.setToolTipText("Select to show Cards or Tokens(and emblems) for the chosen set"); cardsOrTokens.addActionListener(e -> mageBook.cardsOrTokens(cardsOrTokens.isSelected())); - jPanel1.add(cardsOrTokens); + buttonsPanel.add(cardsOrTokens); formats.addActionListener(e -> { if (mageBook != null) { @@ -162,12 +188,12 @@ public final class CollectionViewerPanel extends JPanel { } }); - jPanel1.add(Box.createVerticalGlue()); + buttonsPanel.add(Box.createVerticalGlue()); bigCard.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); bigCard.setAlignmentX(Component.LEFT_ALIGNMENT); bigCard.setAlignmentY(Component.BOTTOM_ALIGNMENT); - jPanel1.add(bigCard); + buttonsPanel.add(bigCard); jPanel2 = new MageBookContainer(); jPanel2.setOpaque(false); @@ -177,13 +203,13 @@ public final class CollectionViewerPanel extends JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 604, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE) ); @@ -241,8 +267,10 @@ public final class CollectionViewerPanel extends JPanel { } } - private javax.swing.JPanel jPanel1; + private javax.swing.JPanel buttonsPanel; private javax.swing.JPanel jPanel2; + private javax.swing.JPanel setPanel; + private javax.swing.JButton btnSetFastSearch; private mage.client.cards.BigCard bigCard; private javax.swing.JButton btnExit; private JComboBox formats; diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java index d0b946fa0c..4cb7a20ec8 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java @@ -750,7 +750,7 @@ public class ConnectDialog extends MageDialog { } choice.setKeyChoices(choiceItems); - choice.setMessage("Select your coutry"); + choice.setMessage("Select your country"); // current selection value restore String needSelectValue = null; diff --git a/Mage.Client/src/main/java/mage/client/util/gui/FastSearchUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/FastSearchUtil.java new file mode 100644 index 0000000000..9d88e27137 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/gui/FastSearchUtil.java @@ -0,0 +1,58 @@ +package mage.client.util.gui; + +import mage.choices.ChoiceImpl; +import mage.client.dialog.PickChoiceDialog; + +import javax.swing.*; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author JayDi85 + */ +public class FastSearchUtil { + + public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion"; + public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion"; + + /** + * Show fast choice modal dialog with incremental searching for any string combobox components + * @param combo combobox control with default data model + * @param chooseMessage caption message for dialog + */ + public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage){ + // fast search/choice dialog for string combobox + + mage.choices.Choice choice = new ChoiceImpl(false); + + // collect data from expansion combobox (String) + DefaultComboBoxModel comboModel = (DefaultComboBoxModel)combo.getModel(); + Map choiceItems = new HashMap<>(comboModel.getSize()); + Map choiceSorting = new HashMap<>(comboModel.getSize()); + String item; + + for(int i = 0; i < comboModel.getSize() - 1; i++){ + item = (String)comboModel.getElementAt(i); + choiceItems.put(item, item); + choiceSorting.put(item, i); // need so sorting + } + + choice.setKeyChoices(choiceItems); + choice.setSortData(choiceSorting); + choice.setMessage(chooseMessage); + + // current selection value restore + String needSelectValue; + needSelectValue = (String)comboModel.getSelectedItem(); + + // ask for new value + PickChoiceDialog dlg = new PickChoiceDialog(); + dlg.setWindowSize(300, 500); + dlg.showDialog(choice, needSelectValue); + if(choice.isChosen()){ + item = choice.getChoiceKey(); + comboModel.setSelectedItem(item); + } + } +} diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java new file mode 100644 index 0000000000..26a495c026 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/src/mage/tournament/cubes/VintageCubeDecember2017.java @@ -0,0 +1,555 @@ +package mage.tournament.cubes; + +import mage.game.draft.DraftCube; + +/** + * + * @author JayDi85 + */ +public class VintageCubeDecember2017 extends DraftCube { + + public VintageCubeDecember2017() { + super("MTGO Vintage Cube December 2017"); + + cubeCards.add(new DraftCube.CardIdentity("Mana Flare", "")); + cubeCards.add(new DraftCube.CardIdentity("Zurgo Bellstriker", "")); + cubeCards.add(new DraftCube.CardIdentity("Glorybringer", "")); + cubeCards.add(new DraftCube.CardIdentity("Burning of Xinye", "")); + cubeCards.add(new DraftCube.CardIdentity("Wildfire", "")); + cubeCards.add(new DraftCube.CardIdentity("Dismember", "")); + cubeCards.add(new DraftCube.CardIdentity("Magus of the Moon", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Dark-Dwellers", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Lavamancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Fiery Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Ruby", "")); + cubeCards.add(new DraftCube.CardIdentity("Jackal Pup", "")); + cubeCards.add(new DraftCube.CardIdentity("Stormbreath Dragon", "")); + cubeCards.add(new DraftCube.CardIdentity("Flametongue Kavu", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Pyromaster", "")); + cubeCards.add(new DraftCube.CardIdentity("Manic Vandal", "")); + cubeCards.add(new DraftCube.CardIdentity("Song of the Dryads", "")); + cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", "")); + cubeCards.add(new DraftCube.CardIdentity("Falkenrath Gorger", "")); + cubeCards.add(new DraftCube.CardIdentity("Hellrider", "")); + cubeCards.add(new DraftCube.CardIdentity("Siege-Gang Commander", "")); + cubeCards.add(new DraftCube.CardIdentity("Delver of Secrets", "")); + cubeCards.add(new DraftCube.CardIdentity("Strip Mine", "")); + cubeCards.add(new DraftCube.CardIdentity("Wasteland", "")); + cubeCards.add(new DraftCube.CardIdentity("Inferno Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Guide", "")); + cubeCards.add(new DraftCube.CardIdentity("Avalanche Riders", "")); + cubeCards.add(new DraftCube.CardIdentity("Thundermaw Hellkite", "")); + cubeCards.add(new DraftCube.CardIdentity("Koth of the Hammer", "")); + cubeCards.add(new DraftCube.CardIdentity("Firedrinker Satyr", "")); + cubeCards.add(new DraftCube.CardIdentity("Reckless Bushwhacker", "")); + cubeCards.add(new DraftCube.CardIdentity("Eidolon of the Great Revel", "")); + cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", "")); + cubeCards.add(new DraftCube.CardIdentity("Adanto Vanguard", "")); + cubeCards.add(new DraftCube.CardIdentity("Angel of Sanctions", "")); + cubeCards.add(new DraftCube.CardIdentity("Timely Reinforcements", "")); + cubeCards.add(new DraftCube.CardIdentity("Vryn Wingmare", "")); + cubeCards.add(new DraftCube.CardIdentity("Gideon of the Trials", "")); + cubeCards.add(new DraftCube.CardIdentity("Blade Splicer", "")); + cubeCards.add(new DraftCube.CardIdentity("Student of Warfare", "")); + cubeCards.add(new DraftCube.CardIdentity("Gideon, Ally of Zendikar", "")); + cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", "")); + cubeCards.add(new DraftCube.CardIdentity("Restoration Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Flickerwisp", "")); + cubeCards.add(new DraftCube.CardIdentity("Angel of Invention", "")); + cubeCards.add(new DraftCube.CardIdentity("Banisher Priest", "")); + cubeCards.add(new DraftCube.CardIdentity("Declaration in Stone", "")); + cubeCards.add(new DraftCube.CardIdentity("Thalia, Guardian of Thraben", "")); + cubeCards.add(new DraftCube.CardIdentity("Linvala, Keeper of Silence", "")); + cubeCards.add(new DraftCube.CardIdentity("Knight of the White Orchid", "")); + cubeCards.add(new DraftCube.CardIdentity("Fiend Hunter", "")); + cubeCards.add(new DraftCube.CardIdentity("Emeria Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Mother of Runes", "")); + cubeCards.add(new DraftCube.CardIdentity("Brimaz, King of Oreskos", "")); + cubeCards.add(new DraftCube.CardIdentity("Recruiter of the Guard", "")); + cubeCards.add(new DraftCube.CardIdentity("Soldier of the Pantheon", "")); + cubeCards.add(new DraftCube.CardIdentity("Porcelain Legionnaire", "")); + cubeCards.add(new DraftCube.CardIdentity("Selfless Spirit", "")); + cubeCards.add(new DraftCube.CardIdentity("Hero of Bladehold", "")); + cubeCards.add(new DraftCube.CardIdentity("Stoneforge Mystic", "")); + cubeCards.add(new DraftCube.CardIdentity("Spectral Procession", "")); + cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", "")); + cubeCards.add(new DraftCube.CardIdentity("Kytheon, Hero of Akros", "")); + cubeCards.add(new DraftCube.CardIdentity("Mirran Crusader", "")); + cubeCards.add(new DraftCube.CardIdentity("Silverblade Paladin", "")); + cubeCards.add(new DraftCube.CardIdentity("Linvala, the Preserver", "")); + cubeCards.add(new DraftCube.CardIdentity("Seeker of the Way", "")); + cubeCards.add(new DraftCube.CardIdentity("Legion's Landing", "")); + cubeCards.add(new DraftCube.CardIdentity("Lingering Souls", "")); + cubeCards.add(new DraftCube.CardIdentity("Leonin Relic-Warder", "")); + cubeCards.add(new DraftCube.CardIdentity("Parallax Wave", "")); + cubeCards.add(new DraftCube.CardIdentity("Disenchant", "")); + cubeCards.add(new DraftCube.CardIdentity("Awakening Zone", "")); + cubeCards.add(new DraftCube.CardIdentity("Elesh Norn, Grand Cenobite", "")); + cubeCards.add(new DraftCube.CardIdentity("Council's Judgment", "")); + cubeCards.add(new DraftCube.CardIdentity("Sun Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Elspeth, Knight-Errant", "")); + cubeCards.add(new DraftCube.CardIdentity("Faith's Fetters", "")); + cubeCards.add(new DraftCube.CardIdentity("Honor of the Pure", "")); + cubeCards.add(new DraftCube.CardIdentity("Bitterblossom", "")); + cubeCards.add(new DraftCube.CardIdentity("Wrath of God", "")); + cubeCards.add(new DraftCube.CardIdentity("Swords to Plowshares", "")); + cubeCards.add(new DraftCube.CardIdentity("Spear of Heliod", "")); + cubeCards.add(new DraftCube.CardIdentity("Day of Judgment", "")); + cubeCards.add(new DraftCube.CardIdentity("Leyline of Sanctity", "")); + cubeCards.add(new DraftCube.CardIdentity("Karakas", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, Vryn's Prodigy", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Pearl", "")); + cubeCards.add(new DraftCube.CardIdentity("Oblivion Ring", "")); + cubeCards.add(new DraftCube.CardIdentity("Path to Exile", "")); + cubeCards.add(new DraftCube.CardIdentity("Zealous Conscripts", "")); + cubeCards.add(new DraftCube.CardIdentity("Reveillark", "")); + cubeCards.add(new DraftCube.CardIdentity("Unexpectedly Absent", "")); + cubeCards.add(new DraftCube.CardIdentity("Armageddon", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Tithe", "")); + cubeCards.add(new DraftCube.CardIdentity("Ravages of War", "")); + cubeCards.add(new DraftCube.CardIdentity("Angel of Serenity", "")); + cubeCards.add(new DraftCube.CardIdentity("Balance", "")); + cubeCards.add(new DraftCube.CardIdentity("Enlightened Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Land Tax", "")); + cubeCards.add(new DraftCube.CardIdentity("Academy Ruins", "")); + cubeCards.add(new DraftCube.CardIdentity("Elspeth, Sun's Champion", "")); + cubeCards.add(new DraftCube.CardIdentity("Riftwing Cloudskate", "")); + cubeCards.add(new DraftCube.CardIdentity("Moat", "")); + cubeCards.add(new DraftCube.CardIdentity("Baneslayer Angel", "")); + cubeCards.add(new DraftCube.CardIdentity("Banishing Light", "")); + cubeCards.add(new DraftCube.CardIdentity("Sower of Temptation", "")); + cubeCards.add(new DraftCube.CardIdentity("Treachery", "")); + cubeCards.add(new DraftCube.CardIdentity("Augur of Bolas", "")); + cubeCards.add(new DraftCube.CardIdentity("Bribery", "")); + cubeCards.add(new DraftCube.CardIdentity("Force Spike", "")); + cubeCards.add(new DraftCube.CardIdentity("Torrential Gearhulk", "")); + cubeCards.add(new DraftCube.CardIdentity("Mulldrifter", "")); + cubeCards.add(new DraftCube.CardIdentity("Upheaval", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace Beleren", "")); + cubeCards.add(new DraftCube.CardIdentity("Spell Pierce", "")); + cubeCards.add(new DraftCube.CardIdentity("Commit // Memory", "")); + cubeCards.add(new DraftCube.CardIdentity("Tamiyo, the Moon Sage", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, the Mind Sculptor", "")); + cubeCards.add(new DraftCube.CardIdentity("Tezzeret the Seeker", "")); + cubeCards.add(new DraftCube.CardIdentity("Baral, Chief of Compliance", "")); + cubeCards.add(new DraftCube.CardIdentity("Phyrexian Metamorph", "")); + cubeCards.add(new DraftCube.CardIdentity("Frost Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Venser, Shaper Savant", "")); + cubeCards.add(new DraftCube.CardIdentity("Mental Misstep", "")); + cubeCards.add(new DraftCube.CardIdentity("Jace, Architect of Thought", "")); + cubeCards.add(new DraftCube.CardIdentity("Control Magic", "")); + cubeCards.add(new DraftCube.CardIdentity("Phantasmal Image", "")); + cubeCards.add(new DraftCube.CardIdentity("Consecrated Sphinx", "")); + cubeCards.add(new DraftCube.CardIdentity("Inkwell Leviathan", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Drain", "")); + cubeCards.add(new DraftCube.CardIdentity("Remand", "")); + cubeCards.add(new DraftCube.CardIdentity("Counterspell", "")); + cubeCards.add(new DraftCube.CardIdentity("Pestermite", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Leak", "")); + cubeCards.add(new DraftCube.CardIdentity("Vendilion Clique", "")); + cubeCards.add(new DraftCube.CardIdentity("Glen Elendra Archmage", "")); + cubeCards.add(new DraftCube.CardIdentity("Daze", "")); + cubeCards.add(new DraftCube.CardIdentity("Snapcaster Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Deceiver Exarch", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystic Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("True-Name Nemesis", "")); + cubeCards.add(new DraftCube.CardIdentity("Vedalken Shackles", "")); + cubeCards.add(new DraftCube.CardIdentity("Timetwister", "")); + cubeCards.add(new DraftCube.CardIdentity("Brainstorm", "")); + cubeCards.add(new DraftCube.CardIdentity("Empty the Warrens", "")); + cubeCards.add(new DraftCube.CardIdentity("Compulsive Research", "")); + cubeCards.add(new DraftCube.CardIdentity("Time Walk", "")); + cubeCards.add(new DraftCube.CardIdentity("Frantic Search", "")); + cubeCards.add(new DraftCube.CardIdentity("Cryptic Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Gush", "")); + cubeCards.add(new DraftCube.CardIdentity("Tinker", "")); + cubeCards.add(new DraftCube.CardIdentity("Time Spiral", "")); + cubeCards.add(new DraftCube.CardIdentity("Gitaxian Probe", "")); + cubeCards.add(new DraftCube.CardIdentity("Show and Tell", "")); + cubeCards.add(new DraftCube.CardIdentity("Mind's Desire", "")); + cubeCards.add(new DraftCube.CardIdentity("Palinchron", "")); + cubeCards.add(new DraftCube.CardIdentity("Fact or Fiction", "")); + cubeCards.add(new DraftCube.CardIdentity("Force of Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Impulse", "")); + cubeCards.add(new DraftCube.CardIdentity("Chart a Course", "")); + cubeCards.add(new DraftCube.CardIdentity("Ponder", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Sapphire", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancestral Vision", "")); + cubeCards.add(new DraftCube.CardIdentity("Preordain", "")); + cubeCards.add(new DraftCube.CardIdentity("Gifts Ungiven", "")); + cubeCards.add(new DraftCube.CardIdentity("Heartbeat of Spring", "")); + cubeCards.add(new DraftCube.CardIdentity("Gideon Jura", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancestral Recall", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystical Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Repeal", "")); + cubeCards.add(new DraftCube.CardIdentity("Thirst for Knowledge", "")); + cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", "")); + cubeCards.add(new DraftCube.CardIdentity("Trinket Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Shelldock Isle", "")); + cubeCards.add(new DraftCube.CardIdentity("Brain Freeze", "")); + cubeCards.add(new DraftCube.CardIdentity("Treasure Cruise", "")); + cubeCards.add(new DraftCube.CardIdentity("Turnabout", "")); + cubeCards.add(new DraftCube.CardIdentity("Dig Through Time", "")); + cubeCards.add(new DraftCube.CardIdentity("Thoughtseize", "")); + cubeCards.add(new DraftCube.CardIdentity("Braids, Cabal Minion", "")); + cubeCards.add(new DraftCube.CardIdentity("Desecration Demon", "")); + cubeCards.add(new DraftCube.CardIdentity("Hero's Downfall", "")); + cubeCards.add(new DraftCube.CardIdentity("Damnation", "")); + cubeCards.add(new DraftCube.CardIdentity("Shriekmaw", "")); + cubeCards.add(new DraftCube.CardIdentity("Liliana, Death's Majesty", "")); + cubeCards.add(new DraftCube.CardIdentity("Kalitas, Traitor of Ghet", "")); + cubeCards.add(new DraftCube.CardIdentity("Painful Truths", "")); + cubeCards.add(new DraftCube.CardIdentity("Diabolic Edict", "")); + cubeCards.add(new DraftCube.CardIdentity("Skinrender", "")); + cubeCards.add(new DraftCube.CardIdentity("Toxic Deluge", "")); + cubeCards.add(new DraftCube.CardIdentity("Ophiomancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Nekrataal", "")); + cubeCards.add(new DraftCube.CardIdentity("Gurmag Angler", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Petition", "")); + cubeCards.add(new DraftCube.CardIdentity("Cabal Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Phyrexian Arena", "")); + cubeCards.add(new DraftCube.CardIdentity("Go for the Throat", "")); + cubeCards.add(new DraftCube.CardIdentity("Duress", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("The Abyss", "")); + cubeCards.add(new DraftCube.CardIdentity("Vampire Nighthawk", "")); + cubeCards.add(new DraftCube.CardIdentity("Inquisition of Kozilek", "")); + cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", "")); + cubeCards.add(new DraftCube.CardIdentity("Hypnotic Specter", "")); + cubeCards.add(new DraftCube.CardIdentity("Mesmeric Fiend", "")); + cubeCards.add(new DraftCube.CardIdentity("Magus of the Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Confidant", "")); + cubeCards.add(new DraftCube.CardIdentity("Ultimate Price", "")); + cubeCards.add(new DraftCube.CardIdentity("Kitesail Freebooter", "")); + cubeCards.add(new DraftCube.CardIdentity("Exhume", "")); + cubeCards.add(new DraftCube.CardIdentity("Collective Brutality", "")); + cubeCards.add(new DraftCube.CardIdentity("Bone Shredder", "")); + cubeCards.add(new DraftCube.CardIdentity("Brain Maggot", "")); + cubeCards.add(new DraftCube.CardIdentity("Fatal Push", "")); + cubeCards.add(new DraftCube.CardIdentity("Hymn to Tourach", "")); + cubeCards.add(new DraftCube.CardIdentity("Tendrils of Agony", "")); + cubeCards.add(new DraftCube.CardIdentity("Rishadan Port", "")); + cubeCards.add(new DraftCube.CardIdentity("Grave Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Entomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Bazaar of Baghdad", "")); + cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Will", "")); + cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Bargain", "")); + cubeCards.add(new DraftCube.CardIdentity("Demonic Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Jet", "")); + cubeCards.add(new DraftCube.CardIdentity("Necropotence", "")); + cubeCards.add(new DraftCube.CardIdentity("Looter il-Kor", "")); + cubeCards.add(new DraftCube.CardIdentity("Living Death", "")); + cubeCards.add(new DraftCube.CardIdentity("Dark Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Sheoldred, Whispering One", "")); + cubeCards.add(new DraftCube.CardIdentity("Terastodon", "")); + cubeCards.add(new DraftCube.CardIdentity("Corpse Dance", "")); + cubeCards.add(new DraftCube.CardIdentity("Makeshift Mannequin", "")); + cubeCards.add(new DraftCube.CardIdentity("Recurring Nightmare", "")); + cubeCards.add(new DraftCube.CardIdentity("Animate Dead", "")); + cubeCards.add(new DraftCube.CardIdentity("Search for Azcanta", "")); + cubeCards.add(new DraftCube.CardIdentity("Buried Alive", "")); + cubeCards.add(new DraftCube.CardIdentity("Iona, Shield of Emeria", "")); + cubeCards.add(new DraftCube.CardIdentity("Faithless Looting", "")); + cubeCards.add(new DraftCube.CardIdentity("Necromancy", "")); + cubeCards.add(new DraftCube.CardIdentity("Liliana of the Veil", "")); + cubeCards.add(new DraftCube.CardIdentity("Reanimate", "")); + cubeCards.add(new DraftCube.CardIdentity("Griselbrand", "")); + cubeCards.add(new DraftCube.CardIdentity("Putrid Imp", "")); + cubeCards.add(new DraftCube.CardIdentity("Massacre Wurm", "")); + cubeCards.add(new DraftCube.CardIdentity("Unburial Rites", "")); + cubeCards.add(new DraftCube.CardIdentity("Pack Rat", "")); + cubeCards.add(new DraftCube.CardIdentity("Mind Twist", "")); + cubeCards.add(new DraftCube.CardIdentity("Oona's Prowler", "")); + cubeCards.add(new DraftCube.CardIdentity("Vampiric Tutor", "")); + cubeCards.add(new DraftCube.CardIdentity("Shallow Grave", "")); + cubeCards.add(new DraftCube.CardIdentity("Imperial Seal", "")); + cubeCards.add(new DraftCube.CardIdentity("Dualcaster Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Harsh Mentor", "")); + cubeCards.add(new DraftCube.CardIdentity("Splinter Twin", "")); + cubeCards.add(new DraftCube.CardIdentity("Young Pyromancer", "")); + cubeCards.add(new DraftCube.CardIdentity("Char", "")); + cubeCards.add(new DraftCube.CardIdentity("Daretti, Scrap Savant", "")); + cubeCards.add(new DraftCube.CardIdentity("Pyretic Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Rite of Flame", "")); + cubeCards.add(new DraftCube.CardIdentity("Mizzium Mortars", "")); + cubeCards.add(new DraftCube.CardIdentity("Exquisite Firecraft", "")); + cubeCards.add(new DraftCube.CardIdentity("Burst Lightning", "")); + cubeCards.add(new DraftCube.CardIdentity("Firebolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancient Grudge", "")); + cubeCards.add(new DraftCube.CardIdentity("Kiki-Jiki, Mirror Breaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Desperate Ritual", "")); + cubeCards.add(new DraftCube.CardIdentity("Through the Breach", "")); + cubeCards.add(new DraftCube.CardIdentity("Searing Spear", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Bolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Fireblast", "")); + cubeCards.add(new DraftCube.CardIdentity("Incinerate", "")); + cubeCards.add(new DraftCube.CardIdentity("Hazoret the Fervent", "")); + cubeCards.add(new DraftCube.CardIdentity("Seething Song", "")); + cubeCards.add(new DraftCube.CardIdentity("Sneak Attack", "")); + cubeCards.add(new DraftCube.CardIdentity("Wheel of Fortune", "")); + cubeCards.add(new DraftCube.CardIdentity("Sulfuric Vortex", "")); + cubeCards.add(new DraftCube.CardIdentity("Abrade", "")); + cubeCards.add(new DraftCube.CardIdentity("Chain Lightning", "")); + cubeCards.add(new DraftCube.CardIdentity("Goblin Welder", "")); + cubeCards.add(new DraftCube.CardIdentity("Guttersnipe", "")); + cubeCards.add(new DraftCube.CardIdentity("Rift Bolt", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Flamecaller", "")); + cubeCards.add(new DraftCube.CardIdentity("Chandra, Torch of Defiance", "")); + cubeCards.add(new DraftCube.CardIdentity("Imperial Recruiter", "")); + cubeCards.add(new DraftCube.CardIdentity("Bonfire of the Damned", "")); + cubeCards.add(new DraftCube.CardIdentity("Shrine of Burning Rage", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", "")); + cubeCards.add(new DraftCube.CardIdentity("Magma Jet", "")); + cubeCards.add(new DraftCube.CardIdentity("Search for Tomorrow", "")); + cubeCards.add(new DraftCube.CardIdentity("Fyndhorn Elves", "")); + cubeCards.add(new DraftCube.CardIdentity("Lotus Cobra", "")); + cubeCards.add(new DraftCube.CardIdentity("Courser of Kruphix", "")); + cubeCards.add(new DraftCube.CardIdentity("Managorger Hydra", "")); + cubeCards.add(new DraftCube.CardIdentity("Primeval Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Harmonize", "")); + cubeCards.add(new DraftCube.CardIdentity("Birds of Paradise", "")); + cubeCards.add(new DraftCube.CardIdentity("Genesis Wave", "")); + cubeCards.add(new DraftCube.CardIdentity("Fastbond", "")); + cubeCards.add(new DraftCube.CardIdentity("Primal Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Joraga Treespeaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Oracle of Mul Daya", "")); + cubeCards.add(new DraftCube.CardIdentity("Growing Rites of Itlimoc", "")); + cubeCards.add(new DraftCube.CardIdentity("Avacyn's Pilgrim", "")); + cubeCards.add(new DraftCube.CardIdentity("Channel", "")); + cubeCards.add(new DraftCube.CardIdentity("Sakura-Tribe Elder", "")); + cubeCards.add(new DraftCube.CardIdentity("Survival of the Fittest", "")); + cubeCards.add(new DraftCube.CardIdentity("Noble Hierarch", "")); + cubeCards.add(new DraftCube.CardIdentity("Dissenter's Deliverance", "")); + cubeCards.add(new DraftCube.CardIdentity("Regrowth", "")); + cubeCards.add(new DraftCube.CardIdentity("Natural Order", "")); + cubeCards.add(new DraftCube.CardIdentity("Oath of Druids", "")); + cubeCards.add(new DraftCube.CardIdentity("Sylvan Caryatid", "")); + cubeCards.add(new DraftCube.CardIdentity("Llanowar Elves", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Roots", "")); + cubeCards.add(new DraftCube.CardIdentity("Green Sun's Zenith", "")); + cubeCards.add(new DraftCube.CardIdentity("Arbor Elf", "")); + cubeCards.add(new DraftCube.CardIdentity("Elves of Deep Shadow", "")); + cubeCards.add(new DraftCube.CardIdentity("Eureka", "")); + cubeCards.add(new DraftCube.CardIdentity("Yavimaya Elder", "")); + cubeCards.add(new DraftCube.CardIdentity("Traverse the Ulvenwald", "")); + cubeCards.add(new DraftCube.CardIdentity("Sylvan Library", "")); + cubeCards.add(new DraftCube.CardIdentity("Elvish Mystic", "")); + cubeCards.add(new DraftCube.CardIdentity("Tooth and Nail", "")); + cubeCards.add(new DraftCube.CardIdentity("Rishkar, Peema Renegade", "")); + cubeCards.add(new DraftCube.CardIdentity("Rofellos, Llanowar Emissary", "")); + cubeCards.add(new DraftCube.CardIdentity("Leovold, Emissary of Trest", "")); + cubeCards.add(new DraftCube.CardIdentity("Opposition", "")); + cubeCards.add(new DraftCube.CardIdentity("Archangel of Thune", "")); + cubeCards.add(new DraftCube.CardIdentity("Beast Within", "")); + cubeCards.add(new DraftCube.CardIdentity("Manglehorn", "")); + cubeCards.add(new DraftCube.CardIdentity("Master of the Wild Hunt", "")); + cubeCards.add(new DraftCube.CardIdentity("Avenger of Zendikar", "")); + cubeCards.add(new DraftCube.CardIdentity("High Tide", "")); + cubeCards.add(new DraftCube.CardIdentity("Wall of Blossoms", "")); + cubeCards.add(new DraftCube.CardIdentity("Nissa, Worldwaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk Relentless", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk Wildspeaker", "")); + cubeCards.add(new DraftCube.CardIdentity("Nature's Claim", "")); + cubeCards.add(new DraftCube.CardIdentity("Thrun, the Last Troll", "")); + cubeCards.add(new DraftCube.CardIdentity("Gaea's Cradle", "")); + cubeCards.add(new DraftCube.CardIdentity("Reclamation Sage", "")); + cubeCards.add(new DraftCube.CardIdentity("Oath of Nissa", "")); + cubeCards.add(new DraftCube.CardIdentity("Thragtusk", "")); + cubeCards.add(new DraftCube.CardIdentity("Sweltering Suns", "")); + cubeCards.add(new DraftCube.CardIdentity("Verdurous Gearhulk", "")); + cubeCards.add(new DraftCube.CardIdentity("Freyalise, Llanowar's Fury", "")); + cubeCards.add(new DraftCube.CardIdentity("Garruk, Primal Hunter", "")); + cubeCards.add(new DraftCube.CardIdentity("Woodfall Primus", "")); + cubeCards.add(new DraftCube.CardIdentity("Den Protector", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Emerald", "")); + cubeCards.add(new DraftCube.CardIdentity("Tarmogoyf", "")); + cubeCards.add(new DraftCube.CardIdentity("Craterhoof Behemoth", "")); + cubeCards.add(new DraftCube.CardIdentity("Eternal Witness", "")); + cubeCards.add(new DraftCube.CardIdentity("Razaketh, the Foulblooded", "")); + cubeCards.add(new DraftCube.CardIdentity("Fauna Shaman", "")); + cubeCards.add(new DraftCube.CardIdentity("Scavenging Ooze", "")); + cubeCards.add(new DraftCube.CardIdentity("Polukranos, World Eater", "")); + cubeCards.add(new DraftCube.CardIdentity("Deranged Hermit", "")); + cubeCards.add(new DraftCube.CardIdentity("Acidic Slime", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Crypt", "")); + cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", "")); + cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", "")); + cubeCards.add(new DraftCube.CardIdentity("Ancient Tomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Hedron Archive", "")); + cubeCards.add(new DraftCube.CardIdentity("Maze of Ith", "")); + cubeCards.add(new DraftCube.CardIdentity("Mox Diamond", "")); + cubeCards.add(new DraftCube.CardIdentity("Tundra", "")); + cubeCards.add(new DraftCube.CardIdentity("Rakdos Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Dreadbore", "")); + cubeCards.add(new DraftCube.CardIdentity("Rakdos's Return", "")); + cubeCards.add(new DraftCube.CardIdentity("Sol Ring", "")); + cubeCards.add(new DraftCube.CardIdentity("Blackcleave Cliffs", "")); + cubeCards.add(new DraftCube.CardIdentity("Geist of Saint Traft", "")); + cubeCards.add(new DraftCube.CardIdentity("Terminate", "")); + cubeCards.add(new DraftCube.CardIdentity("Seachrome Coast", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Confluence", "")); + cubeCards.add(new DraftCube.CardIdentity("Chrome Mox", "")); + cubeCards.add(new DraftCube.CardIdentity("Lavaclaw Reaches", "")); + cubeCards.add(new DraftCube.CardIdentity("Shardless Agent", "")); + cubeCards.add(new DraftCube.CardIdentity("Olivia Voldaren", "")); + cubeCards.add(new DraftCube.CardIdentity("Creeping Tar Pit", "")); + cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", "")); + cubeCards.add(new DraftCube.CardIdentity("Supreme Verdict", "")); + cubeCards.add(new DraftCube.CardIdentity("Mana Vault", "")); + cubeCards.add(new DraftCube.CardIdentity("Copperline Gorge", "")); + cubeCards.add(new DraftCube.CardIdentity("Mishra's Workshop", "")); + cubeCards.add(new DraftCube.CardIdentity("Library of Alexandria", "")); + cubeCards.add(new DraftCube.CardIdentity("Azorius Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Sphinx's Revelation", "")); + cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", "")); + cubeCards.add(new DraftCube.CardIdentity("Black Lotus", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Ojutai", "")); + cubeCards.add(new DraftCube.CardIdentity("Badlands", "")); + cubeCards.add(new DraftCube.CardIdentity("Tolarian Academy", "")); + cubeCards.add(new DraftCube.CardIdentity("Urborg, Tomb of Yawgmoth", "")); + cubeCards.add(new DraftCube.CardIdentity("Botanical Sanctum", "")); + cubeCards.add(new DraftCube.CardIdentity("Smokestack", "")); + cubeCards.add(new DraftCube.CardIdentity("Reflector Mage", "")); + cubeCards.add(new DraftCube.CardIdentity("Tropical Island", "")); + cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Infinite Gyre", "")); + cubeCards.add(new DraftCube.CardIdentity("Figure of Destiny", "")); + cubeCards.add(new DraftCube.CardIdentity("Progenitus", "")); + cubeCards.add(new DraftCube.CardIdentity("Inspiring Vantage", "")); + cubeCards.add(new DraftCube.CardIdentity("Kozilek, Butcher of Truth", "")); + cubeCards.add(new DraftCube.CardIdentity("Edric, Spymaster of Trest", "")); + cubeCards.add(new DraftCube.CardIdentity("Celestial Colonnade", "")); + cubeCards.add(new DraftCube.CardIdentity("Trygon Predator", "")); + cubeCards.add(new DraftCube.CardIdentity("Boros Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Mishra's Factory", "")); + cubeCards.add(new DraftCube.CardIdentity("Karn Liberated", "")); + cubeCards.add(new DraftCube.CardIdentity("Boros Charm", "")); + cubeCards.add(new DraftCube.CardIdentity("Crucible of Worlds", "")); + cubeCards.add(new DraftCube.CardIdentity("Winter Orb", "")); + cubeCards.add(new DraftCube.CardIdentity("Anguished Unmaking", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Helix", "")); + cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Aeons Torn", "")); + cubeCards.add(new DraftCube.CardIdentity("Simic Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Bring to Light", "")); + cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", "")); + cubeCards.add(new DraftCube.CardIdentity("Plateau", "")); + cubeCards.add(new DraftCube.CardIdentity("Tangle Wire", "")); + cubeCards.add(new DraftCube.CardIdentity("Lodestone Golem", "")); + cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Ceaseless Hunger", "")); + cubeCards.add(new DraftCube.CardIdentity("Ugin, the Spirit Dragon", "")); + cubeCards.add(new DraftCube.CardIdentity("Mutavault", "")); + cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", "")); + cubeCards.add(new DraftCube.CardIdentity("Ajani Vengeant", "")); + cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", "")); + cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", "")); + cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", "")); + cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Light and Shadow", "")); + cubeCards.add(new DraftCube.CardIdentity("Orzhov Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Scrubland", "")); + cubeCards.add(new DraftCube.CardIdentity("Umezawa's Jitte", "")); + cubeCards.add(new DraftCube.CardIdentity("Coalition Relic", "")); + cubeCards.add(new DraftCube.CardIdentity("Huntmaster of the Fells", "")); + cubeCards.add(new DraftCube.CardIdentity("Tidehollow Sculler", "")); + cubeCards.add(new DraftCube.CardIdentity("Skullclamp", "")); + cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", "")); + cubeCards.add(new DraftCube.CardIdentity("Batterskull", "")); + cubeCards.add(new DraftCube.CardIdentity("Lotus Bloom", "")); + cubeCards.add(new DraftCube.CardIdentity("Lion's Eye Diamond", "")); + cubeCards.add(new DraftCube.CardIdentity("Kolaghan's Command", "")); + cubeCards.add(new DraftCube.CardIdentity("Bloodbraid Elf", "")); + cubeCards.add(new DraftCube.CardIdentity("Concealed Courtyard", "")); + cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of War and Peace", "")); + cubeCards.add(new DraftCube.CardIdentity("Needle Spires", "")); + cubeCards.add(new DraftCube.CardIdentity("Xenagos, the Reveler", "")); + cubeCards.add(new DraftCube.CardIdentity("Raging Ravine", "")); + cubeCards.add(new DraftCube.CardIdentity("Gruul Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Atarka", "")); + cubeCards.add(new DraftCube.CardIdentity("Taiga", "")); + cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Fire and Ice", "")); + cubeCards.add(new DraftCube.CardIdentity("Vindicate", "")); + cubeCards.add(new DraftCube.CardIdentity("Lightning Greaves", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Feast and Famine", "")); + cubeCards.add(new DraftCube.CardIdentity("Sword of Body and Mind", "")); + cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", "")); + cubeCards.add(new DraftCube.CardIdentity("Voice of Resurgence", "")); + cubeCards.add(new DraftCube.CardIdentity("Wurmcoil Engine", "")); + cubeCards.add(new DraftCube.CardIdentity("Nykthos, Shrine to Nyx", "")); + cubeCards.add(new DraftCube.CardIdentity("Underground Sea", "")); + cubeCards.add(new DraftCube.CardIdentity("Watery Grave", "")); + cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", "")); + cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, Planeswalker", "")); + cubeCards.add(new DraftCube.CardIdentity("Hostage Taker", "")); + cubeCards.add(new DraftCube.CardIdentity("Tezzeret, Agent of Bolas", "")); + cubeCards.add(new DraftCube.CardIdentity("Nahiri, the Harbinger", "")); + cubeCards.add(new DraftCube.CardIdentity("Spellskite", "")); + cubeCards.add(new DraftCube.CardIdentity("Qasali Pridemage", "")); + cubeCards.add(new DraftCube.CardIdentity("Mirari's Wake", "")); + cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", "")); + cubeCards.add(new DraftCube.CardIdentity("Walking Ballista", "")); + cubeCards.add(new DraftCube.CardIdentity("Memory Jar", "")); + cubeCards.add(new DraftCube.CardIdentity("Temple Garden", "")); + cubeCards.add(new DraftCube.CardIdentity("Mindslaver", "")); + cubeCards.add(new DraftCube.CardIdentity("Baleful Strix", "")); + cubeCards.add(new DraftCube.CardIdentity("Hangarback Walker", "")); + cubeCards.add(new DraftCube.CardIdentity("Coercive Portal", "")); + cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Promised End", "")); + cubeCards.add(new DraftCube.CardIdentity("Stirring Wildwood", "")); + cubeCards.add(new DraftCube.CardIdentity("Selesnya Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Sensei's Divining Top", "")); + cubeCards.add(new DraftCube.CardIdentity("Darkslick Shores", "")); + cubeCards.add(new DraftCube.CardIdentity("Duplicant", "")); + cubeCards.add(new DraftCube.CardIdentity("Sorcerous Spyglass", "")); + cubeCards.add(new DraftCube.CardIdentity("Scroll Rack", "")); + cubeCards.add(new DraftCube.CardIdentity("Nevinyrral's Disk", "")); + cubeCards.add(new DraftCube.CardIdentity("Savannah", "")); + cubeCards.add(new DraftCube.CardIdentity("Dimir Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", "")); + cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", "")); + cubeCards.add(new DraftCube.CardIdentity("Razorverge Thicket", "")); + cubeCards.add(new DraftCube.CardIdentity("Ashiok, Nightmare Weaver", "")); + cubeCards.add(new DraftCube.CardIdentity("The Scarab God", "")); + cubeCards.add(new DraftCube.CardIdentity("Kitchen Finks", "")); + cubeCards.add(new DraftCube.CardIdentity("Dragonlord Dromoka", "")); + cubeCards.add(new DraftCube.CardIdentity("Phyrexian Revoker", "")); + cubeCards.add(new DraftCube.CardIdentity("Spirebluff Canal", "")); + cubeCards.add(new DraftCube.CardIdentity("Golgari Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", "")); + cubeCards.add(new DraftCube.CardIdentity("Sundering Titan", "")); + cubeCards.add(new DraftCube.CardIdentity("Kuldotha Forgemaster", "")); + cubeCards.add(new DraftCube.CardIdentity("Deathrite Shaman", "")); + cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", "")); + cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", "")); + cubeCards.add(new DraftCube.CardIdentity("Maelstrom Pulse", "")); + cubeCards.add(new DraftCube.CardIdentity("Bayou", "")); + cubeCards.add(new DraftCube.CardIdentity("Blooming Marsh", "")); + cubeCards.add(new DraftCube.CardIdentity("Gilded Lotus", "")); + cubeCards.add(new DraftCube.CardIdentity("Worn Powerstone", "")); + cubeCards.add(new DraftCube.CardIdentity("Pernicious Deed", "")); + cubeCards.add(new DraftCube.CardIdentity("Volcanic Island", "")); + cubeCards.add(new DraftCube.CardIdentity("Smuggler's Copter", "")); + cubeCards.add(new DraftCube.CardIdentity("God-Pharaoh's Gift", "")); + cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", "")); + cubeCards.add(new DraftCube.CardIdentity("Myr Battlesphere", "")); + cubeCards.add(new DraftCube.CardIdentity("Grim Monolith", "")); + cubeCards.add(new DraftCube.CardIdentity("Dack Fayden", "")); + cubeCards.add(new DraftCube.CardIdentity("Ral Zarek", "")); + cubeCards.add(new DraftCube.CardIdentity("Steam Vents", "")); + cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", "")); + cubeCards.add(new DraftCube.CardIdentity("Westvale Abbey", "")); + cubeCards.add(new DraftCube.CardIdentity("Pentad Prism", "")); + cubeCards.add(new DraftCube.CardIdentity("Vraska, Relic Seeker", "")); + cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", "")); + cubeCards.add(new DraftCube.CardIdentity("Izzet Signet", "")); + cubeCards.add(new DraftCube.CardIdentity("Electrolyze", "")); + cubeCards.add(new DraftCube.CardIdentity("Metalworker", "")); + cubeCards.add(new DraftCube.CardIdentity("Abrupt Decay", "")); + cubeCards.add(new DraftCube.CardIdentity("Blightsteel Colossus", "")); + cubeCards.add(new DraftCube.CardIdentity("Sphinx of the Steel Wind", "")); + cubeCards.add(new DraftCube.CardIdentity("Basalt Monolith", "")); + cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", "")); + cubeCards.add(new DraftCube.CardIdentity("Thran Dynam", "")); + } +} \ No newline at end of file diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 553261ff8e..aceb3bdd24 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -103,10 +103,10 @@ - + - + @@ -125,7 +125,8 @@ - + + @@ -144,7 +145,7 @@ - + diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml index 9413a83ba1..c3663dbcfc 100644 --- a/Mage.Server/release/config/config.xml +++ b/Mage.Server/release/config/config.xml @@ -93,7 +93,7 @@ - + @@ -103,25 +103,26 @@ - + - - - - - + + + + + - + + @@ -144,7 +145,7 @@ - + diff --git a/Mage.Sets/src/mage/cards/b/BaronVonCount.java b/Mage.Sets/src/mage/cards/b/BaronVonCount.java new file mode 100644 index 0000000000..5948ab714a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BaronVonCount.java @@ -0,0 +1,290 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.util.CardUtil; + +/** + * + * @author L_J + */ +public class BaronVonCount extends CardImpl { + + public BaronVonCount(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{R}"); + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.VILLAIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Baron Von Count enters the battlefield with a doom counter on "5." + this.addAbility(new EntersBattlefieldAbility(new BaronVonCountPutCounterEffect())); + + // Whenever you cast a spell with the indicated numeral in its mana cost, text box, power, or toughness, move the doom counter one numeral to the left. + this.addAbility(new BaronVonCountTriggeredAbility()); + + // When the doom counter moves from "1," destroy target player and put that doom counter on "5." + this.addAbility(new BaronVonCountSecondTriggeredAbility()); + } + + public BaronVonCount(final BaronVonCount card) { + super(card); + } + + @Override + public BaronVonCount copy() { + return new BaronVonCount(this); + } +} + +class BaronVonCountPutCounterEffect extends OneShotEffect { + + public BaronVonCountPutCounterEffect() { + super(Outcome.Benefit); + staticText = "with a doom counter on \"5.\""; + } + + public BaronVonCountPutCounterEffect(final BaronVonCountPutCounterEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { + Integer doomNumber = 5; + game.getState().setValue(mageObject.getId() + "_doom", doomNumber); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("doom counter", CardUtil.addToolTipMarkTags("Doom counter at: " + doomNumber), game); + // This isn't exactly correct - from what I understand from Maro's rulings, the game "can't see" the counter on Baron (i.e. the original counter can't be removed by Vampire Hexmage etc.), + // but it can still be proliferated to put an additional doom counter on itself (the new counters can be removed and aren't placed on the "numbers" - i.e. they don't influence the card's + // functionality in any direct way). To simplify things, I merely put a do-nothing Doom counter on Baron that can be proliferated, etc., in addition to the value that tracks the + // the placement of the functional "counter". This only has fringe incorrect interactions with a few cards like Thief of Blood which now gets an extra counter from Baron. + new AddCountersSourceEffect(CounterType.DOOM.createInstance()).apply(game, source); + } + return true; + } + return false; + } + + @Override + public BaronVonCountPutCounterEffect copy() { + return new BaronVonCountPutCounterEffect(this); + } +} + +class BaronVonCountTriggeredAbility extends TriggeredAbilityImpl { + + public BaronVonCountTriggeredAbility() { + super(Zone.BATTLEFIELD, new BaronVonCountMoveDoomCounterEffect()); + } + + public BaronVonCountTriggeredAbility(final BaronVonCountTriggeredAbility abiltity) { + super(abiltity); + } + + @Override + public BaronVonCountTriggeredAbility copy() { + return new BaronVonCountTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Permanent sourcePermanent = game.getPermanent(getSourceId()); + MageObject mageObject = game.getObject(getSourceId()); + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (game.getState().getValue(mageObject.getId() + "_doom") == null) { + return false; + } + Integer doomNumber = (Integer) game.getState().getValue(mageObject.getId() + "_doom"); + if (spell != null && sourcePermanent != null && mageObject != null && doomNumber > 0) { + String doomString = doomNumber.toString(); + if (spell.getCard().getManaCost().getText().contains(doomString) + || String.valueOf(spell.getPower().getBaseValue()).contains(doomString) + || String.valueOf(spell.getToughness().getBaseValue()).contains(doomString)) { + return true; + } else { + for (String string : spell.getCard().getRules()) { + if (string.contains(doomString)) { + return true; + } + } + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever you cast a spell with the indicated numeral in its mana cost, text box, power, or toughness, " + super.getRule(); + } +} + +class BaronVonCountMoveDoomCounterEffect extends OneShotEffect { + + public BaronVonCountMoveDoomCounterEffect() { + super(Outcome.Neutral); + staticText = "move the doom counter one numeral to the left"; + } + + public BaronVonCountMoveDoomCounterEffect(final BaronVonCountMoveDoomCounterEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getObject(source.getSourceId()); + if (controller != null && mageObject != null) { + if (game.getState().getValue(mageObject.getId() + "_doom") == null) { + return false; + } + Integer doomNumber = (Integer) game.getState().getValue(mageObject.getId() + "_doom"); + if (doomNumber == 1) { + // not completely sure if counter should be moving here or not (relevant in case the second trigger gets countered) + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CUSTOM_EVENT, source.getSourceId(), source.getSourceId(), controller.getId(), "DoomCounterReset", 1)); + } + if (doomNumber > 0) { + doomNumber--; + game.getState().setValue(mageObject.getId() + "_doom", doomNumber); + ((Permanent) mageObject).addInfo("doom counter", CardUtil.addToolTipMarkTags("Doom counter at: " + doomNumber), game); + } + return true; + } + return false; + } + + @Override + public BaronVonCountMoveDoomCounterEffect copy() { + return new BaronVonCountMoveDoomCounterEffect(this); + } +} + +class BaronVonCountSecondTriggeredAbility extends TriggeredAbilityImpl { + + public BaronVonCountSecondTriggeredAbility() { + super(Zone.BATTLEFIELD, new BaronVonCountDestroyPlayerEffect()); + this.addTarget(new TargetPlayer()); + } + + public BaronVonCountSecondTriggeredAbility(BaronVonCountSecondTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.CUSTOM_EVENT; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getData().equals("DoomCounterReset") && event.getTargetId().equals(this.getSourceId()); + } + + @Override + public BaronVonCountSecondTriggeredAbility copy() { + return new BaronVonCountSecondTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When the doom counter moves from \"1,\" " + super.getRule(); + } +} + +class BaronVonCountDestroyPlayerEffect extends OneShotEffect { + + public BaronVonCountDestroyPlayerEffect() { + super(Outcome.Neutral); + staticText = "destroy target player and put that doom counter on \"5.\""; + } + + public BaronVonCountDestroyPlayerEffect(final BaronVonCountDestroyPlayerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + if (targetPlayer != null && targetPlayer.canLose(game)) { + game.informPlayers(targetPlayer.getLogName() + " was destroyed"); + targetPlayer.lost(game); // double checks canLose, but seems more future-proof than lostForced + } + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null) { + if (game.getState().getValue(mageObject.getId() + "_doom") == null) { + return false; + } + Integer doomNumber = 5; + game.getState().setValue(mageObject.getId() + "_doom", doomNumber); + ((Permanent) mageObject).addInfo("doom counter", CardUtil.addToolTipMarkTags("Doom counter at: " + doomNumber), game); + return true; + } + return false; + } + + @Override + public BaronVonCountDestroyPlayerEffect copy() { + return new BaronVonCountDestroyPlayerEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DrJuliusJumblemorph.java b/Mage.Sets/src/mage/cards/d/DrJuliusJumblemorph.java new file mode 100644 index 0000000000..e16331368a --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DrJuliusJumblemorph.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.ChangelingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SuperType; + +/** + * + * @author vereena42 & L_J + */ +public class DrJuliusJumblemorph extends CardImpl { + + public DrJuliusJumblemorph(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}"); + this.addSuperType(SuperType.LEGENDARY); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Dr. Julius Jumblemorph is every creature type (even if this card isn't on the battlefield). + this.addAbility(ChangelingAbility.getInstance()); + + // Whenever a host enters the battlefield under your control, you may search your library and/or graveyard for a card with augment and combine it with that host. If you search your library this way, shuffle it. + // TODO: Host currently isn't implemented, so this ability currently would never trigger + } + + public DrJuliusJumblemorph(final DrJuliusJumblemorph card) { + super(card); + } + + @Override + public DrJuliusJumblemorph copy() { + return new DrJuliusJumblemorph(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/Landslide.java b/Mage.Sets/src/mage/cards/l/Landslide.java new file mode 100644 index 0000000000..9388d000d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/Landslide.java @@ -0,0 +1,122 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; + +/** + * + * @author L_J + */ +public class Landslide extends CardImpl { + + public Landslide(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}"); + + // Sacrifice any number of Mountains. Landslide deals that much damage to target player. + this.getSpellAbility().addEffect(new LandslideEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public Landslide(final Landslide card) { + super(card); + } + + @Override + public Landslide copy() { + return new Landslide(this); + } +} + +class LandslideEffect extends OneShotEffect { + + static final FilterPermanent filter = new FilterPermanent("Mountains to sacrifice"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new SubtypePredicate(SubType.MOUNTAIN)); + } + + public LandslideEffect() { + super(Outcome.Benefit); + staticText = "Sacrifice any number of Mountains. {this} deals that much damage to target player"; + } + + public LandslideEffect(final LandslideEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player you = game.getPlayer(source.getControllerId()); + if (you != null) { + Target target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); + if (!target.canChoose(source.getSourceId(), source.getControllerId(), game)) { + return false; + } + you.chooseTarget(Outcome.Detriment, target, source, game); + if (!target.getTargets().isEmpty()) { + int amount = 0; + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null && permanent.sacrifice(source.getSourceId(), game)) { + amount++; + } + } + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + player.damage(amount, source.getSourceId(), game, false, true); + } + } + return true; + } + return false; + } + + @Override + public LandslideEffect copy() { + return new LandslideEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PanglacialWurm.java b/Mage.Sets/src/mage/cards/p/PanglacialWurm.java new file mode 100644 index 0000000000..889eba921a --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PanglacialWurm.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.WhileSearchingPlayFromLibraryAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author L_J + */ +public class PanglacialWurm extends CardImpl { + + public PanglacialWurm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); + this.subtype.add(SubType.WURM); + this.power = new MageInt(9); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // While you're searching your library, you may cast Panglacial Wurm from your library. + this.addAbility(WhileSearchingPlayFromLibraryAbility.getInstance()); + } + + public PanglacialWurm(final PanglacialWurm card) { + super(card); + } + + @Override + public PanglacialWurm copy() { + return new PanglacialWurm(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/Retether.java b/Mage.Sets/src/mage/cards/r/Retether.java new file mode 100644 index 0000000000..beab992681 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Retether.java @@ -0,0 +1,163 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.CanBeEnchantedByPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; + +/** + * + * @author L_J + */ +public class Retether extends CardImpl { + + public Retether(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{W}"); + + // Return each Aura card from your graveyard to the battlefield. Only creatures can be enchanted this way. + this.getSpellAbility().addEffect(new RetetherEffect()); + } + + public Retether(final Retether card) { + super(card); + } + + @Override + public Retether copy() { + return new Retether(this); + } +} + +class RetetherEffect extends OneShotEffect { + + private static final FilterCard filterAura = new FilterCard("Aura card from your graveyard"); + + static { + filterAura.add(new CardTypePredicate(CardType.ENCHANTMENT)); + filterAura.add(new SubtypePredicate(SubType.AURA)); + } + + public RetetherEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "Return each Aura card from your graveyard to the battlefield. Only creatures can be enchanted this way"; + } + + public RetetherEffect(final RetetherEffect effect) { + super(effect); + } + + @Override + public RetetherEffect copy() { + return new RetetherEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Map auraMap = new HashMap<>(); + auraCardsInGraveyard: + for (Card aura : controller.getGraveyard().getCards(filterAura, source.getSourceId(), source.getControllerId(), game)) { + if (aura != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature to enchant (" + aura.getLogName() + ')'); + filter.add(new CanBeEnchantedByPredicate(aura)); + Target target = null; + + auraLegalitySearch: + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, playerId, game)) { + if (permanent != null) { + for (Ability ability : aura.getAbilities()) { + if (ability instanceof SpellAbility) { + for (Target abilityTarget : ability.getTargets()) { + if (abilityTarget.possibleTargets(controller.getId(), game).contains(permanent.getId())) { + target = abilityTarget.copy(); + break auraLegalitySearch; + } + } + } + } + } + } + } + if (target != null) { + target.getFilter().add(new CardTypePredicate(CardType.CREATURE)); + target.setNotTarget(true); + if (target.canChoose(controller.getId(), game)) { + target.setTargetName("creature to enchant (" + aura.getLogName() + ')'); + if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null && !permanent.cantBeAttachedBy(aura, game)) { + auraMap.put(aura, permanent); + continue auraCardsInGraveyard; + } + } + } + } + game.informPlayers("No valid creature targets for " + aura.getLogName()); + } + } + for (Entry entry : auraMap.entrySet()) { + Card aura = entry.getKey(); + Permanent permanent = entry.getValue(); + if (aura != null) { + if (permanent != null) { + game.getState().setValue("attachTo:" + aura.getId(), permanent); + } + aura.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), controller.getId()); + if (permanent != null) { + permanent.addAttachment(aura.getId(), game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SnickeringSquirrel.java b/Mage.Sets/src/mage/cards/s/SnickeringSquirrel.java index 7022dc9c0b..ad835d320f 100644 --- a/Mage.Sets/src/mage/cards/s/SnickeringSquirrel.java +++ b/Mage.Sets/src/mage/cards/s/SnickeringSquirrel.java @@ -91,7 +91,10 @@ class SnickeringSquirrelEffect extends ReplacementEffectImpl { if (permanent != null && permanent.canTap() && !permanent.isTapped()) { if (controller.chooseUse(Outcome.AIDontUseIt, "Do you want to tap this to increase the result of a die any player rolled by 1?", null, "Yes", "No", source, game)) { permanent.tap(game); - event.setAmount(event.getAmount() + 1); + // ignore planar dies (dice roll amount of planar dies is equal to 0) + if (event.getAmount() > 0) { + event.setAmount(event.getAmount() + 1); + } } } } diff --git a/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java b/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java index 26a4aefa59..1376c52e86 100644 --- a/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java +++ b/Mage.Sets/src/mage/cards/s/SquirrelPoweredScheme.java @@ -87,7 +87,8 @@ class SquirrelPoweredSchemeEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - return source.getControllerId().equals(event.getPlayerId()); + // ignore planar dies (dice roll amount of planar dies is equal to 0) + return event.getAmount() > 0 && source.getControllerId().equals(event.getPlayerId()); } @Override diff --git a/Mage.Sets/src/mage/sets/Coldsnap.java b/Mage.Sets/src/mage/sets/Coldsnap.java index 5d924af0ca..1709fb4e29 100644 --- a/Mage.Sets/src/mage/sets/Coldsnap.java +++ b/Mage.Sets/src/mage/sets/Coldsnap.java @@ -139,6 +139,7 @@ public class Coldsnap extends ExpansionSet { cards.add(new SetCardInfo("Ohran Viper", 115, Rarity.RARE, mage.cards.o.OhranViper.class)); cards.add(new SetCardInfo("Ohran Yeti", 93, Rarity.COMMON, mage.cards.o.OhranYeti.class)); cards.add(new SetCardInfo("Orcish Bloodpainter", 94, Rarity.COMMON, mage.cards.o.OrcishBloodpainter.class)); + cards.add(new SetCardInfo("Panglacial Wurm", 116, Rarity.RARE, mage.cards.p.PanglacialWurm.class)); cards.add(new SetCardInfo("Perilous Research", 41, Rarity.UNCOMMON, mage.cards.p.PerilousResearch.class)); cards.add(new SetCardInfo("Phobian Phantasm", 66, Rarity.UNCOMMON, mage.cards.p.PhobianPhantasm.class)); cards.add(new SetCardInfo("Phyrexian Etchings", 67, Rarity.RARE, mage.cards.p.PhyrexianEtchings.class)); diff --git a/Mage.Sets/src/mage/sets/PlanarChaos.java b/Mage.Sets/src/mage/sets/PlanarChaos.java index 0e86820575..14e6c8cac4 100644 --- a/Mage.Sets/src/mage/sets/PlanarChaos.java +++ b/Mage.Sets/src/mage/sets/PlanarChaos.java @@ -165,6 +165,7 @@ public class PlanarChaos extends ExpansionSet { cards.add(new SetCardInfo("Rebuff the Wicked", 12, Rarity.UNCOMMON, mage.cards.r.RebuffTheWicked.class)); cards.add(new SetCardInfo("Reckless Wurm", 120, Rarity.UNCOMMON, mage.cards.r.RecklessWurm.class)); cards.add(new SetCardInfo("Reflex Sliver", 138, Rarity.COMMON, mage.cards.r.ReflexSliver.class)); + cards.add(new SetCardInfo("Retether", 13, Rarity.RARE, mage.cards.r.Retether.class)); cards.add(new SetCardInfo("Revered Dead", 29, Rarity.COMMON, mage.cards.r.ReveredDead.class)); cards.add(new SetCardInfo("Ridged Kusite", 78, Rarity.COMMON, mage.cards.r.RidgedKusite.class)); cards.add(new SetCardInfo("Riftmarked Knight", 14, Rarity.UNCOMMON, mage.cards.r.RiftmarkedKnight.class)); diff --git a/Mage.Sets/src/mage/sets/Unstable.java b/Mage.Sets/src/mage/sets/Unstable.java index c451dfa932..4b7601ef9f 100644 --- a/Mage.Sets/src/mage/sets/Unstable.java +++ b/Mage.Sets/src/mage/sets/Unstable.java @@ -50,11 +50,13 @@ public class Unstable extends ExpansionSet { cards.add(new SetCardInfo("Amateur Auteur", 3, Rarity.COMMON, mage.cards.a.AmateurAuteur.class)); cards.add(new SetCardInfo("As Luck Would Have It", 102, Rarity.RARE, mage.cards.a.AsLuckWouldHaveIt.class)); + cards.add(new SetCardInfo("Baron Von Count", 127, Rarity.MYTHIC, mage.cards.b.BaronVonCount.class)); cards.add(new SetCardInfo("Box of Free-Range Goblins", 77, Rarity.COMMON, mage.cards.b.BoxOfFreerangeGoblins.class)); cards.add(new SetCardInfo("Buzzing Whack-a-Doodle", 141, Rarity.UNCOMMON, mage.cards.b.BuzzingWhackADoodle.class)); cards.add(new SetCardInfo("Chittering Doom", 104, Rarity.UNCOMMON, mage.cards.c.ChitteringDoom.class)); cards.add(new SetCardInfo("Crow Storm", 31, Rarity.UNCOMMON, mage.cards.c.CrowStorm.class)); cards.add(new SetCardInfo("Curious Killbot", 145, Rarity.COMMON, mage.cards.c.CuriousKillbot.class)); + cards.add(new SetCardInfo("Dr. Julius Jumblemorph", 130, Rarity.MYTHIC, mage.cards.d.DrJuliusJumblemorph.class)); cards.add(new SetCardInfo("Earl of Squirrel", 108, Rarity.RARE, mage.cards.e.EarlOfSquirrel.class)); cards.add(new SetCardInfo("Forest", 216, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.UNH_FULL_ART_BASIC, false))); cards.add(new SetCardInfo("GO TO JAIL", 8, Rarity.COMMON, mage.cards.g.GOTOJAIL.class)); diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index acec22dff2..082450cfd8 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -110,6 +110,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Keldon Champion", 90, Rarity.UNCOMMON, mage.cards.k.KeldonChampion.class)); cards.add(new SetCardInfo("Keldon Vandals", 91, Rarity.COMMON, mage.cards.k.KeldonVandals.class)); cards.add(new SetCardInfo("Kingfisher", 36, Rarity.COMMON, mage.cards.k.Kingfisher.class)); + cards.add(new SetCardInfo("Landslide", 92, Rarity.UNCOMMON, mage.cards.l.Landslide.class)); cards.add(new SetCardInfo("Magnify", 111, Rarity.COMMON, mage.cards.m.Magnify.class)); cards.add(new SetCardInfo("Mantis Engine", 133, Rarity.UNCOMMON, mage.cards.m.MantisEngine.class)); cards.add(new SetCardInfo("Marker Beetles", 112, Rarity.COMMON, mage.cards.m.MarkerBeetles.class)); @@ -120,7 +121,7 @@ public class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Mental Discipline", 37, Rarity.COMMON, mage.cards.m.MentalDiscipline.class)); cards.add(new SetCardInfo("Metalworker", 135, Rarity.RARE, mage.cards.m.Metalworker.class)); cards.add(new SetCardInfo("Metathran Soldier", 39, Rarity.COMMON, mage.cards.m.MetathranSoldier.class)); - cards.add(new SetCardInfo("Momentum", 113, Rarity.UNCOMMON, mage.cards.m.Momentum.class)); + cards.add(new SetCardInfo("Momentum", 113, Rarity.UNCOMMON, mage.cards.m.Momentum.class)); cards.add(new SetCardInfo("Multani's Decree", 114, Rarity.COMMON, mage.cards.m.MultanisDecree.class)); cards.add(new SetCardInfo("Opalescence", 13, Rarity.RARE, mage.cards.o.Opalescence.class)); cards.add(new SetCardInfo("Opposition", 40, Rarity.RARE, mage.cards.o.Opposition.class)); diff --git a/Mage/src/main/java/mage/abilities/common/WhileSearchingPlayFromLibraryAbility.java b/Mage/src/main/java/mage/abilities/common/WhileSearchingPlayFromLibraryAbility.java new file mode 100644 index 0000000000..4de0428289 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/WhileSearchingPlayFromLibraryAbility.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011 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.common; + +import mage.abilities.MageSingleton; +import mage.abilities.StaticAbility; + +import java.io.ObjectStreamException; + +import mage.constants.AbilityType; +import mage.constants.Zone; + +/** + * @author L_J + */ +public class WhileSearchingPlayFromLibraryAbility extends StaticAbility implements MageSingleton { + + private static final WhileSearchingPlayFromLibraryAbility instance = new WhileSearchingPlayFromLibraryAbility(); + + private Object readResolve() throws ObjectStreamException { + return instance; + } + + public static WhileSearchingPlayFromLibraryAbility getInstance() { + return instance; + } + + private WhileSearchingPlayFromLibraryAbility() { + super(AbilityType.STATIC, Zone.LIBRARY); + } + + @Override + public String getRule() { + return "While you're searching your library, you may cast {this} from your library."; + } + + @Override + public WhileSearchingPlayFromLibraryAbility copy() { + return instance; + } + +} diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 6233a4ed6f..1301f19697 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -36,6 +36,7 @@ import mage.MageObject; import mage.Mana; import mage.abilities.*; import mage.abilities.common.PassAbility; +import mage.abilities.common.WhileSearchingPlayFromLibraryAbility; import mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility; import mage.abilities.costs.*; import mage.abilities.costs.mana.ManaCost; @@ -53,6 +54,7 @@ import mage.cards.Cards; import mage.cards.CardsImpl; import mage.cards.SplitCard; import mage.cards.decks.Deck; +import mage.choices.ChoiceImpl; import mage.constants.*; import static mage.constants.Zone.BATTLEFIELD; import static mage.constants.Zone.EXILED; @@ -2307,28 +2309,101 @@ public abstract class PlayerImpl implements Player, Serializable { TargetCardInLibrary newTarget = target.copy(); int count; int librarySearchLimit = event.getAmount(); - if (librarySearchLimit == Integer.MAX_VALUE) { - count = searchedLibrary.count(target.getFilter(), game); - } else { - newTarget.setCardLimit(librarySearchLimit); - count = Math.min(searchedLibrary.count(target.getFilter(), game), librarySearchLimit); - } - - if (count < target.getNumberOfTargets()) { - newTarget.setMinNumberOfTargets(count); - } - if (newTarget.choose(Outcome.Neutral, playerId, targetPlayerId, game)) { - target.getTargets().clear(); - for (UUID targetId : newTarget.getTargets()) { - target.add(targetId, game); + List cardsFromTop = null; + do { + // TODO: prevent shuffling from moving the visualized cards + if (librarySearchLimit == Integer.MAX_VALUE) { + count = searchedLibrary.count(target.getFilter(), game); + } else { + Player targetPlayer = game.getPlayer(targetPlayerId); + if (targetPlayer != null) { + if (cardsFromTop == null) { + cardsFromTop = new ArrayList<>(targetPlayer.getLibrary().getTopCards(game, librarySearchLimit)); + } else { + cardsFromTop.retainAll(targetPlayer.getLibrary().getCards(game)); + } + } + newTarget.setCardLimit(Math.min(librarySearchLimit, cardsFromTop.size())); + count = Math.min(searchedLibrary.count(target.getFilter(), game), librarySearchLimit); } - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, targetPlayerId, playerId)); - } + + if (count < target.getNumberOfTargets()) { + newTarget.setMinNumberOfTargets(count); + } + if (newTarget.choose(Outcome.Neutral, playerId, targetPlayerId, game)) { + if (targetPlayerId.equals(playerId) && handleLibraryCastableCards(library, game, targetPlayerId)) { // for handling Panglacial Wurm + newTarget.clearChosen(); + continue; + } + target.getTargets().clear(); + for (UUID targetId : newTarget.getTargets()) { + target.add(targetId, game); + } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, targetPlayerId, playerId)); + } else if (targetPlayerId.equals(playerId) && handleLibraryCastableCards(library, game, targetPlayerId)) { // for handling Panglacial Wurm + newTarget.clearChosen(); + continue; + } + break; + } while (true); return true; } return false; } + private boolean handleLibraryCastableCards(Library library, Game game, UUID targetPlayerId) { + // for handling Panglacial Wurm + boolean alreadyChosenUse = false; + Map libraryCastableCardTracker = new HashMap<>(); + searchForCards: + do { + for (Card card : library.getCards(game)) { + for (Ability ability : card.getAbilities()) { + if (ability.getClass() == WhileSearchingPlayFromLibraryAbility.class) { + libraryCastableCardTracker.put(card.getId(), card.getName() + " [" + card.getId().toString().substring(0, 3) + "]"); + } + } + } + if (!libraryCastableCardTracker.isEmpty()) { + Player player = game.getPlayer(targetPlayerId); + if (player != null) { + if (player.isHuman() && (alreadyChosenUse || player.chooseUse(Outcome.AIDontUseIt, "Cast a creature card from your library? (choose \"No\" to finish search)", null, game))) { + ChoiceImpl chooseCard = new ChoiceImpl(); + chooseCard.setMessage("Which creature do you wish to cast from your library?"); + Set choice = new LinkedHashSet<>(); + for (Entry entry : libraryCastableCardTracker.entrySet()) { + choice.add(new AbstractMap.SimpleEntry(entry).getValue()); + } + chooseCard.setChoices(choice); + while (!choice.isEmpty()) { + if (player.choose(Outcome.AIDontUseIt, chooseCard, game)) { + String chosenCard = chooseCard.getChoice(); + for (Entry entry : libraryCastableCardTracker.entrySet()) { + if (chosenCard.equals(entry.getValue())) { + Card card = game.getCard(entry.getKey()); + if (card != null) { + // TODO: fix costs (why is Panglacial Wurm automatically accepting payment?) + player.cast(card.getSpellAbility(), game, false); + } + chooseCard.clearChoice(); + libraryCastableCardTracker.clear(); + alreadyChosenUse = true; + continue searchForCards; + } + } + continue; + } + break; + } + return true; + } + } + } + break; + } while (alreadyChosenUse); + return alreadyChosenUse; + } + @Override public boolean flipCoin(Game game) { return this.flipCoin(game, null);