From 9f470e2bd03ad28035e6f291bfc92fcd84e34af0 Mon Sep 17 00:00:00 2001 From: Kevin Shin Date: Thu, 23 Aug 2018 02:55:47 -0500 Subject: [PATCH 01/50] Fixes Flickerform to return the exiled creature under the creature's owner's control, instead of its own owner's control. #5084 --- Mage.Sets/src/mage/cards/f/Flickerform.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/f/Flickerform.java b/Mage.Sets/src/mage/cards/f/Flickerform.java index 550ae27ce61..b7aabe64753 100644 --- a/Mage.Sets/src/mage/cards/f/Flickerform.java +++ b/Mage.Sets/src/mage/cards/f/Flickerform.java @@ -156,8 +156,9 @@ class FlickerformReturnEffect extends OneShotEffect { } ExileZone exileZone = game.getExile().getExileZone(exileZoneId); Card enchantedCard = exileZone.get(enchantedCardId, game); + Player owner = game.getPlayer(enchantedCard.getOwnerId()); if (enchantedCard != null) { - controller.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game); + owner.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game); Permanent newPermanent = game.getPermanent(enchantedCardId); if (newPermanent != null) { Set toBattlefieldAttached = new HashSet(); From 97e4e2738b497b51d8147cdc0f354ea3e6dfa836 Mon Sep 17 00:00:00 2001 From: Kevin Shin Date: Sat, 25 Aug 2018 03:36:32 -0500 Subject: [PATCH 02/50] Added check for if the exiled card's owner is missing. --- Mage.Sets/src/mage/cards/f/Flickerform.java | 60 +++++++++++---------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/Flickerform.java b/Mage.Sets/src/mage/cards/f/Flickerform.java index b7aabe64753..0f0ef9da3e1 100644 --- a/Mage.Sets/src/mage/cards/f/Flickerform.java +++ b/Mage.Sets/src/mage/cards/f/Flickerform.java @@ -156,40 +156,44 @@ class FlickerformReturnEffect extends OneShotEffect { } ExileZone exileZone = game.getExile().getExileZone(exileZoneId); Card enchantedCard = exileZone.get(enchantedCardId, game); - Player owner = game.getPlayer(enchantedCard.getOwnerId()); + //skip if exiled card is missing if (enchantedCard != null) { - owner.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game); - Permanent newPermanent = game.getPermanent(enchantedCardId); - if (newPermanent != null) { - Set toBattlefieldAttached = new HashSet(); - for (Card enchantment : exileZone.getCards(game)) { - if (filterAura.match(enchantment, game)) { - boolean canTarget = false; - for (Target target : enchantment.getSpellAbility().getTargets()) { - Filter filter = target.getFilter(); - if (filter.match(newPermanent, game)) { - canTarget = true; - break; + Player owner = game.getPlayer(enchantedCard.getOwnerId()); + //skip if card's owner is missing + if (owner != null) { + owner.moveCards(enchantedCard, Zone.BATTLEFIELD, source, game); + Permanent newPermanent = game.getPermanent(enchantedCardId); + if (newPermanent != null) { + Set toBattlefieldAttached = new HashSet(); + for (Card enchantment : exileZone.getCards(game)) { + if (filterAura.match(enchantment, game)) { + boolean canTarget = false; + for (Target target : enchantment.getSpellAbility().getTargets()) { + Filter filter = target.getFilter(); + if (filter.match(newPermanent, game)) { + canTarget = true; + break; + } + } + if (!canTarget) { + // Aura stays exiled + continue; + } + game.getState().setValue("attachTo:" + enchantment.getId(), newPermanent); + } + toBattlefieldAttached.add(enchantment); + } + if (!toBattlefieldAttached.isEmpty()) { + controller.moveCards(toBattlefieldAttached, Zone.BATTLEFIELD, source, game); + for (Card card : toBattlefieldAttached) { + if (game.getState().getZone(card.getId()) == Zone.BATTLEFIELD) { + newPermanent.addAttachment(card.getId(), game); } } - if (!canTarget) { - // Aura stays exiled - continue; - } - game.getState().setValue("attachTo:" + enchantment.getId(), newPermanent); - } - toBattlefieldAttached.add(enchantment); - } - if (!toBattlefieldAttached.isEmpty()) { - controller.moveCards(toBattlefieldAttached, Zone.BATTLEFIELD, source, game); - for (Card card : toBattlefieldAttached) { - if (game.getState().getZone(card.getId()) == Zone.BATTLEFIELD) { - newPermanent.addAttachment(card.getId(), game); - } } } + return true; } - return true; } return false; } From 81c2a62250868bb25f62ccdaef034fc2328ec59d Mon Sep 17 00:00:00 2001 From: Aaron Miller Date: Sat, 29 Sep 2018 19:14:39 -0700 Subject: [PATCH 03/50] Add "minimum rating" option to matches and tournaments --- .../mage/client/dialog/NewTableDialog.java | 34 ++++++++++++++----- .../client/dialog/NewTournamentDialog.java | 18 +++++++++- .../mage/client/dialog/PreferencesDialog.java | 2 ++ .../java/mage/client/table/TablesPanel.java | 14 +++++--- .../src/main/java/mage/view/TableView.java | 9 +++-- .../main/java/mage/server/MageServerImpl.java | 28 ++++++++++++++- .../java/mage/server/TableController.java | 30 ++++++++++++++++ .../java/mage/game/match/MatchOptions.java | 5 +++ .../game/tournament/TournamentOptions.java | 5 +++ 9 files changed, 126 insertions(+), 19 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java index 0e3121f61d9..c47059ed798 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java @@ -51,6 +51,7 @@ public class NewTableDialog extends MageDialog { this.spnNumWins.setModel(new SpinnerNumberModel(1, 1, 5, 1)); this.spnFreeMulligans.setModel(new SpinnerNumberModel(0, 0, 5, 1)); this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5)); + this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10)); this.spnEdhPowerLevel.setModel(new SpinnerNumberModel(100, 0, 100, 5)); MageFrame.getUI().addButton(MageComponents.NEW_TABLE_OK_BUTTON, btnOK); } @@ -102,8 +103,10 @@ public class NewTableDialog extends MageDialog { btnPreviousConfiguration2 = new javax.swing.JButton(); btnCancel = new javax.swing.JButton(); lblQuitRatio = new javax.swing.JLabel(); + lblMinimumRating = new javax.swing.JLabel(); lblEdhPowerLevel = new javax.swing.JLabel(); spnQuitRatio = new javax.swing.JSpinner(); + spnMinimumRating = new javax.swing.JSpinner(); spnEdhPowerLevel = new javax.swing.JSpinner(); setTitle("New Table"); @@ -186,9 +189,11 @@ public class NewTableDialog extends MageDialog { btnCancel.addActionListener(evt -> btnCancelActionPerformed(evt)); lblQuitRatio.setText("Allowed quit %"); + lblMinimumRating.setText("Minimum rating"); lblEdhPowerLevel.setText("EDH power level"); spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table"); + spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table"); spnEdhPowerLevel.setToolTipText("Players with decks with a higher power level can't join this table"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); @@ -239,9 +244,10 @@ public class NewTableDialog extends MageDialog { .addComponent(lblQuitRatio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblEdhPowerLevel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblMinimumRating) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() @@ -270,7 +276,11 @@ public class NewTableDialog extends MageDialog { .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lblNumWins) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblEdhPowerLevel) + .addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(jSeparator2) .addComponent(player1Panel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pnlOtherPlayers, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -297,14 +307,13 @@ public class NewTableDialog extends MageDialog { .addComponent(cbTimeLimit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lbDeckType) + .addComponent(cbDeckType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(chkRated) .addComponent(lblQuitRatio) - .addComponent(chkRated) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lblEdhPowerLevel) - .addComponent(chkRated) - .addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(lblMinimumRating) + .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -326,6 +335,7 @@ public class NewTableDialog extends MageDialog { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lblSkillLevel) .addComponent(lblNumWins) + .addComponent(lblEdhPowerLevel) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(lblRange) .addComponent(lblAttack))) @@ -334,7 +344,8 @@ public class NewTableDialog extends MageDialog { .addComponent(cbRange, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(cbAttackOption, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(cbSkillLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(spnEdhPowerLevel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -394,6 +405,7 @@ public class NewTableDialog extends MageDialog { options.setFreeMulligans((Integer) this.spnFreeMulligans.getValue()); options.setPassword(this.txtPassword.getText()); options.setQuitRatio((Integer) this.spnQuitRatio.getValue()); + options.setMinimumRating((Integer) this.spnMinimumRating.getValue()); options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue()); String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); @@ -695,6 +707,7 @@ public class NewTableDialog extends MageDialog { } this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO, "100"))); + this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, "0"))); this.spnEdhPowerLevel.setValue(0); } @@ -729,6 +742,7 @@ public class NewTableDialog extends MageDialog { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_SPECTATORS_ALLOWED + versionStr, options.isSpectatorsAllowed() ? "Yes" : "No"); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLANECHASE + versionStr, options.isPlaneChase() ? "Yes" : "No"); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_QUIT_RATIO + versionStr, Integer.toString(options.getQuitRatio())); + PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, Integer.toString(options.getMinimumRating())); StringBuilder playerTypesString = new StringBuilder(); for (Object player : players) { if (playerTypesString.length() > 0) { @@ -770,6 +784,7 @@ public class NewTableDialog extends MageDialog { private javax.swing.JLabel lblNumWins; private javax.swing.JLabel lblPassword; private javax.swing.JLabel lblQuitRatio; + private javax.swing.JLabel lblMinimumRating; private javax.swing.JLabel lblEdhPowerLevel; private javax.swing.JLabel lblRange; private javax.swing.JLabel lblSkillLevel; @@ -779,6 +794,7 @@ public class NewTableDialog extends MageDialog { private javax.swing.JSpinner spnNumPlayers; private javax.swing.JSpinner spnNumWins; private javax.swing.JSpinner spnQuitRatio; + private javax.swing.JSpinner spnMinimumRating; private javax.swing.JSpinner spnEdhPowerLevel; private javax.swing.JTextField txtName; private javax.swing.JTextField txtPassword; diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java index f5f2961f513..e11e0c62767 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java @@ -74,6 +74,7 @@ public class NewTournamentDialog extends MageDialog { this.spnConstructTime.setModel(new SpinnerNumberModel(10, CONSTRUCTION_TIME_MIN, CONSTRUCTION_TIME_MAX, 2)); this.spnNumRounds.setModel(new SpinnerNumberModel(2, 2, 10, 1)); this.spnQuitRatio.setModel(new SpinnerNumberModel(100, 0, 100, 5)); + this.spnMinimumRating.setModel(new SpinnerNumberModel(0, 0, 3000, 10)); } public void showDialog(UUID roomId) { @@ -164,6 +165,8 @@ public class NewTournamentDialog extends MageDialog { pnlRandomPacks = new javax.swing.JPanel(); lblQuitRatio = new javax.swing.JLabel(); spnQuitRatio = new javax.swing.JSpinner(); + lblMinimumRating = new javax.swing.JLabel(); + spnMinimumRating = new javax.swing.JSpinner(); setTitle("New Tournament"); @@ -314,8 +317,10 @@ public class NewTournamentDialog extends MageDialog { pnlRandomPacks.setLayout(new javax.swing.BoxLayout(pnlRandomPacks, javax.swing.BoxLayout.Y_AXIS)); lblQuitRatio.setText("Allowed quit %:"); + lblMinimumRating.setText("Minimum rating:"); spnQuitRatio.setToolTipText("Players with quit % more than this value can't join this table"); + spnMinimumRating.setToolTipText("Players with rating less than this value can't join this table"); spnNumSeats.setToolTipText("The number of seats for each duel. If more than 2, will set number of wins to 1"); spnNumPlayers.setToolTipText("The total number of players who will draft"); @@ -385,11 +390,15 @@ public class NewTournamentDialog extends MageDialog { .addComponent(lblNumWins) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lblQuitRatio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblMinimumRating) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(chkRated)) .addComponent(cbTournamentType, javax.swing.GroupLayout.PREFERRED_SIZE, 290, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGroup(layout.createSequentialGroup() @@ -443,6 +452,8 @@ public class NewTournamentDialog extends MageDialog { .addComponent(spnNumWins, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(lblQuitRatio) .addComponent(spnQuitRatio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblMinimumRating) + .addComponent(spnMinimumRating, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(chkRated)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -521,6 +532,7 @@ public class NewTournamentDialog extends MageDialog { tOptions.setWatchingAllowed(cbAllowSpectators.isSelected()); tOptions.setPlaneChase(cbPlaneChase.isSelected()); tOptions.setQuitRatio((Integer) spnQuitRatio.getValue()); + tOptions.setMinimumRating((Integer) spnMinimumRating.getValue()); for (TournamentPlayerPanel player : players) { tOptions.getPlayerTypes().add((PlayerType) player.getPlayerType().getSelectedItem()); } @@ -1061,6 +1073,7 @@ public class NewTournamentDialog extends MageDialog { this.spnFreeMulligans.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, "0"))); this.spnNumWins.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, "2"))); this.spnQuitRatio.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, "100"))); + this.spnMinimumRating.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, "0"))); TournamentTypeView tournamentType = (TournamentTypeView) cbTournamentType.getSelectedItem(); activatePanelElements(tournamentType); @@ -1146,6 +1159,7 @@ public class NewTournamentDialog extends MageDialog { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_FREE_MULLIGANS + versionStr, Integer.toString(tOptions.getMatchOptions().getFreeMulligans())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_NUMBER_OF_WINS + versionStr, Integer.toString(tOptions.getMatchOptions().getWinsNeeded())); PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_QUIT_RATIO + versionStr, Integer.toString(tOptions.getQuitRatio())); + PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_MINIMUM_RATING + versionStr, Integer.toString(tOptions.getMinimumRating())); if (tOptions.getTournamentType().startsWith("Sealed")) { PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TOURNAMENT_PACKS_SEALED + versionStr, tOptions.getLimitedOptions().getSetCodes().toString()); @@ -1217,6 +1231,7 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JLabel lblPassword; private javax.swing.JLabel lblPlayer1; private javax.swing.JLabel lblQuitRatio; + private javax.swing.JLabel lblMinimumRating; private javax.swing.JLabel lblTournamentType; private mage.client.table.NewPlayerPanel player1Panel; private javax.swing.JPanel pnlDraftOptions; @@ -1231,6 +1246,7 @@ public class NewTournamentDialog extends MageDialog { private javax.swing.JSpinner spnNumRounds; private javax.swing.JSpinner spnNumWins; private javax.swing.JSpinner spnQuitRatio; + private javax.swing.JSpinner spnMinimumRating; private javax.swing.JTextField txtName; private javax.swing.JTextField txtPassword; private org.jdesktop.beansbinding.BindingGroup bindingGroup; diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index 4d595a005a8..5826d2c85b3 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -222,6 +222,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers"; public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes"; public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio"; + public static final String KEY_NEW_TABLE_MINIMUM_RATING = "newTableMinimumRating"; public static final String KEY_NEW_TABLE_RATED = "newTableRated"; // pref setting for new tournament dialog @@ -243,6 +244,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_NEW_TOURNAMENT_ALLOW_ROLLBACKS = "newTournamentAllowRollbacks"; public static final String KEY_NEW_TOURNAMENT_DECK_FILE = "newTournamentDeckFile"; public static final String KEY_NEW_TOURNAMENT_QUIT_RATIO = "newTournamentQuitRatio"; + public static final String KEY_NEW_TOURNAMENT_MINIMUM_RATING = "newTournamentMinimumRating"; public static final String KEY_NEW_TOURNAMENT_RATED = "newTournamentRated"; // pref setting for deck generator diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index d28badf2f79..e486c5f8343 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -1221,6 +1221,7 @@ public class TablesPanel extends javax.swing.JPanel { options.setSkillLevel(SkillLevel.CASUAL); options.setRollbackTurnsAllowed(true); options.setQuitRatio(100); + options.setMinimumRating(0); String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); options.setBannedUsers(IgnoreList.ignoreList(serverAddress)); table = SessionHandler.createTable(roomId, options); @@ -1335,14 +1336,15 @@ class TableTableModel extends AbstractTableModel { public static final int COLUMN_SKILL = 8; public static final int COLUMN_RATING = 9; public static final int COLUMN_QUIT_RATIO = 10; - public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0) + public static final int COLUMN_MINIMUM_RATING = 11; + public static final int ACTION_COLUMN = 12; // column the action is located (starting with 0) public static final String RATED_VALUE_YES = "YES"; public static final String RATED_VALUE_NO = ""; public static final String PASSWORD_VALUE_YES = "YES"; - private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"}; + private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rated", "Quit %", "Min Rating", "Action"}; private TableView[] tables = new TableView[0]; @@ -1390,6 +1392,8 @@ class TableTableModel extends AbstractTableModel { case 10: return tables[arg0].getQuitRatio(); case 11: + return tables[arg0].getMinimumRating(); + case 12: switch (tables[arg0].getTableState()) { case WAITING: @@ -1419,14 +1423,14 @@ class TableTableModel extends AbstractTableModel { default: return ""; } - case 12: - return tables[arg0].isTournament(); case 13: + return tables[arg0].isTournament(); + case 14: if (!tables[arg0].getGames().isEmpty()) { return tables[arg0].getGames().get(0); } return null; - case 14: + case 15: return tables[arg0].getTableId(); } return ""; diff --git a/Mage.Common/src/main/java/mage/view/TableView.java b/Mage.Common/src/main/java/mage/view/TableView.java index c3d748c3446..948c7717bf1 100644 --- a/Mage.Common/src/main/java/mage/view/TableView.java +++ b/Mage.Common/src/main/java/mage/view/TableView.java @@ -36,6 +36,7 @@ public class TableView implements Serializable { private List seats = new ArrayList<>(); private List games = new ArrayList<>(); private final String quitRatio; + private final String minimumRating; private final boolean limited; private final boolean rated; private final boolean passworded; @@ -111,6 +112,7 @@ public class TableView implements Serializable { this.additionalInfo = addInfo.toString(); this.skillLevel = table.getMatch().getOptions().getSkillLevel(); this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio()); + this.minimumRating = Integer.toString(table.getMatch().getOptions().getMinimumRating()); this.limited = table.getMatch().getOptions().isLimited(); this.rated = table.getMatch().getOptions().isRated(); this.passworded = !table.getMatch().getOptions().getPassword().isEmpty(); @@ -159,6 +161,7 @@ public class TableView implements Serializable { this.deckType = table.getDeckType() + ' ' + table.getTournament().getBoosterInfo() + (tableNameInfo != null ? tableNameInfo : ""); this.skillLevel = table.getTournament().getOptions().getMatchOptions().getSkillLevel(); this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio()); + this.minimumRating = Integer.toString(table.getTournament().getOptions().getMinimumRating()); this.limited = table.getTournament().getOptions().getMatchOptions().isLimited(); this.rated = table.getTournament().getOptions().getMatchOptions().isRated(); this.passworded = !table.getTournament().getOptions().getPassword().isEmpty(); @@ -223,9 +226,9 @@ public class TableView implements Serializable { return skillLevel; } - public String getQuitRatio() { - return quitRatio; - } + public String getQuitRatio() { return quitRatio; } + + public String getMinimumRating() { return minimumRating; } public boolean isLimited() { return limited; diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index f6676754ef3..35e7fb4e907 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -227,6 +227,20 @@ public class MageServerImpl implements MageServer { user.showUserMessage("Create tournament", message); throw new MageException("No message"); } + // check if the user satisfies the minimumRating requirement. + int minimumRating = options.getMinimumRating(); + int userRating; + if (options.getMatchOptions().isLimited()) { + userRating = user.getUserData().getLimitedRating(); + } else { + userRating = user.getUserData().getConstructedRating(); + } + if (userRating < minimumRating) { + String message = new StringBuilder("Your rating ").append(userRating) + .append(" is lower than the table requirement ").append(minimumRating).toString(); + user.showUserMessage("Create tournament", message); + throw new MageException("No message"); + } Optional room = GamesRoomManager.instance.getRoom(roomId); if (!room.isPresent()) { @@ -1386,7 +1400,19 @@ public class MageServerImpl implements MageServer { user.showUserMessage("Create table", "Your quit ratio " + user.getMatchQuitRatio() + "% is higher than the table requirement " + quitRatio + '%'); throw new MageException("No message"); } - + // check if the user satisfies the minimumRating requirement. + int minimumRating = options.getMinimumRating(); + int userRating; + if (options.isLimited()) { + userRating = user.getUserData().getLimitedRating(); + } else { + userRating = user.getUserData().getConstructedRating(); + } + if (userRating < minimumRating) { + String message = new StringBuilder("Your rating ").append(userRating).append(" is lower than the table requirement ").append(minimumRating).toString(); + user.showUserMessage("Create table", message); + throw new MageException("No message"); + } Optional room = GamesRoomManager.instance.getRoom(roomId); if (room.isPresent()) { TableView table = room.get().createTable(userId, options); diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index 58a0b695b85..1d511d7e4f8 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -172,6 +172,21 @@ public class TableController { return false; } + // Check minimum rating. + int minimumRating = table.getTournament().getOptions().getMinimumRating(); + int userRating; + if (table.getTournament().getOptions().getMatchOptions().isLimited()) { + userRating = user.getUserData().getLimitedRating(); + } else { + userRating = user.getUserData().getConstructedRating(); + } + if (userRating < minimumRating) { + String message = new StringBuilder("Your rating ").append(userRating) + .append(" is lower than the table requirement ").append(minimumRating).toString(); + user.showUserMessage("Join Table", message); + return false; + } + Optional playerOptional = createPlayer(name, seat.getPlayerType(), skill); if (playerOptional.isPresent()) { Player player = playerOptional.get(); @@ -272,6 +287,21 @@ public class TableController { return false; } + // Check minimum rating. + int minimumRating = table.getMatch().getOptions().getMinimumRating(); + int userRating; + if (table.getMatch().getOptions().isLimited()) { + userRating = user.getUserData().getLimitedRating(); + } else { + userRating = user.getUserData().getConstructedRating(); + } + if (userRating < minimumRating) { + String message = new StringBuilder("Your rating ").append(userRating) + .append(" is lower than the table requirement ").append(minimumRating).toString(); + user.showUserMessage("Join Table", message); + return false; + } + // Check power level for table (currently only used for EDH/Commander table) int edhPowerLevel = table.getMatch().getOptions().getEdhPowerLevel(); if (edhPowerLevel > 0 && table.getValidator().getName().toLowerCase(Locale.ENGLISH).equals("commander")) { diff --git a/Mage/src/main/java/mage/game/match/MatchOptions.java b/Mage/src/main/java/mage/game/match/MatchOptions.java index 02e6808416c..47ad873e631 100644 --- a/Mage/src/main/java/mage/game/match/MatchOptions.java +++ b/Mage/src/main/java/mage/game/match/MatchOptions.java @@ -37,6 +37,7 @@ public class MatchOptions implements Serializable { protected boolean spectatorsAllowed; protected boolean planeChase; protected int quitRatio; + protected int minimumRating; protected int edhPowerLevel; protected boolean rated; protected int numSeatsForMatch; @@ -205,6 +206,10 @@ public class MatchOptions implements Serializable { this.quitRatio = quitRatio; } + public int getMinimumRating() { return minimumRating; } + + public void setMinimumRating(int minimumRating) { this.minimumRating = minimumRating; } + public int getEdhPowerLevel() { return edhPowerLevel; } diff --git a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java index 2b042d19a1d..c81294ce3ee 100644 --- a/Mage/src/main/java/mage/game/tournament/TournamentOptions.java +++ b/Mage/src/main/java/mage/game/tournament/TournamentOptions.java @@ -24,6 +24,7 @@ public class TournamentOptions implements Serializable { protected int numberRounds; protected String password; protected int quitRatio; + protected int minimumRating; public TournamentOptions(String name, String matchType, int numSeats) { this.name = name; @@ -98,4 +99,8 @@ public class TournamentOptions implements Serializable { public void setQuitRatio(int quitRatio) { this.quitRatio = quitRatio; } + + public int getMinimumRating() { return minimumRating; } + + public void setMinimumRating(int minimumRating) { this.minimumRating = minimumRating; } } From 88f3db03c4ac3e575e51c3f3be8654bd78edf4c9 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Wed, 3 Oct 2018 17:38:30 -0700 Subject: [PATCH 04/50] Both players' decks show up at the same time, but hangs if you don't select in the correct order --- .../mage/cards/j/JaceArchitectOfThought.java | 68 +++++++++++++++---- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 09ebb7644ef..1caa13f393f 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -1,6 +1,8 @@ package mage.cards.j; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Set; import java.util.UUID; @@ -34,10 +36,13 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import javax.swing.*; + /** * * @@ -239,23 +244,21 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } + ArrayList threads = new ArrayList<>(); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (source.isControlledBy(player.getId())) { - playerName = "your"; - } - TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (controller.searchLibrary(target, game, playerId)) { - UUID targetId = target.getFirstTarget(); - Card card = player.getLibrary().remove(targetId, game); - if (card != null) { - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + JaceArchitectOfThoughtEffect3Helper thread = new JaceArchitectOfThoughtEffect3Helper(playerId, game, source, sourcePermanent, controller); + thread.execute(); + thread.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if("state".equals(evt.getPropertyName()) && SwingWorker.StateValue.DONE.equals(evt.getNewValue())){ + threads.remove(evt.getSource()); + } } - } - player.shuffleLibrary(source, game); + }); + threads.add(thread); } - + while(threads.size() > 0) {} ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; @@ -274,3 +277,40 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { return true; } } + +class JaceArchitectOfThoughtEffect3Helper extends SwingWorker { + + UUID playerId; + Game game; + Ability source; + Permanent sourcePermanent; + Player controller; + + public JaceArchitectOfThoughtEffect3Helper (UUID playerId, Game game, Ability source, Permanent sourcePermanent, Player controller) { + this.playerId = playerId; + this.game = game; + this.source = source; + this.sourcePermanent = sourcePermanent; + this.controller = controller; + } + + @Override + protected Boolean doInBackground() throws Exception { + Player player = this.game.getPlayer(this.playerId); + String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); + if (this.source.isControlledBy(player.getId())) { + playerName = "your"; + } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); + if (this.controller.searchLibrary(target, this.game, this.playerId)) { + UUID targetId = target.getFirstTarget(); + Card card = player.getLibrary().remove(targetId, this.game); + if (card != null) { + this.controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(this.game, this.source), this.sourcePermanent.getIdName(), this.source.getSourceId(), this.game, Zone.LIBRARY, true); + } + player.shuffleLibrary(this.source, this.game); + } + return true; + } + +} From 02d9287cfae35c50956ec2b81971fc32ede28956 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 11:19:40 -0700 Subject: [PATCH 05/50] Reverting concurrent code to start fresh --- .../mage/cards/j/JaceArchitectOfThought.java | 68 ++++--------------- 1 file changed, 14 insertions(+), 54 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 1caa13f393f..09ebb7644ef 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -1,8 +1,6 @@ package mage.cards.j; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Set; import java.util.UUID; @@ -36,13 +34,10 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; -import javax.swing.*; - /** * * @@ -244,21 +239,23 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } - ArrayList threads = new ArrayList<>(); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - JaceArchitectOfThoughtEffect3Helper thread = new JaceArchitectOfThoughtEffect3Helper(playerId, game, source, sourcePermanent, controller); - thread.execute(); - thread.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if("state".equals(evt.getPropertyName()) && SwingWorker.StateValue.DONE.equals(evt.getNewValue())){ - threads.remove(evt.getSource()); - } + Player player = game.getPlayer(playerId); + String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); + if (source.isControlledBy(player.getId())) { + playerName = "your"; + } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); + if (controller.searchLibrary(target, game, playerId)) { + UUID targetId = target.getFirstTarget(); + Card card = player.getLibrary().remove(targetId, game); + if (card != null) { + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); } - }); - threads.add(thread); + } + player.shuffleLibrary(source, game); } - while(threads.size() > 0) {} + ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; @@ -277,40 +274,3 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { return true; } } - -class JaceArchitectOfThoughtEffect3Helper extends SwingWorker { - - UUID playerId; - Game game; - Ability source; - Permanent sourcePermanent; - Player controller; - - public JaceArchitectOfThoughtEffect3Helper (UUID playerId, Game game, Ability source, Permanent sourcePermanent, Player controller) { - this.playerId = playerId; - this.game = game; - this.source = source; - this.sourcePermanent = sourcePermanent; - this.controller = controller; - } - - @Override - protected Boolean doInBackground() throws Exception { - Player player = this.game.getPlayer(this.playerId); - String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (this.source.isControlledBy(player.getId())) { - playerName = "your"; - } - TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (this.controller.searchLibrary(target, this.game, this.playerId)) { - UUID targetId = target.getFirstTarget(); - Card card = player.getLibrary().remove(targetId, this.game); - if (card != null) { - this.controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(this.game, this.source), this.sourcePermanent.getIdName(), this.source.getSourceId(), this.game, Zone.LIBRARY, true); - } - player.shuffleLibrary(this.source, this.game); - } - return true; - } - -} From c5cedc2abacbe2fff2e2564d8663244824df8e78 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 13:45:44 -0700 Subject: [PATCH 06/50] Adding lookAtAllLibraries to Player/PlayerImpl and using that method during JAOT's -8 resolution --- .../src/mage/cards/j/JaceArchitectOfThought.java | 2 ++ Mage/src/main/java/mage/players/Player.java | 9 +++++++++ Mage/src/main/java/mage/players/PlayerImpl.java | 12 ++++++++++++ 3 files changed, 23 insertions(+) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 09ebb7644ef..8a5c9342e1d 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -239,12 +239,14 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } + controller.lookAtAllLibraries(source, game); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); if (source.isControlledBy(player.getId())) { playerName = "your"; } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); if (controller.searchLibrary(target, game, playerId)) { UUID targetId = target.getFirstTarget(); diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index a730164f736..f6f30cf08e5 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -350,6 +350,15 @@ public interface Player extends MageItem, Copyable { */ boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents); + /** + * Reveals all players' libraries. Useful for abilities like Jace, Architect of Thought's -8 + * that have effects that require information from all libraries. + * @param source + * @param game + * @return + */ + boolean lookAtAllLibraries(Ability source, Game game); + boolean canPlayLand(); /** diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 2659dfd1450..9b202e4466c 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2477,6 +2477,18 @@ public abstract class PlayerImpl implements Player, Serializable { return false; } + @Override + public boolean lookAtAllLibraries(Ability source, Game game) { + for(UUID playerId : game.getState().getPlayersInRange(this.getId(), game)){ + Player player = game.getPlayer(playerId); + String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s "; + playerName += "library"; + Cards cardsInLibrary = new CardsImpl(player.getLibrary().getTopCards(game, player.getLibrary().size())); + lookAtCards(playerName, cardsInLibrary, game); + } + return true; + } + private boolean handleLibraryCastableCards(Library library, Game game, UUID targetPlayerId) { // for handling Panglacial Wurm boolean alreadyChosenUse = false; From 4057cc2859b0e448b72fd6845daa529ec0ff3a0b Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 14:16:52 -0700 Subject: [PATCH 07/50] Implementing new function in all classes implementing Player --- Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java | 4 ++++ Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java | 3 +++ Mage/src/main/java/mage/players/Player.java | 2 +- Mage/src/main/java/mage/players/PlayerImpl.java | 3 +-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 0fa4a84a094..05837e862f4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2072,6 +2072,10 @@ public class TestPlayer implements Player { return computerPlayer.searchLibrary(target, game, targetPlayerId, triggerEvents); } + public void lookAtAllLibraries(Ability source, Game game) { + computerPlayer.lookAtAllLibraries(source, game); + } + @Override public boolean flipCoin(Game game) { return computerPlayer.flipCoin(game); diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index 810c068ccf6..360bd942514 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -597,6 +597,9 @@ public class PlayerStub implements Player { return false; } + @Override + public void lookAtAllLibraries(Ability source, Game game) {} + @Override public boolean canPlayLand() { return false; diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index f6f30cf08e5..ec86ad550c1 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -357,7 +357,7 @@ public interface Player extends MageItem, Copyable { * @param game * @return */ - boolean lookAtAllLibraries(Ability source, Game game); + void lookAtAllLibraries(Ability source, Game game); boolean canPlayLand(); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 9b202e4466c..53053fb0466 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2478,7 +2478,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean lookAtAllLibraries(Ability source, Game game) { + public void lookAtAllLibraries(Ability source, Game game) { for(UUID playerId : game.getState().getPlayersInRange(this.getId(), game)){ Player player = game.getPlayer(playerId); String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s "; @@ -2486,7 +2486,6 @@ public abstract class PlayerImpl implements Player, Serializable { Cards cardsInLibrary = new CardsImpl(player.getLibrary().getTopCards(game, player.getLibrary().size())); lookAtCards(playerName, cardsInLibrary, game); } - return true; } private boolean handleLibraryCastableCards(Library library, Game game, UUID targetPlayerId) { From 297b543630a6ea301234a787e472baed6f73047b Mon Sep 17 00:00:00 2001 From: L_J Date: Thu, 4 Oct 2018 22:12:06 +0000 Subject: [PATCH 08/50] Jace, Architect of Thought ult fix --- .../mage/cards/j/JaceArchitectOfThought.java | 57 +++++++++++++++---- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 09ebb7644ef..e6c207f4d5a 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -2,6 +2,7 @@ package mage.cards.j; import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.UUID; import mage.MageObjectReference; @@ -24,7 +25,10 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.FilterPlayer; import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; @@ -32,6 +36,7 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; +import mage.target.TargetPlayer; import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; @@ -239,21 +244,49 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (source.isControlledBy(player.getId())) { - playerName = "your"; + List playerList = new ArrayList<>(); + playerList.addAll(game.getState().getPlayersInRange(controller.getId(), game)); + List checkList = new ArrayList<>(); + while (!playerList.isEmpty()) { + FilterPlayer filter = new FilterPlayer(); + List playerPredicates = new ArrayList<>(); + for (UUID playerId : playerList) { + playerPredicates.add(new PlayerIdPredicate(playerId)); } - TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (controller.searchLibrary(target, game, playerId)) { - UUID targetId = target.getFirstTarget(); - Card card = player.getLibrary().remove(targetId, game); - if (card != null) { - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + filter.add(Predicates.or(playerPredicates)); + TargetPlayer targetPlayer = new TargetPlayer(1, 1, true, filter); + targetPlayer.setRequired(!checkList.containsAll(playerList)); + if (controller.chooseTarget(outcome, targetPlayer, source, game)) { + UUID playerId = targetPlayer.getFirstTarget(); + Player player = game.getPlayer(playerId); + if (player != null) { + String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); + if (source.isControlledBy(player.getId())) { + playerName = "your"; + } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); + if (controller.searchLibrary(target, game, playerId)) { + UUID targetId = target.getFirstTarget(); + Card card = player.getLibrary().remove(targetId, game); + if (card != null) { + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + playerList.remove(playerId); + } + } + if (!checkList.contains(playerId)) { + player.shuffleLibrary(source, game); // only one shuffle per library (to prevent bad interactions with Psychogenic Probe etc.) + } + } + checkList.add(playerId); + } else { + break; + } + for (UUID playerId : playerList) { + Player player = game.getPlayer(playerId); + if (player == null || !player.canRespond()) { + playerList.remove(player); } } - player.shuffleLibrary(source, game); } ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); From 2ed63a7184cc29bb163ad17fb702a1f28395d915 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 15:14:43 -0700 Subject: [PATCH 09/50] Notifying players of library search, and giving controller choice to search --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 5 ++++- .../src/test/java/org/mage/test/player/TestPlayer.java | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 8a5c9342e1d..125d144b15d 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -239,7 +239,10 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } - controller.lookAtAllLibraries(source, game); + if(controller.chooseUse(Outcome.Benefit, "Look at all players' libraries before card select?", null, game)) { + game.informPlayers(controller.getLogName() + " is looking at all players' libraries."); + controller.lookAtAllLibraries(source, game); + } for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 05837e862f4..8c22e36169e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2072,6 +2072,7 @@ public class TestPlayer implements Player { return computerPlayer.searchLibrary(target, game, targetPlayerId, triggerEvents); } + @Override public void lookAtAllLibraries(Ability source, Game game) { computerPlayer.lookAtAllLibraries(source, game); } From 57fdae9c9235ce115e8b5d37fec99a82e892890d Mon Sep 17 00:00:00 2001 From: L_J Date: Thu, 4 Oct 2018 22:43:23 +0000 Subject: [PATCH 10/50] Minor shuffle fix --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index e6c207f4d5a..770ae965aae 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -273,9 +273,6 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { playerList.remove(playerId); } } - if (!checkList.contains(playerId)) { - player.shuffleLibrary(source, game); // only one shuffle per library (to prevent bad interactions with Psychogenic Probe etc.) - } } checkList.add(playerId); } else { @@ -288,7 +285,12 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { } } } - + for (UUID playerId : checkList) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.shuffleLibrary(source, game); + } + } ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; From bf4988382ed17befe1e3de59f6f8bdec8a67987c Mon Sep 17 00:00:00 2001 From: L_J Date: Thu, 4 Oct 2018 22:53:50 +0000 Subject: [PATCH 11/50] More edits --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 770ae965aae..88695547985 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -266,15 +266,19 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { } TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); if (controller.searchLibrary(target, game, playerId)) { + checkList.add(playerId); UUID targetId = target.getFirstTarget(); Card card = player.getLibrary().remove(targetId, game); if (card != null) { controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); playerList.remove(playerId); } + } else { + playerList.remove(playerId); } + } else { + playerList.remove(playerId); } - checkList.add(playerId); } else { break; } From b67107b1b5de09bc0dd0e4c402f39fb782daaaf5 Mon Sep 17 00:00:00 2001 From: L_J Date: Wed, 10 Oct 2018 22:55:42 +0000 Subject: [PATCH 12/50] Prevent arbitrary library search triggers from Jace ultimate --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 88695547985..2dd15baf2d1 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -265,7 +265,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { playerName = "your"; } TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (controller.searchLibrary(target, game, playerId)) { + if (controller.searchLibrary(target, game, playerId, !checkList.contains(playerId))) { checkList.add(playerId); UUID targetId = target.getFirstTarget(); Card card = player.getLibrary().remove(targetId, game); From 9939af89683b6a9cad560899084dcbe8e0ae6322 Mon Sep 17 00:00:00 2001 From: L_J Date: Wed, 10 Oct 2018 23:09:49 +0000 Subject: [PATCH 13/50] Prevent arbitrary shuffles from Jace ultimate --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 2dd15baf2d1..f5f54108041 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -2,6 +2,7 @@ package mage.cards.j; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; @@ -246,7 +247,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { } List playerList = new ArrayList<>(); playerList.addAll(game.getState().getPlayersInRange(controller.getId(), game)); - List checkList = new ArrayList<>(); + Set checkList = new HashSet<>(); while (!playerList.isEmpty()) { FilterPlayer filter = new FilterPlayer(); List playerPredicates = new ArrayList<>(); From 738cb59eaf59b2ff523e8978b40a6a724542de46 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 22 Nov 2018 19:17:18 +0400 Subject: [PATCH 14/50] Added all cards to Ultimate Masters --- Mage.Sets/src/mage/sets/UltimateMasters.java | 214 ++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/UltimateMasters.java b/Mage.Sets/src/mage/sets/UltimateMasters.java index a97affe33b6..7e39b5da524 100644 --- a/Mage.Sets/src/mage/sets/UltimateMasters.java +++ b/Mage.Sets/src/mage/sets/UltimateMasters.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -27,46 +26,259 @@ public final class UltimateMasters extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Aethersnipe", 44, Rarity.COMMON, mage.cards.a.Aethersnipe.class)); + cards.add(new SetCardInfo("Akroan Crusader", 121, Rarity.COMMON, mage.cards.a.AkroanCrusader.class)); + cards.add(new SetCardInfo("All Is Dust", 1, Rarity.RARE, mage.cards.a.AllIsDust.class)); + cards.add(new SetCardInfo("Ancestor's Chosen", 9, Rarity.UNCOMMON, mage.cards.a.AncestorsChosen.class)); cards.add(new SetCardInfo("Ancient Tomb", 236, Rarity.RARE, mage.cards.a.AncientTomb.class)); + cards.add(new SetCardInfo("Angel of Despair", 196, Rarity.UNCOMMON, mage.cards.a.AngelOfDespair.class)); + cards.add(new SetCardInfo("Angelic Renewal", 10, Rarity.COMMON, mage.cards.a.AngelicRenewal.class)); + cards.add(new SetCardInfo("Anger", 122, Rarity.UNCOMMON, mage.cards.a.Anger.class)); + cards.add(new SetCardInfo("Appetite for Brains", 83, Rarity.UNCOMMON, mage.cards.a.AppetiteForBrains.class)); + cards.add(new SetCardInfo("Apprentice Necromancer", 84, Rarity.UNCOMMON, mage.cards.a.ApprenticeNecromancer.class)); + cards.add(new SetCardInfo("Archaeomancer", 45, Rarity.COMMON, mage.cards.a.Archaeomancer.class)); + cards.add(new SetCardInfo("Arena Athlete", 123, Rarity.COMMON, mage.cards.a.ArenaAthlete.class)); + cards.add(new SetCardInfo("Artisan of Kozilek", 2, Rarity.UNCOMMON, mage.cards.a.ArtisanOfKozilek.class)); + cards.add(new SetCardInfo("Back to Basics", 46, Rarity.RARE, mage.cards.b.BackToBasics.class)); cards.add(new SetCardInfo("Balefire Dragon", 124, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); + cards.add(new SetCardInfo("Basking Rootwalla", 156, Rarity.COMMON, mage.cards.b.BaskingRootwalla.class)); + cards.add(new SetCardInfo("Beckon Apparition", 211, Rarity.COMMON, mage.cards.b.BeckonApparition.class)); + cards.add(new SetCardInfo("Become Immense", 157, Rarity.UNCOMMON, mage.cards.b.BecomeImmense.class)); cards.add(new SetCardInfo("Bitterblossom", 85, Rarity.MYTHIC, mage.cards.b.Bitterblossom.class)); + cards.add(new SetCardInfo("Blast of Genius", 197, Rarity.UNCOMMON, mage.cards.b.BlastOfGenius.class)); + cards.add(new SetCardInfo("Bloodflow Connoisseur", 86, Rarity.COMMON, mage.cards.b.BloodflowConnoisseur.class)); + cards.add(new SetCardInfo("Boar Umbra", 158, Rarity.UNCOMMON, mage.cards.b.BoarUmbra.class)); + cards.add(new SetCardInfo("Boneyard Wurm", 159, Rarity.UNCOMMON, mage.cards.b.BoneyardWurm.class)); + cards.add(new SetCardInfo("Brawn", 160, Rarity.UNCOMMON, mage.cards.b.Brawn.class)); + cards.add(new SetCardInfo("Brazen Scourge", 125, Rarity.UNCOMMON, mage.cards.b.BrazenScourge.class)); + cards.add(new SetCardInfo("Bridge from Below", 87, Rarity.RARE, mage.cards.b.BridgeFromBelow.class)); + cards.add(new SetCardInfo("Buried Alive", 88, Rarity.UNCOMMON, mage.cards.b.BuriedAlive.class)); + cards.add(new SetCardInfo("Canker Abomination", 212, Rarity.COMMON, mage.cards.c.CankerAbomination.class)); + cards.add(new SetCardInfo("Cathodion", 226, Rarity.COMMON, mage.cards.c.Cathodion.class)); cards.add(new SetCardInfo("Cavern of Souls", 237, Rarity.MYTHIC, mage.cards.c.CavernOfSouls.class)); cards.add(new SetCardInfo("Celestial Colonnade", 238, Rarity.RARE, mage.cards.c.CelestialColonnade.class)); + cards.add(new SetCardInfo("Chainer's Edict", 89, Rarity.UNCOMMON, mage.cards.c.ChainersEdict.class)); + cards.add(new SetCardInfo("Circular Logic", 47, Rarity.UNCOMMON, mage.cards.c.CircularLogic.class)); + cards.add(new SetCardInfo("Conflagrate", 126, Rarity.UNCOMMON, mage.cards.c.Conflagrate.class)); + cards.add(new SetCardInfo("Containment Priest", 11, Rarity.RARE, mage.cards.c.ContainmentPriest.class)); + cards.add(new SetCardInfo("Conviction", 12, Rarity.COMMON, mage.cards.c.Conviction.class)); + cards.add(new SetCardInfo("Countersquall", 198, Rarity.UNCOMMON, mage.cards.c.Countersquall.class)); cards.add(new SetCardInfo("Creeping Tar Pit", 239, Rarity.RARE, mage.cards.c.CreepingTarPit.class)); + cards.add(new SetCardInfo("Crow of Dark Tidings", 90, Rarity.COMMON, mage.cards.c.CrowOfDarkTidings.class)); + cards.add(new SetCardInfo("Crushing Canopy", 161, Rarity.COMMON, mage.cards.c.CrushingCanopy.class)); + cards.add(new SetCardInfo("Dakmor Salvage", 240, Rarity.UNCOMMON, mage.cards.d.DakmorSalvage.class)); + cards.add(new SetCardInfo("Dark Dabbling", 91, Rarity.COMMON, mage.cards.d.DarkDabbling.class)); cards.add(new SetCardInfo("Dark Depths", 241, Rarity.MYTHIC, mage.cards.d.DarkDepths.class)); + cards.add(new SetCardInfo("Dawn Charm", 13, Rarity.UNCOMMON, mage.cards.d.DawnCharm.class)); + cards.add(new SetCardInfo("Daybreak Coronet", 14, Rarity.RARE, mage.cards.d.DaybreakCoronet.class)); + cards.add(new SetCardInfo("Death Denied", 92, Rarity.COMMON, mage.cards.d.DeathDenied.class)); + cards.add(new SetCardInfo("Defy Gravity", 48, Rarity.COMMON, mage.cards.d.DefyGravity.class)); cards.add(new SetCardInfo("Demonic Tutor", 93, Rarity.RARE, mage.cards.d.DemonicTutor.class)); + cards.add(new SetCardInfo("Deranged Assistant", 49, Rarity.COMMON, mage.cards.d.DerangedAssistant.class)); + cards.add(new SetCardInfo("Desolate Lighthouse", 242, Rarity.RARE, mage.cards.d.DesolateLighthouse.class)); + cards.add(new SetCardInfo("Desperate Ritual", 127, Rarity.UNCOMMON, mage.cards.d.DesperateRitual.class)); + cards.add(new SetCardInfo("Devoted Druid", 162, Rarity.UNCOMMON, mage.cards.d.DevotedDruid.class)); + cards.add(new SetCardInfo("Dig Through Time", 50, Rarity.RARE, mage.cards.d.DigThroughTime.class)); + cards.add(new SetCardInfo("Dimir Guildmage", 213, Rarity.COMMON, mage.cards.d.DimirGuildmage.class)); + cards.add(new SetCardInfo("Disrupting Shoal", 51, Rarity.RARE, mage.cards.d.DisruptingShoal.class)); + cards.add(new SetCardInfo("Double Cleave", 214, Rarity.COMMON, mage.cards.d.DoubleCleave.class)); + cards.add(new SetCardInfo("Dreamscape Artist", 52, Rarity.UNCOMMON, mage.cards.d.DreamscapeArtist.class)); + cards.add(new SetCardInfo("Eel Umbra", 53, Rarity.COMMON, mage.cards.e.EelUmbra.class)); + cards.add(new SetCardInfo("Eldrazi Conscription", 3, Rarity.RARE, mage.cards.e.EldraziConscription.class)); + cards.add(new SetCardInfo("Emancipation Angel", 15, Rarity.UNCOMMON, mage.cards.e.EmancipationAngel.class)); cards.add(new SetCardInfo("Emrakul, the Aeons Torn", 4, Rarity.MYTHIC, mage.cards.e.EmrakulTheAeonsTorn.class)); cards.add(new SetCardInfo("Engineered Explosives", 227, Rarity.RARE, mage.cards.e.EngineeredExplosives.class)); cards.add(new SetCardInfo("Entomb", 94, Rarity.RARE, mage.cards.e.Entomb.class)); cards.add(new SetCardInfo("Eternal Witness", 163, Rarity.UNCOMMON, mage.cards.e.EternalWitness.class)); + cards.add(new SetCardInfo("Faith's Fetters", 16, Rarity.COMMON, mage.cards.f.FaithsFetters.class)); + cards.add(new SetCardInfo("Faithless Looting", 128, Rarity.COMMON, mage.cards.f.FaithlessLooting.class)); + cards.add(new SetCardInfo("Fauna Shaman", 164, Rarity.RARE, mage.cards.f.FaunaShaman.class)); + cards.add(new SetCardInfo("Fecundity", 165, Rarity.UNCOMMON, mage.cards.f.Fecundity.class)); + cards.add(new SetCardInfo("Fiend Hunter", 17, Rarity.UNCOMMON, mage.cards.f.FiendHunter.class)); + cards.add(new SetCardInfo("Fiery Temper", 129, Rarity.COMMON, mage.cards.f.FieryTemper.class)); + cards.add(new SetCardInfo("Fire // Ice", 225, Rarity.COMMON, mage.cards.f.FireIce.class)); + cards.add(new SetCardInfo("Firewing Phoenix", 130, Rarity.UNCOMMON, mage.cards.f.FirewingPhoenix.class)); + cards.add(new SetCardInfo("Flagstones of Trokair", 243, Rarity.RARE, mage.cards.f.FlagstonesOfTrokair.class)); + cards.add(new SetCardInfo("Flight of Fancy", 54, Rarity.COMMON, mage.cards.f.FlightOfFancy.class)); + cards.add(new SetCardInfo("Foil", 55, Rarity.COMMON, mage.cards.f.Foil.class)); + cards.add(new SetCardInfo("Forbidden Alchemy", 56, Rarity.UNCOMMON, mage.cards.f.ForbiddenAlchemy.class)); + cards.add(new SetCardInfo("Frantic Search", 57, Rarity.COMMON, mage.cards.f.FranticSearch.class)); cards.add(new SetCardInfo("Fulminator Mage", 215, Rarity.RARE, mage.cards.f.FulminatorMage.class)); + cards.add(new SetCardInfo("Fume Spitter", 95, Rarity.COMMON, mage.cards.f.FumeSpitter.class)); + cards.add(new SetCardInfo("Furnace Celebration", 131, Rarity.UNCOMMON, mage.cards.f.FurnaceCelebration.class)); cards.add(new SetCardInfo("Gaddock Teeg", 199, Rarity.RARE, mage.cards.g.GaddockTeeg.class)); + cards.add(new SetCardInfo("Gamble", 132, Rarity.RARE, mage.cards.g.Gamble.class)); + cards.add(new SetCardInfo("Garna, the Bloodflame", 200, Rarity.UNCOMMON, mage.cards.g.GarnaTheBloodflame.class)); + cards.add(new SetCardInfo("Generator Servant", 133, Rarity.COMMON, mage.cards.g.GeneratorServant.class)); + cards.add(new SetCardInfo("Ghoulcaller's Accomplice", 96, Rarity.COMMON, mage.cards.g.GhoulcallersAccomplice.class)); + cards.add(new SetCardInfo("Ghoulsteed", 97, Rarity.UNCOMMON, mage.cards.g.Ghoulsteed.class)); + cards.add(new SetCardInfo("Glen Elendra Archmage", 58, Rarity.RARE, mage.cards.g.GlenElendraArchmage.class)); + cards.add(new SetCardInfo("Gods Willing", 18, Rarity.COMMON, mage.cards.g.GodsWilling.class)); + cards.add(new SetCardInfo("Golgari Brownscale", 166, Rarity.COMMON, mage.cards.g.GolgariBrownscale.class)); + cards.add(new SetCardInfo("Golgari Charm", 201, Rarity.UNCOMMON, mage.cards.g.GolgariCharm.class)); + cards.add(new SetCardInfo("Golgari Grave-Troll", 167, Rarity.RARE, mage.cards.g.GolgariGraveTroll.class)); + cards.add(new SetCardInfo("Golgari Thug", 98, Rarity.UNCOMMON, mage.cards.g.GolgariThug.class)); cards.add(new SetCardInfo("Goryo's Vengeance", 99, Rarity.RARE, mage.cards.g.GoryosVengeance.class)); + cards.add(new SetCardInfo("Grave Scrabbler", 100, Rarity.COMMON, mage.cards.g.GraveScrabbler.class)); + cards.add(new SetCardInfo("Grave Strength", 101, Rarity.UNCOMMON, mage.cards.g.GraveStrength.class)); + cards.add(new SetCardInfo("Groundskeeper", 168, Rarity.COMMON, mage.cards.g.Groundskeeper.class)); + cards.add(new SetCardInfo("Gurmag Angler", 102, Rarity.COMMON, mage.cards.g.GurmagAngler.class)); + cards.add(new SetCardInfo("Heap Doll", 228, Rarity.UNCOMMON, mage.cards.h.HeapDoll.class)); + cards.add(new SetCardInfo("Heliod's Pilgrim", 19, Rarity.COMMON, mage.cards.h.HeliodsPilgrim.class)); + cards.add(new SetCardInfo("Hero of Iroas", 20, Rarity.UNCOMMON, mage.cards.h.HeroOfIroas.class)); + cards.add(new SetCardInfo("Hero of Leina Tower", 169, Rarity.UNCOMMON, mage.cards.h.HeroOfLeinaTower.class)); + cards.add(new SetCardInfo("Hissing Iguanar", 134, Rarity.COMMON, mage.cards.h.HissingIguanar.class)); + cards.add(new SetCardInfo("Hooting Mandrills", 170, Rarity.COMMON, mage.cards.h.HootingMandrills.class)); + cards.add(new SetCardInfo("Hyena Umbra", 21, Rarity.COMMON, mage.cards.h.HyenaUmbra.class)); + cards.add(new SetCardInfo("Icatian Crier", 22, Rarity.COMMON, mage.cards.i.IcatianCrier.class)); + cards.add(new SetCardInfo("Ingot Chewer", 135, Rarity.COMMON, mage.cards.i.IngotChewer.class)); + cards.add(new SetCardInfo("Iridescent Drake", 59, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); + cards.add(new SetCardInfo("Just the Wind", 60, Rarity.COMMON, mage.cards.j.JustTheWind.class)); cards.add(new SetCardInfo("Karakas", 244, Rarity.MYTHIC, mage.cards.k.Karakas.class)); cards.add(new SetCardInfo("Karn Liberated", 5, Rarity.MYTHIC, mage.cards.k.KarnLiberated.class)); cards.add(new SetCardInfo("Kitchen Finks", 216, Rarity.UNCOMMON, mage.cards.k.KitchenFinks.class)); + cards.add(new SetCardInfo("Kodama's Reach", 171, Rarity.COMMON, mage.cards.k.KodamasReach.class)); cards.add(new SetCardInfo("Kozilek, Butcher of Truth", 6, Rarity.MYTHIC, mage.cards.k.KozilekButcherOfTruth.class)); + cards.add(new SetCardInfo("Laboratory Maniac", 61, Rarity.UNCOMMON, mage.cards.l.LaboratoryManiac.class)); + cards.add(new SetCardInfo("Last Gasp", 103, Rarity.COMMON, mage.cards.l.LastGasp.class)); + cards.add(new SetCardInfo("Lava Spike", 136, Rarity.UNCOMMON, mage.cards.l.LavaSpike.class)); cards.add(new SetCardInfo("Lavaclaw Reaches", 245, Rarity.RARE, mage.cards.l.LavaclawReaches.class)); cards.add(new SetCardInfo("Leovold, Emissary of Trest", 202, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); cards.add(new SetCardInfo("Life from the Loam", 172, Rarity.RARE, mage.cards.l.LifeFromTheLoam.class)); cards.add(new SetCardInfo("Liliana of the Veil", 104, Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class)); + cards.add(new SetCardInfo("Living Lore", 62, Rarity.UNCOMMON, mage.cards.l.LivingLore.class)); cards.add(new SetCardInfo("Lord of Extinction", 203, Rarity.MYTHIC, mage.cards.l.LordOfExtinction.class)); + cards.add(new SetCardInfo("Lotus-Eye Mystics", 23, Rarity.COMMON, mage.cards.l.LotusEyeMystics.class)); + cards.add(new SetCardInfo("Mad Prophet", 137, Rarity.COMMON, mage.cards.m.MadProphet.class)); cards.add(new SetCardInfo("Maelstrom Pulse", 204, Rarity.RARE, mage.cards.m.MaelstromPulse.class)); + cards.add(new SetCardInfo("Mage-Ring Network", 246, Rarity.UNCOMMON, mage.cards.m.MageRingNetwork.class)); + cards.add(new SetCardInfo("Magmaw", 138, Rarity.UNCOMMON, mage.cards.m.Magmaw.class)); + cards.add(new SetCardInfo("Magus of the Bazaar", 63, Rarity.RARE, mage.cards.m.MagusOfTheBazaar.class)); + cards.add(new SetCardInfo("Mahamoti Djinn", 64, Rarity.UNCOMMON, mage.cards.m.MahamotiDjinn.class)); + cards.add(new SetCardInfo("Malevolent Whispers", 139, Rarity.UNCOMMON, mage.cards.m.MalevolentWhispers.class)); + cards.add(new SetCardInfo("Mammoth Umbra", 24, Rarity.COMMON, mage.cards.m.MammothUmbra.class)); cards.add(new SetCardInfo("Mana Vault", 229, Rarity.MYTHIC, mage.cards.m.ManaVault.class)); + cards.add(new SetCardInfo("Marang River Prowler", 65, Rarity.UNCOMMON, mage.cards.m.MarangRiverProwler.class)); + cards.add(new SetCardInfo("Mark of the Vampire", 105, Rarity.COMMON, mage.cards.m.MarkOfTheVampire.class)); + cards.add(new SetCardInfo("Martyr of Sands", 25, Rarity.COMMON, mage.cards.m.MartyrOfSands.class)); cards.add(new SetCardInfo("Mikaeus, the Unhallowed", 106, Rarity.MYTHIC, mage.cards.m.MikaeusTheUnhallowed.class)); + cards.add(new SetCardInfo("Miming Slime", 173, Rarity.COMMON, mage.cards.m.MimingSlime.class)); + cards.add(new SetCardInfo("Miraculous Recovery", 26, Rarity.UNCOMMON, mage.cards.m.MiraculousRecovery.class)); + cards.add(new SetCardInfo("Mistveil Plains", 247, Rarity.UNCOMMON, mage.cards.m.MistveilPlains.class)); + cards.add(new SetCardInfo("Moan of the Unhallowed", 107, Rarity.COMMON, mage.cards.m.MoanOfTheUnhallowed.class)); + cards.add(new SetCardInfo("Molten Birth", 140, Rarity.COMMON, mage.cards.m.MoltenBirth.class)); + cards.add(new SetCardInfo("Murderous Redcap", 217, Rarity.UNCOMMON, mage.cards.m.MurderousRedcap.class)); + cards.add(new SetCardInfo("Myr Servitor", 230, Rarity.COMMON, mage.cards.m.MyrServitor.class)); + cards.add(new SetCardInfo("Mystic Retrieval", 66, Rarity.UNCOMMON, mage.cards.m.MysticRetrieval.class)); + cards.add(new SetCardInfo("Nightbird's Clutches", 141, Rarity.COMMON, mage.cards.n.NightbirdsClutches.class)); cards.add(new SetCardInfo("Noble Hierarch", 174, Rarity.RARE, mage.cards.n.NobleHierarch.class)); + cards.add(new SetCardInfo("Nourishing Shoal", 175, Rarity.RARE, mage.cards.n.NourishingShoal.class)); + cards.add(new SetCardInfo("Offalsnout", 108, Rarity.COMMON, mage.cards.o.Offalsnout.class)); + cards.add(new SetCardInfo("Olivia's Dragoon", 109, Rarity.COMMON, mage.cards.o.OliviasDragoon.class)); + cards.add(new SetCardInfo("Patchwork Gnomes", 231, Rarity.COMMON, mage.cards.p.PatchworkGnomes.class)); + cards.add(new SetCardInfo("Pattern of Rebirth", 176, Rarity.RARE, mage.cards.p.PatternOfRebirth.class)); + cards.add(new SetCardInfo("Penumbra Wurm", 177, Rarity.UNCOMMON, mage.cards.p.PenumbraWurm.class)); + cards.add(new SetCardInfo("Phalanx Leader", 27, Rarity.UNCOMMON, mage.cards.p.PhalanxLeader.class)); + cards.add(new SetCardInfo("Phyrexian Altar", 232, Rarity.RARE, mage.cards.p.PhyrexianAltar.class)); + cards.add(new SetCardInfo("Phyrexian Tower", 248, Rarity.RARE, mage.cards.p.PhyrexianTower.class)); cards.add(new SetCardInfo("Platinum Emperion", 233, Rarity.MYTHIC, mage.cards.p.PlatinumEmperion.class)); + cards.add(new SetCardInfo("Plumeveil", 218, Rarity.UNCOMMON, mage.cards.p.Plumeveil.class)); + cards.add(new SetCardInfo("Prey Upon", 178, Rarity.COMMON, mage.cards.p.PreyUpon.class)); + cards.add(new SetCardInfo("Prismatic Lens", 234, Rarity.UNCOMMON, mage.cards.p.PrismaticLens.class)); + cards.add(new SetCardInfo("Pulse of Murasa", 179, Rarity.COMMON, mage.cards.p.PulseOfMurasa.class)); cards.add(new SetCardInfo("Raging Ravine", 249, Rarity.RARE, mage.cards.r.RagingRavine.class)); + cards.add(new SetCardInfo("Raid Bombardment", 142, Rarity.COMMON, mage.cards.r.RaidBombardment.class)); + cards.add(new SetCardInfo("Rakdos Shred-Freak", 219, Rarity.COMMON, mage.cards.r.RakdosShredFreak.class)); + cards.add(new SetCardInfo("Rally the Peasants", 28, Rarity.UNCOMMON, mage.cards.r.RallyThePeasants.class)); cards.add(new SetCardInfo("Reanimate", 110, Rarity.RARE, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Reckless Charge", 143, Rarity.COMMON, mage.cards.r.RecklessCharge.class)); + cards.add(new SetCardInfo("Reckless Wurm", 144, Rarity.COMMON, mage.cards.r.RecklessWurm.class)); + cards.add(new SetCardInfo("Repel the Darkness", 29, Rarity.COMMON, mage.cards.r.RepelTheDarkness.class)); + cards.add(new SetCardInfo("Resurrection", 30, Rarity.COMMON, mage.cards.r.Resurrection.class)); + cards.add(new SetCardInfo("Reveillark", 31, Rarity.RARE, mage.cards.r.Reveillark.class)); + cards.add(new SetCardInfo("Reviving Vapors", 205, Rarity.UNCOMMON, mage.cards.r.RevivingVapors.class)); + cards.add(new SetCardInfo("Reya Dawnbringer", 32, Rarity.RARE, mage.cards.r.ReyaDawnbringer.class)); + cards.add(new SetCardInfo("Rise from the Tides", 67, Rarity.UNCOMMON, mage.cards.r.RiseFromTheTides.class)); + cards.add(new SetCardInfo("Rogue's Passage", 250, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); + cards.add(new SetCardInfo("Rolling Temblor", 145, Rarity.UNCOMMON, mage.cards.r.RollingTemblor.class)); + cards.add(new SetCardInfo("Ronom Unicorn", 33, Rarity.COMMON, mage.cards.r.RonomUnicorn.class)); + cards.add(new SetCardInfo("Rune Snag", 68, Rarity.COMMON, mage.cards.r.RuneSnag.class)); + cards.add(new SetCardInfo("Runed Halo", 34, Rarity.RARE, mage.cards.r.RunedHalo.class)); + cards.add(new SetCardInfo("Safehold Elite", 220, Rarity.COMMON, mage.cards.s.SafeholdElite.class)); + cards.add(new SetCardInfo("Sanitarium Skeleton", 111, Rarity.COMMON, mage.cards.s.SanitariumSkeleton.class)); + cards.add(new SetCardInfo("Satyr Wayfinder", 180, Rarity.COMMON, mage.cards.s.SatyrWayfinder.class)); + cards.add(new SetCardInfo("Scuzzback Marauders", 221, Rarity.COMMON, mage.cards.s.ScuzzbackMarauders.class)); + cards.add(new SetCardInfo("Seismic Assault", 146, Rarity.RARE, mage.cards.s.SeismicAssault.class)); + cards.add(new SetCardInfo("Seize the Day", 147, Rarity.RARE, mage.cards.s.SeizeTheDay.class)); + cards.add(new SetCardInfo("Shed Weakness", 181, Rarity.COMMON, mage.cards.s.ShedWeakness.class)); + cards.add(new SetCardInfo("Shielding Plax", 222, Rarity.COMMON, mage.cards.s.ShieldingPlax.class)); + cards.add(new SetCardInfo("Shirei, Shizo's Caretaker", 112, Rarity.UNCOMMON, mage.cards.s.ShireiShizosCaretaker.class)); + cards.add(new SetCardInfo("Shriekmaw", 113, Rarity.UNCOMMON, mage.cards.s.Shriekmaw.class)); cards.add(new SetCardInfo("Sigarda, Host of Herons", 206, Rarity.MYTHIC, mage.cards.s.SigardaHostOfHerons.class)); + cards.add(new SetCardInfo("Sigil of the New Dawn", 35, Rarity.UNCOMMON, mage.cards.s.SigilOfTheNewDawn.class)); + cards.add(new SetCardInfo("Skyspear Cavalry", 36, Rarity.COMMON, mage.cards.s.SkyspearCavalry.class)); + cards.add(new SetCardInfo("Skywing Aven", 69, Rarity.COMMON, mage.cards.s.SkywingAven.class)); + cards.add(new SetCardInfo("Sleight of Hand", 70, Rarity.UNCOMMON, mage.cards.s.SleightOfHand.class)); + cards.add(new SetCardInfo("Slippery Bogle", 223, Rarity.UNCOMMON, mage.cards.s.SlipperyBogle.class)); + cards.add(new SetCardInfo("Slum Reaper", 114, Rarity.COMMON, mage.cards.s.SlumReaper.class)); + cards.add(new SetCardInfo("Snake Umbra", 182, Rarity.UNCOMMON, mage.cards.s.SnakeUmbra.class)); cards.add(new SetCardInfo("Snapcaster Mage", 71, Rarity.MYTHIC, mage.cards.s.SnapcasterMage.class)); + cards.add(new SetCardInfo("Songs of the Damned", 115, Rarity.UNCOMMON, mage.cards.s.SongsOfTheDamned.class)); + cards.add(new SetCardInfo("Soul's Fire", 148, Rarity.COMMON, mage.cards.s.SoulsFire.class)); + cards.add(new SetCardInfo("Sovereigns of Lost Alara", 207, Rarity.RARE, mage.cards.s.SovereignsOfLostAlara.class)); + cards.add(new SetCardInfo("Sparkspitter", 149, Rarity.COMMON, mage.cards.s.Sparkspitter.class)); + cards.add(new SetCardInfo("Spider Spawning", 183, Rarity.UNCOMMON, mage.cards.s.SpiderSpawning.class)); + cards.add(new SetCardInfo("Spider Umbra", 184, Rarity.COMMON, mage.cards.s.SpiderUmbra.class)); + cards.add(new SetCardInfo("Spirit Cairn", 37, Rarity.UNCOMMON, mage.cards.s.SpiritCairn.class)); + cards.add(new SetCardInfo("Spoils of the Vault", 116, Rarity.RARE, mage.cards.s.SpoilsOfTheVault.class)); + cards.add(new SetCardInfo("Squee, Goblin Nabob", 150, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class)); + cards.add(new SetCardInfo("Staunch-Hearted Warrior", 185, Rarity.COMMON, mage.cards.s.StaunchHeartedWarrior.class)); + cards.add(new SetCardInfo("Stingerfling Spider", 186, Rarity.UNCOMMON, mage.cards.s.StingerflingSpider.class)); cards.add(new SetCardInfo("Stirring Wildwood", 251, Rarity.RARE, mage.cards.s.StirringWildwood.class)); + cards.add(new SetCardInfo("Stitched Drake", 72, Rarity.COMMON, mage.cards.s.StitchedDrake.class)); + cards.add(new SetCardInfo("Stitcher's Apprentice", 73, Rarity.COMMON, mage.cards.s.StitchersApprentice.class)); + cards.add(new SetCardInfo("Stream of Consciousness", 74, Rarity.UNCOMMON, mage.cards.s.StreamOfConsciousness.class)); + cards.add(new SetCardInfo("Sublime Archangel", 38, Rarity.RARE, mage.cards.s.SublimeArchangel.class)); + cards.add(new SetCardInfo("Sultai Skullkeeper", 75, Rarity.COMMON, mage.cards.s.SultaiSkullkeeper.class)); + cards.add(new SetCardInfo("Swift Reckoning", 39, Rarity.UNCOMMON, mage.cards.s.SwiftReckoning.class)); + cards.add(new SetCardInfo("Talrand, Sky Summoner", 76, Rarity.RARE, mage.cards.t.TalrandSkySummoner.class)); cards.add(new SetCardInfo("Tarmogoyf", 187, Rarity.MYTHIC, mage.cards.t.Tarmogoyf.class)); cards.add(new SetCardInfo("Tasigur, the Golden Fang", 117, Rarity.RARE, mage.cards.t.TasigurTheGoldenFang.class)); cards.add(new SetCardInfo("Temporal Manipulation", 77, Rarity.MYTHIC, mage.cards.t.TemporalManipulation.class)); + cards.add(new SetCardInfo("Terramorphic Expanse", 252, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); + cards.add(new SetCardInfo("Tethmos High Priest", 40, Rarity.COMMON, mage.cards.t.TethmosHighPriest.class)); + cards.add(new SetCardInfo("Thermo-Alchemist", 151, Rarity.COMMON, mage.cards.t.ThermoAlchemist.class)); + cards.add(new SetCardInfo("Thespian's Stage", 253, Rarity.RARE, mage.cards.t.ThespiansStage.class)); + cards.add(new SetCardInfo("Think Twice", 78, Rarity.COMMON, mage.cards.t.ThinkTwice.class)); cards.add(new SetCardInfo("Through the Breach", 152, Rarity.RARE, mage.cards.t.ThroughTheBreach.class)); + cards.add(new SetCardInfo("Travel Preparations", 188, Rarity.UNCOMMON, mage.cards.t.TravelPreparations.class)); + cards.add(new SetCardInfo("Treasure Cruise", 79, Rarity.COMMON, mage.cards.t.TreasureCruise.class)); + cards.add(new SetCardInfo("Turn to Mist", 224, Rarity.COMMON, mage.cards.t.TurnToMist.class)); + cards.add(new SetCardInfo("Twins of Maurer Estate", 118, Rarity.COMMON, mage.cards.t.TwinsOfMaurerEstate.class)); + cards.add(new SetCardInfo("Ulamog's Crusher", 8, Rarity.COMMON, mage.cards.u.UlamogsCrusher.class)); cards.add(new SetCardInfo("Ulamog, the Infinite Gyre", 7, Rarity.MYTHIC, mage.cards.u.UlamogTheInfiniteGyre.class)); + cards.add(new SetCardInfo("Unburial Rites", 119, Rarity.UNCOMMON, mage.cards.u.UnburialRites.class)); + cards.add(new SetCardInfo("Undying Rage", 153, Rarity.COMMON, mage.cards.u.UndyingRage.class)); + cards.add(new SetCardInfo("Unholy Hunger", 120, Rarity.COMMON, mage.cards.u.UnholyHunger.class)); + cards.add(new SetCardInfo("Unstable Mutation", 80, Rarity.UNCOMMON, mage.cards.u.UnstableMutation.class)); + cards.add(new SetCardInfo("Urban Evolution", 208, Rarity.UNCOMMON, mage.cards.u.UrbanEvolution.class)); cards.add(new SetCardInfo("Urborg, Tomb of Yawgmoth", 254, Rarity.RARE, mage.cards.u.UrborgTombOfYawgmoth.class)); + cards.add(new SetCardInfo("Vengeful Rebirth", 209, Rarity.UNCOMMON, mage.cards.v.VengefulRebirth.class)); cards.add(new SetCardInfo("Vengevine", 189, Rarity.MYTHIC, mage.cards.v.Vengevine.class)); + cards.add(new SetCardInfo("Verdant Eidolon", 190, Rarity.COMMON, mage.cards.v.VerdantEidolon.class)); + cards.add(new SetCardInfo("Vessel of Endless Rest", 235, Rarity.COMMON, mage.cards.v.VesselOfEndlessRest.class)); + cards.add(new SetCardInfo("Vexing Devil", 154, Rarity.RARE, mage.cards.v.VexingDevil.class)); + cards.add(new SetCardInfo("Visions of Beyond", 81, Rarity.RARE, mage.cards.v.VisionsOfBeyond.class)); + cards.add(new SetCardInfo("Walker of the Grove", 191, Rarity.COMMON, mage.cards.w.WalkerOfTheGrove.class)); + cards.add(new SetCardInfo("Wall of Reverence", 41, Rarity.RARE, mage.cards.w.WallOfReverence.class)); + cards.add(new SetCardInfo("Wandering Champion", 42, Rarity.COMMON, mage.cards.w.WanderingChampion.class)); + cards.add(new SetCardInfo("Warleader's Helix", 210, Rarity.UNCOMMON, mage.cards.w.WarleadersHelix.class)); + cards.add(new SetCardInfo("Whirlwind Adept", 82, Rarity.COMMON, mage.cards.w.WhirlwindAdept.class)); + cards.add(new SetCardInfo("Wickerbough Elder", 192, Rarity.COMMON, mage.cards.w.WickerboughElder.class)); + cards.add(new SetCardInfo("Wild Hunger", 193, Rarity.UNCOMMON, mage.cards.w.WildHunger.class)); + cards.add(new SetCardInfo("Wild Mongrel", 194, Rarity.COMMON, mage.cards.w.WildMongrel.class)); + cards.add(new SetCardInfo("Wingsteed Rider", 43, Rarity.COMMON, mage.cards.w.WingsteedRider.class)); + cards.add(new SetCardInfo("Woodfall Primus", 195, Rarity.RARE, mage.cards.w.WoodfallPrimus.class)); + cards.add(new SetCardInfo("Young Pyromancer", 155, Rarity.UNCOMMON, mage.cards.y.YoungPyromancer.class)); } } From 57d5c391fa23d748b8d4df4f92e46359c389b6c1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 22 Nov 2018 16:22:07 +0100 Subject: [PATCH 15/50] * Adroit Hateflayer - Fixed triggered ability only doing damage to opponents instead of all players (#5416). --- Mage.Sets/src/mage/cards/a/AdroitHateflayer.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java index e51f259f632..dcf0a7f023a 100644 --- a/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java +++ b/Mage.Sets/src/mage/cards/a/AdroitHateflayer.java @@ -1,10 +1,9 @@ - package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.LoseLifeAllPlayersEffect; import mage.abilities.keyword.MenaceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -18,7 +17,7 @@ import mage.constants.SubType; public final class AdroitHateflayer extends CardImpl { public AdroitHateflayer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}"); this.subtype.add(SubType.NAUTOLAN); this.subtype.add(SubType.SITH); this.power = new MageInt(3); @@ -26,9 +25,9 @@ public final class AdroitHateflayer extends CardImpl { // Menace this.addAbility(new MenaceAbility()); - - // Whenever Adroit Hateflayer attacks, each opponent loses 2 life. - this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(2), false)); + + // Whenever Adroit Hateflayer attacks, each player loses 2 life. + this.addAbility(new AttacksTriggeredAbility(new LoseLifeAllPlayersEffect(2), false)); } public AdroitHateflayer(final AdroitHateflayer card) { From dbbe92ff0a363eb41a1369353abe57cff1a65300 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 23 Nov 2018 10:59:04 +0100 Subject: [PATCH 16/50] * Outer Rim Slaver - Fixed rule text. Improved target description text (#5416). --- Mage.Sets/src/mage/cards/o/OuterRimSlaver.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java b/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java index 98ea2f4b723..438ca1a7292 100644 --- a/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java +++ b/Mage.Sets/src/mage/cards/o/OuterRimSlaver.java @@ -1,4 +1,3 @@ - package mage.cards.o; import java.util.UUID; @@ -30,12 +29,13 @@ public final class OuterRimSlaver extends CardImpl { this.toughness = new MageInt(3); // When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature - Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true); - ability.addEffect(new FightTargetsEffect("another target creature fights that creature")); - TargetCreaturePermanent target = new TargetCreaturePermanent(); + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()) + .setText("you may put a bounty counter on target creature"), true); + ability.addEffect(new FightTargetsEffect("If you do, another target creature fights that creature")); + TargetCreaturePermanent target = new TargetCreaturePermanent(new FilterCreaturePermanent("creature to put a bounty counter on it")); target.setTargetTag(1); ability.addTarget(target); - FilterCreaturePermanent filter = new FilterCreaturePermanent(); + FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature to fight that creature that gets the bounty counter"); filter.add(new AnotherTargetPredicate(2)); TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter); target2.setTargetTag(2); From 43ee5e9c43dc6ae9c48d301abdf8792b7b9c79f3 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 23 Nov 2018 12:30:44 +0100 Subject: [PATCH 17/50] * Acklay of the Arena - Fixed triggered ability (fixes #5416). --- Mage.Sets/src/mage/cards/g/GhostQuarter.java | 4 +- .../effects/common/FightTargetsEffect.java | 57 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GhostQuarter.java b/Mage.Sets/src/mage/cards/g/GhostQuarter.java index b84b4a3ba4d..66a20c6860e 100644 --- a/Mage.Sets/src/mage/cards/g/GhostQuarter.java +++ b/Mage.Sets/src/mage/cards/g/GhostQuarter.java @@ -1,4 +1,3 @@ - package mage.cards.g; import java.util.UUID; @@ -16,7 +15,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.filter.common.FilterBasicLandCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -30,7 +28,7 @@ import mage.target.common.TargetLandPermanent; public final class GhostQuarter extends CardImpl { public GhostQuarter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); diff --git a/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java index c0fd2f1ca51..db8b80f874c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/FightTargetsEffect.java @@ -1,6 +1,6 @@ - package mage.abilities.effects.common; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; @@ -32,35 +32,58 @@ public class FightTargetsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); if (card != null) { - // only if both targets are legal the effect will be applied - if (source.getTargets().get(0).isLegal(source, game) && source.getTargets().get(1).isLegal(source, game)) { - Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget()); - Permanent creature2 = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - // 20110930 - 701.10 - if (creature1 != null && creature2 != null) { - if (creature1.isCreature() && creature2.isCreature()) { - return creature1.fight(creature2, source, game); - } + UUID target1Id = null; + UUID target2Id = null; + // first target is in target pointer, second target is a normal target + if (source.getTargets().size() < 2) { + if (!source.getTargets().get(0).isLegal(source, game)) { + return false; + } + target1Id = getTargetPointer().getFirst(game, source); + target2Id = source.getTargets().getFirstTarget(); + if (target1Id == target2Id) { + return false; + } + // two normal targets available, only if both targets are legal the effect will be applied + } else if (source.getTargets().get(0).isLegal(source, game) && source.getTargets().get(1).isLegal(source, game)) { + target1Id = source.getTargets().get(0).getFirstTarget(); + target2Id = source.getTargets().get(1).getFirstTarget(); + } + Permanent creature1 = game.getPermanent(target1Id); + Permanent creature2 = game.getPermanent(target2Id); + // 20110930 - 701.10 + if (creature1 != null && creature2 != null) { + if (creature1.isCreature() && creature2.isCreature()) { + return creature1.fight(creature2, source, game); } } - if (!game.isSimulation()) { - game.informPlayers(card.getName() + " has been fizzled."); - } + } + if (!game.isSimulation()) { + game.informPlayers(card.getName() + " has been fizzled."); } return false; } @Override - public FightTargetsEffect copy() { + public FightTargetsEffect + copy() { return new FightTargetsEffect(this); + } @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { + public String + getText(Mode mode + ) { + if (staticText + != null && !staticText + .isEmpty()) { return staticText; + } - return "Target " + mode.getTargets().get(0).getTargetName() + " fights another target " + mode.getTargets().get(1).getTargetName(); + return "Target " + mode + .getTargets().get(0).getTargetName() + " fights another target " + mode + .getTargets().get(1).getTargetName(); } } From 2e17cb334e445b6f2dd2df33338a925036af6c3c Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Fri, 23 Nov 2018 11:36:29 -0600 Subject: [PATCH 18/50] - Fixed #5100. Added a replacement effect for skipping the combat phase. --- Mage.Sets/src/mage/cards/b/BlindingAngel.java | 22 ++++---- Mage.Sets/src/mage/cards/e/EmptyCityRuse.java | 10 ++-- Mage.Sets/src/mage/cards/f/FalsePeace.java | 14 ++--- .../src/mage/cards/m/MomentOfSilence.java | 14 ++--- .../src/mage/cards/r/RevenantPatriarch.java | 14 ++--- .../src/mage/cards/s/StonehornDignitary.java | 18 +++--- .../effects/common/SkipCombatStepEffect.java | 55 +++++++++++++++++++ 7 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java diff --git a/Mage.Sets/src/mage/cards/b/BlindingAngel.java b/Mage.Sets/src/mage/cards/b/BlindingAngel.java index c75b26c07e6..f7f25c29ab0 100644 --- a/Mage.Sets/src/mage/cards/b/BlindingAngel.java +++ b/Mage.Sets/src/mage/cards/b/BlindingAngel.java @@ -1,14 +1,14 @@ - package mage.cards.b; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; /** @@ -16,26 +16,28 @@ import mage.constants.SubType; * @author Plopman */ public final class BlindingAngel extends CardImpl { - + public BlindingAngel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); this.subtype.add(SubType.ANGEL); - + this.power = new MageInt(2); this.toughness = new MageInt(4); // Flying this.addAbility(FlyingAbility.getInstance()); - // Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipNextCombatEffect(), false, true)); - } + // Whenever Blinding Angel deals combat damage to a player, that player skips their next combat phase. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("that player skips their next combat phase."), false, true)); + + } + public BlindingAngel(final BlindingAngel card) { super(card); } - + @Override public BlindingAngel copy() { return new BlindingAngel(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java b/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java index 020899fc0ea..8e1ff3e4178 100644 --- a/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java +++ b/Mage.Sets/src/mage/cards/e/EmptyCityRuse.java @@ -1,11 +1,11 @@ - package mage.cards.e; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.common.TargetOpponent; /** @@ -15,10 +15,10 @@ import mage.target.common.TargetOpponent; public final class EmptyCityRuse extends CardImpl { public EmptyCityRuse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Target opponent skips all combat phases of their next turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target opponent skips all combat phases of their next turn.")); this.getSpellAbility().addTarget(new TargetOpponent()); } @@ -30,4 +30,4 @@ public final class EmptyCityRuse extends CardImpl { public EmptyCityRuse copy() { return new EmptyCityRuse(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FalsePeace.java b/Mage.Sets/src/mage/cards/f/FalsePeace.java index 026dae7c19a..55bfe14023c 100644 --- a/Mage.Sets/src/mage/cards/f/FalsePeace.java +++ b/Mage.Sets/src/mage/cards/f/FalsePeace.java @@ -1,11 +1,11 @@ - package mage.cards.f; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.TargetPlayer; /** @@ -13,19 +13,19 @@ import mage.target.TargetPlayer; * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ public final class FalsePeace extends CardImpl { - + public FalsePeace(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}"); // Target player skips all combat phases of their next turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.UntilYourNextTurn).setText("Target player skips all combat phases of their next turn.")); this.getSpellAbility().addTarget(new TargetPlayer()); } - + public FalsePeace(final FalsePeace card) { super(card); } - + @Override public FalsePeace copy() { return new FalsePeace(this); diff --git a/Mage.Sets/src/mage/cards/m/MomentOfSilence.java b/Mage.Sets/src/mage/cards/m/MomentOfSilence.java index 50e275a7ed0..6607ae3528b 100644 --- a/Mage.Sets/src/mage/cards/m/MomentOfSilence.java +++ b/Mage.Sets/src/mage/cards/m/MomentOfSilence.java @@ -1,11 +1,11 @@ - package mage.cards.m; import java.util.UUID; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.TargetPlayer; /** @@ -13,19 +13,19 @@ import mage.target.TargetPlayer; * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ public final class MomentOfSilence extends CardImpl { - + public MomentOfSilence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Target player skips their next combat phase this turn. - this.getSpellAbility().addEffect(new SkipNextCombatEffect()); + this.getSpellAbility().addEffect(new SkipCombatStepEffect(Duration.EndOfTurn).setText("Target player skips their next combat this turn")); this.getSpellAbility().addTarget(new TargetPlayer()); } - + public MomentOfSilence(final MomentOfSilence card) { super(card); } - + @Override public MomentOfSilence copy() { return new MomentOfSilence(this); diff --git a/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java b/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java index 50b1fd07e85..e770b5d4397 100644 --- a/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java +++ b/Mage.Sets/src/mage/cards/r/RevenantPatriarch.java @@ -1,4 +1,3 @@ - package mage.cards.r; import java.util.UUID; @@ -8,12 +7,13 @@ import mage.abilities.common.CantBlockAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.ColoredManaSymbol; +import mage.constants.Duration; import mage.target.TargetPlayer; import mage.watchers.common.ManaSpentToCastWatcher; @@ -22,26 +22,26 @@ import mage.watchers.common.ManaSpentToCastWatcher; * @author ilcartographer */ public final class RevenantPatriarch extends CardImpl { - + public RevenantPatriarch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); this.subtype.add(SubType.SPIRIT); this.power = new MageInt(4); this.toughness = new MageInt(3); // When Revenant Patriarch enters the battlefield, if {W} was spent to cast it, target player skips their next combat phase. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect(), false); + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target player skips their next combat phase."), false); ability.addTarget(new TargetPlayer()); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new ManaWasSpentCondition(ColoredManaSymbol.W), "if {W} was spent to cast it, target player skips their next combat phase."), new ManaSpentToCastWatcher()); // Revenant Patriarch can't block. this.addAbility(new CantBlockAbility()); } - + public RevenantPatriarch(final RevenantPatriarch card) { super(card); } - + @Override public RevenantPatriarch copy() { return new RevenantPatriarch(this); diff --git a/Mage.Sets/src/mage/cards/s/StonehornDignitary.java b/Mage.Sets/src/mage/cards/s/StonehornDignitary.java index 3f92110a139..0443f4f16db 100644 --- a/Mage.Sets/src/mage/cards/s/StonehornDignitary.java +++ b/Mage.Sets/src/mage/cards/s/StonehornDignitary.java @@ -1,14 +1,14 @@ - package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.SkipNextCombatEffect; +import mage.abilities.effects.common.SkipCombatStepEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.target.common.TargetOpponent; @@ -17,27 +17,27 @@ import mage.target.common.TargetOpponent; * @author nantuko */ public final class StonehornDignitary extends CardImpl { - + public StonehornDignitary(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.RHINO); this.subtype.add(SubType.SOLDIER); - + this.power = new MageInt(1); this.toughness = new MageInt(4); // When Stonehorn Dignitary enters the battlefield, target opponent skips their next combat phase. - Ability ability = new EntersBattlefieldTriggeredAbility(new SkipNextCombatEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("target opponent skips their next combat phase.")); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } - + public StonehornDignitary(final StonehornDignitary card) { super(card); } - + @Override public StonehornDignitary copy() { return new StonehornDignitary(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java new file mode 100644 index 00000000000..4d72fe19fd0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipCombatStepEffect.java @@ -0,0 +1,55 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ + +public class SkipCombatStepEffect extends ReplacementEffectImpl { + + public SkipCombatStepEffect(Duration duration) { + super(duration, Outcome.Detriment); + staticText = "that player skips their next combat phase"; + } + + public SkipCombatStepEffect(final SkipCombatStepEffect effect) { + super(effect); + } + + @Override + public SkipCombatStepEffect copy() { + return new SkipCombatStepEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COMBAT_PHASE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(targetPointer.getFirst(game, source)); + } +} From d9b25cbac1e5c55733618c0058ee29750f11b493 Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Fri, 23 Nov 2018 19:21:03 +0100 Subject: [PATCH 19/50] suppert mtgjson v4 --- .../src/main/java/mage/verify/Booster.java | 8 ++++ .../main/java/mage/verify/ForeignData.java | 12 ++++++ .../src/main/java/mage/verify/JsonCard.java | 19 +++++++++ .../src/main/java/mage/verify/JsonSet.java | 12 ++++++ .../src/main/java/mage/verify/Legality.java | 19 +++++++++ .../src/main/java/mage/verify/Meta.java | 6 +++ .../src/main/java/mage/verify/MtgJson.java | 16 ++++++-- .../src/main/java/mage/verify/Ruling.java | 6 +++ .../src/main/java/mage/verify/Token.java | 19 +++++++++ .../java/mage/verify/VerifyCardDataTest.java | 40 ++++++++++--------- 10 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 Mage.Verify/src/main/java/mage/verify/Booster.java create mode 100644 Mage.Verify/src/main/java/mage/verify/ForeignData.java create mode 100644 Mage.Verify/src/main/java/mage/verify/Legality.java create mode 100644 Mage.Verify/src/main/java/mage/verify/Meta.java create mode 100644 Mage.Verify/src/main/java/mage/verify/Ruling.java create mode 100644 Mage.Verify/src/main/java/mage/verify/Token.java diff --git a/Mage.Verify/src/main/java/mage/verify/Booster.java b/Mage.Verify/src/main/java/mage/verify/Booster.java new file mode 100644 index 00000000000..161dcfff1d2 --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/Booster.java @@ -0,0 +1,8 @@ +package mage.verify; + +public class Booster { + + public Booster(String mythic){ + + } +} diff --git a/Mage.Verify/src/main/java/mage/verify/ForeignData.java b/Mage.Verify/src/main/java/mage/verify/ForeignData.java new file mode 100644 index 00000000000..e410fb24d73 --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/ForeignData.java @@ -0,0 +1,12 @@ +package mage.verify; + +public class ForeignData { + + + public String language; + public String name; + public String type; + public String text; + public String flavorText; + public String multiverseId; +} diff --git a/Mage.Verify/src/main/java/mage/verify/JsonCard.java b/Mage.Verify/src/main/java/mage/verify/JsonCard.java index a17d1a7b6bb..c7a0c49a4b5 100644 --- a/Mage.Verify/src/main/java/mage/verify/JsonCard.java +++ b/Mage.Verify/src/main/java/mage/verify/JsonCard.java @@ -3,10 +3,23 @@ package mage.verify; import java.util.List; class JsonCard { + public String uuid; + public String convertedManaCost; + public List foreignData; + public boolean isReserved; + public String side; + public Legality legalities; + public List printings; + public List rulings; + public List colorIndicator; public String layout; public String name; public List names; // flip cards public String manaCost; + public boolean hasFoil; + public boolean hasNonFoil; + public String multiverseId; + public String frameVersion; public int cmc; public List colors; public List colorIdentity; @@ -22,6 +35,10 @@ class JsonCard { public boolean starter; // only available in boxed sets and not in boosters public int hand; // vanguard public int life; // vanguard + public String originalText; + public String originalType; + public String flavorText; + public boolean isOnlineOnly; // only available in AllSets.json public String artist; @@ -37,4 +54,6 @@ class JsonCard { public String border; public String watermark; public boolean timeshifted; + public String borderColor; + public boolean isOversized; } diff --git a/Mage.Verify/src/main/java/mage/verify/JsonSet.java b/Mage.Verify/src/main/java/mage/verify/JsonSet.java index 831721937fd..466ebbfb630 100644 --- a/Mage.Verify/src/main/java/mage/verify/JsonSet.java +++ b/Mage.Verify/src/main/java/mage/verify/JsonSet.java @@ -1,5 +1,7 @@ package mage.verify; +import com.fasterxml.jackson.annotation.JsonIgnore; + import java.util.List; import java.util.Map; @@ -21,4 +23,14 @@ class JsonSet { public String mkm_id; public String mkm_name; public Map translations; + public int baseSetSize; + @JsonIgnore + public List boosterV3; + public String borderColor; + public Meta meta; + public String mtgoCode; + public List tokens; + public int totalSetSize; + public boolean isOnlineOnly; + public boolean isFoilOnly; } diff --git a/Mage.Verify/src/main/java/mage/verify/Legality.java b/Mage.Verify/src/main/java/mage/verify/Legality.java new file mode 100644 index 00000000000..925bc2189e7 --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/Legality.java @@ -0,0 +1,19 @@ +package mage.verify; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Legality { + @JsonProperty("1v1") + public String oneVersusOne; + public String commander; + public String duel; + public String legacy; + public String penny; + public String vintage; +public String frontier; +public String modern; +public String pauper; +public String brawl; +public String future; +public String standard; +} diff --git a/Mage.Verify/src/main/java/mage/verify/Meta.java b/Mage.Verify/src/main/java/mage/verify/Meta.java new file mode 100644 index 00000000000..4a93171da0d --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/Meta.java @@ -0,0 +1,6 @@ +package mage.verify; + +public class Meta { + public String date; + public String version; +} diff --git a/Mage.Verify/src/main/java/mage/verify/MtgJson.java b/Mage.Verify/src/main/java/mage/verify/MtgJson.java index 1919f8db0f8..4301ac0b6cb 100644 --- a/Mage.Verify/src/main/java/mage/verify/MtgJson.java +++ b/Mage.Verify/src/main/java/mage/verify/MtgJson.java @@ -12,8 +12,7 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.text.Normalizer; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.zip.ZipInputStream; public final class MtgJson { @@ -61,6 +60,16 @@ public final class MtgJson { static { try { cards = loadAllCards(); + List oldKeys = new ArrayList<>(); + Map newKeys = new HashMap<>(); + for (String key : cards.keySet()) { + if (key.contains("(")) { + newKeys.put(key.replaceAll("\\(.*\\)", "").trim(), cards.get(key)); + oldKeys.add(key); + } + } + cards.putAll(newKeys); + cards.keySet().removeAll(oldKeys); addAliases(cards); } catch (IOException e) { throw new RuntimeException(e); @@ -95,7 +104,7 @@ public final class MtgJson { if (stream == null) { File file = new File(filename); if (!file.exists()) { - InputStream download = new URL("http://mtgjson.com/json/" + filename).openStream(); + InputStream download = new URL("http://mtgjson.com/v4/json/" + filename).openStream(); Files.copy(download, file.toPath(), StandardCopyOption.REPLACE_EXISTING); System.out.println("Downloaded " + filename + " to " + file.getAbsolutePath()); } else { @@ -133,6 +142,7 @@ public final class MtgJson { name = name.replace("'", "\""); // for Kongming, "Sleeping Dragon" & Pang Tong, "Young Phoenix" ref = reference.get(name); } + return ref; } diff --git a/Mage.Verify/src/main/java/mage/verify/Ruling.java b/Mage.Verify/src/main/java/mage/verify/Ruling.java new file mode 100644 index 00000000000..5bcb036329c --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/Ruling.java @@ -0,0 +1,6 @@ +package mage.verify; + +public class Ruling { + public String text; + public String date; +} diff --git a/Mage.Verify/src/main/java/mage/verify/Token.java b/Mage.Verify/src/main/java/mage/verify/Token.java new file mode 100644 index 00000000000..c99ed0abc25 --- /dev/null +++ b/Mage.Verify/src/main/java/mage/verify/Token.java @@ -0,0 +1,19 @@ +package mage.verify; + +import java.util.List; + +public class Token { + public String artist; + public String borderColor; + public List colorIdentity; + public List colors; + public String name; + public String number; + public String power; + public String toughness; + public List reverseRelated; + public String text; + public String type; + public String uuid; + public String watermark; +} diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 991315438a3..fb16264f15f 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1,14 +1,13 @@ package mage.verify; import mage.ObjectColor; -import mage.abilities.Ability; +import mage.abilities.keyword.DevoidAbility; import mage.abilities.keyword.MultikickerAbility; import mage.cards.*; import mage.cards.basiclands.BasicLand; -import mage.cards.repository.CardRepository; -import mage.cards.repository.CardScanner; import mage.constants.CardType; import mage.constants.Rarity; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.permanent.token.Token; import mage.game.permanent.token.TokenImpl; @@ -232,7 +231,7 @@ public class VerifyCardDataTest { // replace codes for aliases String searchSet = MtgJson.mtgJsonToXMageCodes.getOrDefault(refSet.code, refSet.code); - ExpansionSet mageSet = Sets.findSet(searchSet); + ExpansionSet mageSet = Sets.findSet(searchSet.toUpperCase()); if (mageSet == null) { totalMissingSets = totalMissingSets + 1; totalMissingCards = totalMissingCards + refSet.cards.size(); @@ -383,7 +382,7 @@ public class VerifyCardDataTest { // check for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { boolean cardHaveDoubleName = (doubleNames.getOrDefault(card.getName(), 0) > 1); - boolean cardHaveVariousSetting = card.getGraphicInfo() == null ? false : card.getGraphicInfo().getUsesVariousArt(); + boolean cardHaveVariousSetting = card.getGraphicInfo() != null && card.getGraphicInfo().getUsesVariousArt(); if (cardHaveDoubleName && !cardHaveVariousSetting) { errorsList.add("error, founded double card names, but UsesVariousArt is not true: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber()); @@ -569,17 +568,22 @@ public class VerifyCardDataTest { return; } - Collection expected = ref.colors; - ObjectColor color = card.getColor(null); - if (expected == null) { - expected = Collections.emptyList(); + Set expected = new HashSet<>(); + if (ref.colors != null) { + expected.addAll(ref.colors); } + if(card.isFlipCard()){ + expected.addAll(ref.colorIdentity); + } + + ObjectColor color = card.getColor(null); + if (expected.size() != color.getColorCount() - || (color.isBlack() && !expected.contains("Black")) - || (color.isBlue() && !expected.contains("Blue")) - || (color.isGreen() && !expected.contains("Green")) - || (color.isRed() && !expected.contains("Red")) - || (color.isWhite() && !expected.contains("White"))) { + || (color.isBlack() && !expected.contains("B")) + || (color.isBlue() && !expected.contains("U")) + || (color.isGreen() && !expected.contains("G")) + || (color.isRed() && !expected.contains("R")) + || (color.isWhite() && !expected.contains("W"))) { fail(card, "colors", color + " != " + expected); } } @@ -601,7 +605,7 @@ public class VerifyCardDataTest { } } - if (!eqSet(card.getSubtype(null).stream().map(p -> p.toString()).collect(Collectors.toSet()), expected)) { + if (!eqSet(card.getSubtype(null).stream().map(SubType::toString).collect(Collectors.toSet()), expected)) { fail(card, "subtypes", card.getSubtype(null) + " != " + expected); } } @@ -628,11 +632,11 @@ public class VerifyCardDataTest { } // special check: kicker ability must be in rules - if (card.getAbilities().containsClass(MultikickerAbility.class) && !card.getRules().stream().anyMatch(rule -> rule.contains("Multikicker"))) { + if (card.getAbilities().containsClass(MultikickerAbility.class) && card.getRules().stream().noneMatch(rule -> rule.contains("Multikicker"))) { fail(card, "abilities", "card have Multikicker ability, but missing it in rules text"); } - // spells have only 1 abilities + // spells have only 1 ability if (card.isSorcery() || card.isInstant()) { return; } @@ -697,7 +701,7 @@ public class VerifyCardDataTest { String expected = ref.manaCost; String cost = join(card.getManaCost().getSymbols()); - if (cost != null && cost.isEmpty()) { + if (cost.isEmpty()) { cost = null; } if (cost != null) { From ed69c0449014e37f4ab2496ed665b0ca8b0e5f0d Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Fri, 23 Nov 2018 20:05:30 +0100 Subject: [PATCH 20/50] fix for #5417 --- Mage.Sets/src/mage/cards/i/Icequake.java | 14 ++++++----- .../test/cards/conditional/IcequakeTest.java | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java diff --git a/Mage.Sets/src/mage/cards/i/Icequake.java b/Mage.Sets/src/mage/cards/i/Icequake.java index cad1b47cd1d..70399b40e7d 100644 --- a/Mage.Sets/src/mage/cards/i/Icequake.java +++ b/Mage.Sets/src/mage/cards/i/Icequake.java @@ -59,14 +59,16 @@ class IcequakeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null && controller != null) { - permanent.destroy(source.getSourceId(), game, false); - if (permanent.isSnow()) { - controller.damage(1, source.getSourceId(), game, false, true); + if (permanent != null) { + Player controller = game.getPlayer(permanent.getControllerId()); + if(controller != null) { + permanent.destroy(source.getSourceId(), game, false); + if (permanent.isSnow()) { + controller.damage(1, source.getSourceId(), game, false, true); + } + return true; } - return true; } return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java new file mode 100644 index 00000000000..f3db7d63796 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/conditional/IcequakeTest.java @@ -0,0 +1,25 @@ +package org.mage.test.cards.conditional; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class IcequakeTest extends CardTestPlayerBase { + + @Test + public void testIcequakeOnSnowLand(){ + + addCard(Zone.BATTLEFIELD, playerB, "Snow-Covered Plains"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp",10); + addCard(Zone.HAND, playerA, "Icequake"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN,playerA, "Icequake", "Snow-Covered Plains"); + + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 19); + } +} From 25e7b53268ec320c09660e8bfd8afcdcd5ce6ebf Mon Sep 17 00:00:00 2001 From: Ingmar Goudt Date: Sat, 24 Nov 2018 23:50:05 +0100 Subject: [PATCH 21/50] small performance update for ClassScanner --- Mage/src/main/java/mage/util/ClassScanner.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mage/src/main/java/mage/util/ClassScanner.java b/Mage/src/main/java/mage/util/ClassScanner.java index 46609ea4baf..47972fe400b 100644 --- a/Mage/src/main/java/mage/util/ClassScanner.java +++ b/Mage/src/main/java/mage/util/ClassScanner.java @@ -33,8 +33,8 @@ public final class ClassScanner { if(classLoader == null) classLoader = Thread.currentThread().getContextClassLoader(); assert classLoader != null; - HashMap dirs = new HashMap<>(); - TreeSet jars = new TreeSet<>(); + Map dirs = new HashMap<>(); + Set jars = new TreeSet<>(); for (String packageName : packages) { String path = packageName.replace('.', '/'); Enumeration resources = classLoader.getResources(path); @@ -51,8 +51,8 @@ public final class ClassScanner { } } - for (String filePath : dirs.keySet()) { - cards.addAll(findClasses(classLoader, new File(filePath), dirs.get(filePath), type)); + for (Map.Entry dir : dirs.entrySet()) { + cards.addAll(findClasses(classLoader, new File(dir.getKey()), dir.getValue(), type)); } for (String filePath : jars) { @@ -66,7 +66,7 @@ public final class ClassScanner { private static List findClasses(ClassLoader classLoader, File directory, String packageName, Class type) { List cards = new ArrayList<>(); - if (!directory.exists()) return cards; + if (directory == null || !directory.exists()) return cards; for (File file : directory.listFiles()) { if (file.getName().endsWith(".class")) { From 2144ae75a4cabb230353d68ea597cd9b68210c44 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:08:30 -0600 Subject: [PATCH 22/50] - Added Archery Training and Fend Off. --- .../src/mage/cards/a/ArcheryTraining.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/cards/f/FendOff.java | 41 ++++++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 2 + 3 files changed, 110 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/ArcheryTraining.java create mode 100644 Mage.Sets/src/mage/cards/f/FendOff.java diff --git a/Mage.Sets/src/mage/cards/a/ArcheryTraining.java b/Mage.Sets/src/mage/cards/a/ArcheryTraining.java new file mode 100644 index 00000000000..f70caaa22c9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArcheryTraining.java @@ -0,0 +1,67 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetAttackingOrBlockingCreature; + +/** + * + * @author jeffwadsworth + */ +public final class ArcheryTraining extends CardImpl { + + private static final String rule = "This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on {this}."; + + public ArcheryTraining(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put an arrow counter on Archery Training. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.ARROW.createInstance(), true), TargetController.YOU, true)); + + // Enchanted creature has "{tap}: This creature deals X damage to target attacking or blocking creature, where X is the number of arrow counters on Archery Training." + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new CountersSourceCount(CounterType.ARROW)).setText(rule), new TapSourceCost()); + gainedAbility.addTarget(new TargetAttackingOrBlockingCreature()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA))); + + } + + public ArcheryTraining(final ArcheryTraining card) { + super(card); + } + + @Override + public ArcheryTraining copy() { + return new ArcheryTraining(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FendOff.java b/Mage.Sets/src/mage/cards/f/FendOff.java new file mode 100644 index 00000000000..045d166fe7d --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FendOff.java @@ -0,0 +1,41 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.keyword.CyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public final class FendOff extends CardImpl { + + private static final String rule = "Prevent all combat damage that would be dealt by target creature this turn."; + + public FendOff(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Prevent all combat damage that would be dealt by target creature this turn. + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText(rule)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl("{2}"))); + + } + + public FendOff(final FendOff card) { + super(card); + } + + @Override + public FendOff copy() { + return new FendOff(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 810b12ccff6..2590ab67e58 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -32,6 +32,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Aether Sting", 76, Rarity.UNCOMMON, mage.cards.a.AetherSting.class)); cards.add(new SetCardInfo("Ancient Silverback", 101, Rarity.RARE, mage.cards.a.AncientSilverback.class)); cards.add(new SetCardInfo("Apprentice Necromancer", 51, Rarity.RARE, mage.cards.a.ApprenticeNecromancer.class)); + cards.add(new SetCardInfo("Archery Training", 2, Rarity.UNCOMMON, mage.cards.a.ArcheryTraining.class)); cards.add(new SetCardInfo("Attrition", 52, Rarity.RARE, mage.cards.a.Attrition.class)); cards.add(new SetCardInfo("Aura Thief", 26, Rarity.RARE, mage.cards.a.AuraThief.class)); cards.add(new SetCardInfo("Blizzard Elemental", 27, Rarity.RARE, mage.cards.b.BlizzardElemental.class)); @@ -63,6 +64,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); + cards.add(new SetCardInfo("Fend Off", 7, Rarity.COMMON, mage.cards.f.FendOff.class)); cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); cards.add(new SetCardInfo("Flame Jet", 81, Rarity.COMMON, mage.cards.f.FlameJet.class)); From 9c0162caad06038485c74cadcd1850ff406f6cc5 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:11:50 -0600 Subject: [PATCH 23/50] - Added "ARROW" counter. --- Mage/src/main/java/mage/counters/CounterType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index fd2eb779126..a5ce8b6a603 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -9,6 +9,7 @@ public enum CounterType { AGE("age"), AIM("aim"), + ARROW("arrow"), ARROWHEAD("arrowhead"), AWAKENING("awakening"), BLAZE("blaze"), From ea4c202a40f89ea9911c5b8e4b00a410092bb315 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:51:27 -0600 Subject: [PATCH 24/50] - Added Fatigue and Disappear. --- Mage.Sets/src/mage/cards/d/Disappear.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/cards/f/Fatigue.java | 36 ++++++++ .../common/SkipNextDrawStepTargetEffect.java | 55 ++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/Disappear.java create mode 100644 Mage.Sets/src/mage/cards/f/Fatigue.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/d/Disappear.java b/Mage.Sets/src/mage/cards/d/Disappear.java new file mode 100644 index 00000000000..43b6fa78a8a --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Disappear.java @@ -0,0 +1,87 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class Disappear extends CardImpl { + + public Disappear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // {U}: Return enchanted creature and Disappear to their owners' hands. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DisappearEffect(), new ManaCostsImpl("{U}"))); + + } + + public Disappear(final Disappear card) { + super(card); + } + + @Override + public Disappear copy() { + return new Disappear(this); + } +} + +class DisappearEffect extends OneShotEffect { + + public DisappearEffect() { + super(Outcome.ReturnToHand); + staticText = "Return enchanted creature and {this} to their owners' hands"; + } + + public DisappearEffect(final DisappearEffect effect) { + super(effect); + } + + @Override + public DisappearEffect copy() { + return new DisappearEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent aura = (Permanent) game.getPermanentOrLKIBattlefield(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null + && aura != null + && aura.getAttachedTo() != null) { + Permanent enchantedCreature = game.getPermanent(aura.getAttachedTo()); + controller.moveCards(aura, Zone.HAND, source, game); + if (enchantedCreature != null) { + controller.moveCards(enchantedCreature, Zone.HAND, source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/Fatigue.java b/Mage.Sets/src/mage/cards/f/Fatigue.java new file mode 100644 index 00000000000..8f3ae9784b2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Fatigue.java @@ -0,0 +1,36 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.abilities.effects.common.SkipNextDrawStepTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class Fatigue extends CardImpl { + + private static final String rule = "Target player skips his or her next draw step."; + + public Fatigue(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); + + + // Target player skips his or her next draw step. + this.getSpellAbility().addEffect(new SkipNextDrawStepTargetEffect().setText(rule)); + this.getSpellAbility().addTarget(new TargetPlayer()); + + } + + public Fatigue(final Fatigue card) { + super(card); + } + + @Override + public Fatigue copy() { + return new Fatigue(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java new file mode 100644 index 00000000000..2f1ba7d187e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/SkipNextDrawStepTargetEffect.java @@ -0,0 +1,55 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author jeffwadsworth + */ + +public class SkipNextDrawStepTargetEffect extends ReplacementEffectImpl { + + public SkipNextDrawStepTargetEffect() { + super(Duration.OneUse, Outcome.Detriment); + staticText = "Target player skips his or her next draw step"; + } + + public SkipNextDrawStepTargetEffect(final SkipNextDrawStepTargetEffect effect) { + super(effect); + } + + @Override + public SkipNextDrawStepTargetEffect copy() { + return new SkipNextDrawStepTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DRAW_STEP; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(source.getFirstTarget()); + } +} \ No newline at end of file From 2e9879616c0c9e2282758509eeab78aa72c2d2dd Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 10:52:16 -0600 Subject: [PATCH 25/50] - Updated Urza's Destiny set. --- Mage.Sets/src/mage/sets/UrzasDestiny.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index 2590ab67e58..d5b344ce21b 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -54,6 +54,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Colos Yearling", 79, Rarity.COMMON, mage.cards.c.ColosYearling.class)); cards.add(new SetCardInfo("Compost", 102, Rarity.UNCOMMON, mage.cards.c.Compost.class)); cards.add(new SetCardInfo("Covetous Dragon", 80, Rarity.RARE, mage.cards.c.CovetousDragon.class)); + cards.add(new SetCardInfo("Disappear", 30, Rarity.UNCOMMON, mage.cards.d.Disappear.class)); cards.add(new SetCardInfo("Disease Carriers", 57, Rarity.COMMON, mage.cards.d.DiseaseCarriers.class)); cards.add(new SetCardInfo("Donate", 31, Rarity.RARE, mage.cards.d.Donate.class)); cards.add(new SetCardInfo("Dying Wail", 58, Rarity.COMMON, mage.cards.d.DyingWail.class)); @@ -64,6 +65,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Eradicate", 60, Rarity.UNCOMMON, mage.cards.e.Eradicate.class)); cards.add(new SetCardInfo("Extruder", 130, Rarity.UNCOMMON, mage.cards.e.Extruder.class)); cards.add(new SetCardInfo("False Prophet", 6, Rarity.RARE, mage.cards.f.FalseProphet.class)); + cards.add(new SetCardInfo("Fatigue", 32, Rarity.COMMON, mage.cards.f.Fatigue.class)); cards.add(new SetCardInfo("Fend Off", 7, Rarity.COMMON, mage.cards.f.FendOff.class)); cards.add(new SetCardInfo("Festering Wound", 61, Rarity.UNCOMMON, mage.cards.f.FesteringWound.class)); cards.add(new SetCardInfo("Field Surgeon", 8, Rarity.COMMON, mage.cards.f.FieldSurgeon.class)); From 4f0725586b5d7ffbb7edb2a4fbc2cfc5eed4c104 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 11:40:10 -0600 Subject: [PATCH 26/50] - Urza's Destiny 100%. Added Private Research, Lurking Jackals, Incendiary. --- Mage.Sets/src/mage/cards/i/Incendiary.java | 65 +++++++++ .../src/mage/cards/l/LurkingJackals.java | 123 ++++++++++++++++++ .../src/mage/cards/p/PrivateResearch.java | 60 +++++++++ Mage.Sets/src/mage/sets/UrzasDestiny.java | 3 + 4 files changed, 251 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/Incendiary.java create mode 100644 Mage.Sets/src/mage/cards/l/LurkingJackals.java create mode 100644 Mage.Sets/src/mage/cards/p/PrivateResearch.java diff --git a/Mage.Sets/src/mage/cards/i/Incendiary.java b/Mage.Sets/src/mage/cards/i/Incendiary.java new file mode 100644 index 00000000000..f5987a4793c --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/Incendiary.java @@ -0,0 +1,65 @@ +package mage.cards.i; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class Incendiary extends CardImpl { + + private static final String rule = "{this} deals X damage to any target, where X is the number of fuse counters on {this}."; + + public Incendiary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put a fuse counter on Incendiary. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.FUSE.createInstance(), true), TargetController.YOU, true)); + + // When enchanted creature dies, Incendiary deals X damage to any target, where X is the number of fuse counters on Incendiary. + Effect effect = new DamageTargetEffect(new CountersSourceCount(CounterType.FUSE)).setText(rule); + Ability ability2 = new DiesAttachedTriggeredAbility(effect, "enchanted creature"); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability2); + + } + + public Incendiary(final Incendiary card) { + super(card); + } + + @Override + public Incendiary copy() { + return new Incendiary(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LurkingJackals.java b/Mage.Sets/src/mage/cards/l/LurkingJackals.java new file mode 100644 index 00000000000..2ff584e5a7e --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LurkingJackals.java @@ -0,0 +1,123 @@ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TokenImpl; + +/** + * + * @author jeffwadsworth + */ +public final class LurkingJackals extends CardImpl { + + public LurkingJackals(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); + + // When an opponent has 10 or less life, if Lurking Jackals is an enchantment, it becomes a 3/2 Hound creature. + this.addAbility(new LurkingJackalsStateTriggeredAbility()); + } + + public LurkingJackals(final LurkingJackals card) { + super(card); + } + + @Override + public LurkingJackals copy() { + return new LurkingJackals(this); + } +} + +class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { + + public LurkingJackalsStateTriggeredAbility() { + super(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new LurkingJackalsToken(), "", Duration.Custom, true, false)); + } + + public LurkingJackalsStateTriggeredAbility(final LurkingJackalsStateTriggeredAbility ability) { + super(ability); + } + + @Override + public LurkingJackalsStateTriggeredAbility copy() { + return new LurkingJackalsStateTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (game.getOpponents(getControllerId()).stream().anyMatch((playerId) -> (game.getPlayer(playerId).getLife() <= 10))) { + return true; + } + return false; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + } + + @Override + public boolean canTrigger(Game game) { + //20100716 - 603.8 + Boolean triggered = (Boolean) game.getState().getValue(getSourceId().toString() + "triggered"); + if (triggered == null) { + triggered = Boolean.FALSE; + } + return !triggered; + } + + @Override + public void trigger(Game game, UUID controllerId) { + //20100716 - 603.8 + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.TRUE); + super.trigger(game, controllerId); + } + + @Override + public boolean resolve(Game game) { + //20100716 - 603.8 + boolean result = super.resolve(game); + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + return result; + } + + @Override + public void counter(Game game) { + game.getState().setValue(this.getSourceId().toString() + "triggered", Boolean.FALSE); + } + + @Override + public String getRule() { + return new StringBuilder("When an opponent has 10 or less life, if {this} is an enchantment, ").append(super.getRule()).toString(); + } + +} + +class LurkingJackalsToken extends TokenImpl { + + public LurkingJackalsToken() { + super("Hound", "3/2 Hound creature"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.HOUND); + power = new MageInt(3); + toughness = new MageInt(2); + } + + public LurkingJackalsToken(final LurkingJackalsToken token) { + super(token); + } + + @Override + public LurkingJackalsToken copy() { + return new LurkingJackalsToken(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrivateResearch.java b/Mage.Sets/src/mage/cards/p/PrivateResearch.java new file mode 100644 index 00000000000..bef10ca1c29 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrivateResearch.java @@ -0,0 +1,60 @@ +package mage.cards.p; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; + +/** + * + * @author jeffwadsworth + */ +public final class PrivateResearch extends CardImpl { + + private static final String rule = "draw a card for each page counter on {this}."; + + public PrivateResearch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // At the beginning of your upkeep, you may put a page counter on Private Research. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.PAGE.createInstance(), true), TargetController.YOU, true)); + + // When enchanted creature dies, draw a card for each page counter on Private Research. + this.addAbility(new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.PAGE)).setText(rule), "enchanted creature")); + + } + + public PrivateResearch(final PrivateResearch card) { + super(card); + } + + @Override + public PrivateResearch copy() { + return new PrivateResearch(this); + } +} diff --git a/Mage.Sets/src/mage/sets/UrzasDestiny.java b/Mage.Sets/src/mage/sets/UrzasDestiny.java index d5b344ce21b..aae8ca309c2 100644 --- a/Mage.Sets/src/mage/sets/UrzasDestiny.java +++ b/Mage.Sets/src/mage/sets/UrzasDestiny.java @@ -85,6 +85,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Hunting Moa", 109, Rarity.UNCOMMON, mage.cards.h.HuntingMoa.class)); cards.add(new SetCardInfo("Illuminated Wings", 34, Rarity.COMMON, mage.cards.i.IlluminatedWings.class)); cards.add(new SetCardInfo("Impatience", 88, Rarity.RARE, mage.cards.i.Impatience.class)); + cards.add(new SetCardInfo("Incendiary", 89, Rarity.UNCOMMON, mage.cards.i.Incendiary.class)); cards.add(new SetCardInfo("Iridescent Drake", 35, Rarity.UNCOMMON, mage.cards.i.IridescentDrake.class)); cards.add(new SetCardInfo("Ivy Seer", 110, Rarity.UNCOMMON, mage.cards.i.IvySeer.class)); cards.add(new SetCardInfo("Jasmine Seer", 10, Rarity.UNCOMMON, mage.cards.j.JasmineSeer.class)); @@ -93,6 +94,7 @@ public final class UrzasDestiny extends ExpansionSet { 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("Lurking Jackals", 62, Rarity.UNCOMMON, mage.cards.l.LurkingJackals.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)); @@ -116,6 +118,7 @@ public final class UrzasDestiny extends ExpansionSet { cards.add(new SetCardInfo("Plated Spider", 116, Rarity.COMMON, mage.cards.p.PlatedSpider.class)); cards.add(new SetCardInfo("Plow Under", 117, Rarity.RARE, mage.cards.p.PlowUnder.class)); cards.add(new SetCardInfo("Powder Keg", 136, Rarity.RARE, mage.cards.p.PowderKeg.class)); + cards.add(new SetCardInfo("Private Research", 41, Rarity.UNCOMMON, mage.cards.p.PrivateResearch.class)); cards.add(new SetCardInfo("Quash", 42, Rarity.UNCOMMON, mage.cards.q.Quash.class)); cards.add(new SetCardInfo("Rapid Decay", 67, Rarity.RARE, mage.cards.r.RapidDecay.class)); cards.add(new SetCardInfo("Ravenous Rats", 68, Rarity.COMMON, mage.cards.r.RavenousRats.class)); From a01891f11e3578ba05c273f88e5e40a03d3c9866 Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 19:11:12 -0600 Subject: [PATCH 27/50] - added some null checks. --- Mage.Sets/src/mage/cards/h/HiddenPredators.java | 5 ++++- Mage.Sets/src/mage/cards/l/LurkingJackals.java | 13 ++++++++++--- Mage.Sets/src/mage/cards/o/OpalAvenger.java | 10 ++++++++-- Mage.Sets/src/mage/cards/v/VeiledCrocodile.java | 5 ++++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HiddenPredators.java b/Mage.Sets/src/mage/cards/h/HiddenPredators.java index f5ff50d09b3..88f532926e3 100644 --- a/Mage.Sets/src/mage/cards/h/HiddenPredators.java +++ b/Mage.Sets/src/mage/cards/h/HiddenPredators.java @@ -71,7 +71,10 @@ class HiddenPredatorsStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/l/LurkingJackals.java b/Mage.Sets/src/mage/cards/l/LurkingJackals.java index 2ff584e5a7e..4822bb2c2de 100644 --- a/Mage.Sets/src/mage/cards/l/LurkingJackals.java +++ b/Mage.Sets/src/mage/cards/l/LurkingJackals.java @@ -54,15 +54,22 @@ class LurkingJackalsStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (game.getOpponents(getControllerId()).stream().anyMatch((playerId) -> (game.getPlayer(playerId).getLife() <= 10))) { - return true; + if (game.getOpponents(getControllerId()) != null) { + for (UUID opponentId : game.getOpponents(getControllerId())) { + if (game.getPlayer(opponentId).getLife() <= 10) { + return true; + } + } } return false; } @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/o/OpalAvenger.java b/Mage.Sets/src/mage/cards/o/OpalAvenger.java index 5586cbedf6e..cc28e074245 100644 --- a/Mage.Sets/src/mage/cards/o/OpalAvenger.java +++ b/Mage.Sets/src/mage/cards/o/OpalAvenger.java @@ -54,12 +54,18 @@ class OpalAvengerStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getState().getPlayer(getControllerId()).getLife() <= 10; + if (game.getState().getPlayer(getControllerId()) != null) { + return game.getState().getPlayer(getControllerId()).getLife() <= 10; + } + return false; } @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java index c3790e5c738..860795598af 100644 --- a/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java +++ b/Mage.Sets/src/mage/cards/v/VeiledCrocodile.java @@ -67,7 +67,10 @@ class VeiledCrocodileStateTriggeredAbility extends StateTriggeredAbility { @Override public boolean checkInterveningIfClause(Game game) { - return this.getSourcePermanentIfItStillExists(game).getCardType().contains(CardType.ENCHANTMENT); + if (getSourcePermanentIfItStillExists(game) != null) { + return getSourcePermanentIfItStillExists(game).isEnchantment(); + } + return false; } @Override From 4f1e9b0394380acae4f324e53407cc2457c390b6 Mon Sep 17 00:00:00 2001 From: L_J Date: Mon, 26 Nov 2018 04:16:41 +0100 Subject: [PATCH 28/50] Implemented some Legends cards --- Mage.Sets/src/mage/cards/b/BronzeHorse.java | 91 +++++++++++++++ Mage.Sets/src/mage/cards/e/ElderSpawn.java | 102 +++++++++++++++++ .../src/mage/cards/e/EnchantedBeing.java | 79 +++++++++++++ .../src/mage/cards/f/ForethoughtAmulet.java | 91 +++++++++++++++ Mage.Sets/src/mage/cards/k/KryShield.java | 49 ++++++++ Mage.Sets/src/mage/cards/r/Reverberation.java | 105 ++++++++++++++++++ Mage.Sets/src/mage/cards/s/Subdue.java | 39 +++++++ .../src/mage/cards/w/WallOfTombstones.java | 77 +++++++++++++ Mage.Sets/src/mage/sets/Chronicles.java | 1 + Mage.Sets/src/mage/sets/Legends.java | 16 +++ 10 files changed, 650 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BronzeHorse.java create mode 100644 Mage.Sets/src/mage/cards/e/ElderSpawn.java create mode 100644 Mage.Sets/src/mage/cards/e/EnchantedBeing.java create mode 100644 Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java create mode 100644 Mage.Sets/src/mage/cards/k/KryShield.java create mode 100644 Mage.Sets/src/mage/cards/r/Reverberation.java create mode 100644 Mage.Sets/src/mage/cards/s/Subdue.java create mode 100644 Mage.Sets/src/mage/cards/w/WallOfTombstones.java diff --git a/Mage.Sets/src/mage/cards/b/BronzeHorse.java b/Mage.Sets/src/mage/cards/b/BronzeHorse.java new file mode 100644 index 00000000000..28180cf2bb4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BronzeHorse.java @@ -0,0 +1,91 @@ + +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalReplacementEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventAllDamageToSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.Target; + +/** + * + * @author L_J + */ +public final class BronzeHorse extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(new AnotherPredicate()); + } + + public BronzeHorse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT, CardType.CREATURE},"{7}"); + this.subtype.add(SubType.HORSE); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // As long as you control another creature, prevent all damage that would be dealt to Bronze Horse by spells that target it. + Effect effect = new ConditionalReplacementEffect(new PreventDamageToSourceBySpellsThatTargetIt(), new PermanentsOnTheBattlefieldCondition(filter)); + effect.setText("As long as you control another creature, prevent all damage that would be dealt to {this} by spells that target it."); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public BronzeHorse(final BronzeHorse card) { + super(card); + } + + @Override + public BronzeHorse copy() { + return new BronzeHorse(this); + } +} + +class PreventDamageToSourceBySpellsThatTargetIt extends PreventAllDamageToSourceEffect { + + public PreventDamageToSourceBySpellsThatTargetIt() { + super(Duration.WhileOnBattlefield); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + if (event.getTargetId().equals(source.getSourceId())) { + Spell spell = game.getStack().getSpell(event.getSourceId()); + if (spell != null) { + for (UUID modeId : spell.getStackAbility().getModes().getSelectedModes()) { + Mode mode = spell.getStackAbility().getModes().get(modeId); + for (Target target : mode.getTargets()) { + for (UUID targetId : target.getTargets()) { + if (targetId.equals(source.getSourceId())) { + return true; + } + } + } + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/e/ElderSpawn.java b/Mage.Sets/src/mage/cards/e/ElderSpawn.java new file mode 100644 index 00000000000..1d65526cdcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElderSpawn.java @@ -0,0 +1,102 @@ + +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author L_J + */ +public final class ElderSpawn extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public ElderSpawn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}{U}"); + this.subtype.add(SubType.SPAWN); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // At the beginning of your upkeep, unless you sacrifice an Island, sacrifice Elder Spawn and it deals 6 damage to you. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ElderSpawnEffect(), TargetController.YOU, false)); + + // Elder Spawn can't be blocked by red creatures. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + } + + public ElderSpawn(final ElderSpawn card) { + super(card); + } + + @Override + public ElderSpawn copy() { + return new ElderSpawn(this); + } +} + +class ElderSpawnEffect extends OneShotEffect { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("an Island"); + static { + filter.add(new SubtypePredicate(SubType.ISLAND)); + } + + public ElderSpawnEffect() { + super(Outcome.Sacrifice); + staticText = "unless you sacrifice an Island, sacrifice {this} and it deals 6 damage to you"; + } + + public ElderSpawnEffect(final ElderSpawnEffect effect) { + super(effect); + } + + @Override + public ElderSpawnEffect copy() { + return new ElderSpawnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && sourcePermanent != null) { + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + SacrificeTargetCost cost = new SacrificeTargetCost(target); + if (!controller.chooseUse(Outcome.AIDontUseIt, "Do you wish to sacrifice an Island?", source, game) + || !cost.canPay(source, source.getSourceId(), source.getControllerId(), game) + || !cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) { + sourcePermanent.sacrifice(source.getSourceId(), game); + controller.damage(6, sourcePermanent.getId(), game, false, true); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/e/EnchantedBeing.java b/Mage.Sets/src/mage/cards/e/EnchantedBeing.java new file mode 100644 index 00000000000..0843ff51f8a --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnchantedBeing.java @@ -0,0 +1,79 @@ + +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventAllDamageToSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author L_J + */ +public final class EnchantedBeing extends CardImpl { + + public EnchantedBeing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Prevent all damage that would be dealt to Enchanted Being by enchanted creatures. + Effect effect = new PreventDamageToSourceByEnchantedCreatures(); + effect.setText("Prevent all damage that would be dealt to {this} by enchanted creatures."); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public EnchantedBeing(final EnchantedBeing card) { + super(card); + } + + @Override + public EnchantedBeing copy() { + return new EnchantedBeing(this); + } +} + +class PreventDamageToSourceByEnchantedCreatures extends PreventAllDamageToSourceEffect { + + public PreventDamageToSourceByEnchantedCreatures() { + super(Duration.WhileOnBattlefield); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (super.applies(event, source, game)) { + if (isEnchantedCreature(game.getObject(event.getSourceId()), game)) { + if (event.getTargetId().equals(source.getSourceId())) { + return true; + } + } + } + return false; + } + + public boolean isEnchantedCreature(MageObject input, Game game) { + if (input == null || input.isCreature()) { + return false; + } + for (UUID attachmentId : ((Permanent) input).getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.isEnchantment()) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java b/Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java new file mode 100644 index 00000000000..f6eff9d8ff1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/ForethoughtAmulet.java @@ -0,0 +1,91 @@ + +package mage.cards.f; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent; + +/** + * + * @author L_J + */ +public final class ForethoughtAmulet extends CardImpl { + + public ForethoughtAmulet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); + + // At the beginning of your upkeep, sacrifice Forethought Amulet unless you pay {3}. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new GenericManaCost(3)), TargetController.YOU, false)); + + // If an instant or sorcery source would deal 3 or more damage to you, it deals 2 damage to you instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ForethoughtAmuletEffect())); + } + + public ForethoughtAmulet(final ForethoughtAmulet card) { + super(card); + } + + @Override + public ForethoughtAmulet copy() { + return new ForethoughtAmulet(this); + } +} + +class ForethoughtAmuletEffect extends ReplacementEffectImpl { + + public ForethoughtAmuletEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "If an instant or sorcery source would deal 3 or more damage to you, it deals 2 damage to you instead"; + } + + public ForethoughtAmuletEffect(final ForethoughtAmuletEffect effect) { + super(effect); + } + + @Override + public ForethoughtAmuletEffect copy() { + return new ForethoughtAmuletEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getAmount() >= 3) { + MageObject object = game.getObject(event.getSourceId()); + return object != null && (object.isInstant() || object.isSorcery()); + } + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + if (event.getTargetId().equals(source.getControllerId())) { + event.setAmount(2); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KryShield.java b/Mage.Sets/src/mage/cards/k/KryShield.java new file mode 100644 index 00000000000..8fc55fc5dc4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KryShield.java @@ -0,0 +1,49 @@ + +package mage.cards.k; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.dynamicvalue.common.TargetConvertedManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author L_J + */ +public final class KryShield extends CardImpl { + + public KryShield(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + + // {2}, {T}: Prevent all damage that would be dealt this turn by target creature you control. That creature gets +0/+X until end of turn, where X is its converted mana cost. + Effect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn); + effect.setText("Prevent all damage that would be dealt this turn by target creature you control"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2)); + ability.addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true) + .setText("That creature gets +0/+X until end of turn, where X is its converted mana cost")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + } + + public KryShield(final KryShield card) { + super(card); + } + + @Override + public KryShield copy() { + return new KryShield(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/Reverberation.java b/Mage.Sets/src/mage/cards/r/Reverberation.java new file mode 100644 index 00000000000..0a0768ae700 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Reverberation.java @@ -0,0 +1,105 @@ + +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.events.DamageEvent; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetSpell; + +/** + * + * @author L_J + */ +public final class Reverberation extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("sorcery spell"); + + static { + filter.add(new CardTypePredicate(CardType.SORCERY)); + } + + public Reverberation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); + + // All damage that would be dealt this turn by target sorcery spell is dealt to that spell’s controller instead. + this.getSpellAbility().addEffect(new ReverberationEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + } + + public Reverberation(final Reverberation card) { + super(card); + } + + @Override + public Reverberation copy() { + return new Reverberation(this); + } +} + +class ReverberationEffect extends ReplacementEffectImpl { + + public ReverberationEffect() { + super(Duration.EndOfTurn, Outcome.RedirectDamage); + staticText = "All damage that would be dealt this turn by target sorcery spell is dealt to that spell’s controller instead"; + } + + public ReverberationEffect(final ReverberationEffect effect) { + super(effect); + } + + @Override + public ReverberationEffect copy() { + return new ReverberationEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_CREATURE || + event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER || + event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + DamageEvent damageEvent = (DamageEvent) event; + if (controller != null) { + Spell targetSpell = game.getStack().getSpell(source.getFirstTarget()); + if (targetSpell != null) { + Player targetsController = game.getPlayer(targetSpell.getControllerId()); + if (targetsController != null) { + targetsController.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects()); + return true; + } + } + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + DamageEvent damageEvent = (DamageEvent) event; + Spell targetSpell = game.getStack().getSpell(source.getFirstTarget()); + if (targetSpell != null) { + return damageEvent.getAmount() > 0; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/Subdue.java b/Mage.Sets/src/mage/cards/s/Subdue.java new file mode 100644 index 00000000000..63ac77351e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Subdue.java @@ -0,0 +1,39 @@ + +package mage.cards.s; + +import java.util.UUID; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.dynamicvalue.common.TargetConvertedManaCost; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author L_J + */ +public final class Subdue extends CardImpl { + + public Subdue(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); + + // Prevent all combat damage that would be dealt by target creature this turn. That creature gets +0/+X until end of turn, where X is its converted mana cost. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true)); + this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true) + .setText("That creature gets +0/+X until end of turn, where X is its converted mana cost")); + } + + public Subdue(final Subdue card) { + super(card); + } + + @Override + public Subdue copy() { + return new Subdue(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WallOfTombstones.java b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java new file mode 100644 index 00000000000..16abfc19f7c --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WallOfTombstones.java @@ -0,0 +1,77 @@ + +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.SetToughnessSourceEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.TargetController; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.util.CardUtil; + +/** + * + * @author L_J + */ +public final class WallOfTombstones extends CardImpl { + + public WallOfTombstones(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + this.subtype.add(SubType.WALL); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // At the beginning of your upkeep, change Wall of Tombstones’s base toughness to 1 plus the number of creature cards in your graveyard. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new WallOfTombstonesEffect(), TargetController.YOU, false)); + + } + + public WallOfTombstones(final WallOfTombstones card) { + super(card); + } + + @Override + public WallOfTombstones copy() { + return new WallOfTombstones(this); + } +} + +class WallOfTombstonesEffect extends OneShotEffect { + + public WallOfTombstonesEffect() { + super(Outcome.Detriment); + this.staticText = "change {this}’s base toughness to 1 plus the number of creature cards in your graveyard"; + } + + public WallOfTombstonesEffect(final WallOfTombstonesEffect effect) { + super(effect); + } + + @Override + public WallOfTombstonesEffect copy() { + return new WallOfTombstonesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int newToughness = CardUtil.addWithOverflowCheck(1, new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE).calculate(game, source, this)); + game.addEffect(new SetToughnessSourceEffect(new StaticValue(newToughness), Duration.Custom, SubLayer.SetPT_7b), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/Chronicles.java b/Mage.Sets/src/mage/sets/Chronicles.java index 050f42904b8..66a72016426 100644 --- a/Mage.Sets/src/mage/sets/Chronicles.java +++ b/Mage.Sets/src/mage/sets/Chronicles.java @@ -47,6 +47,7 @@ public final class Chronicles extends ExpansionSet { cards.add(new SetCardInfo("Bog Rats", 2, Rarity.COMMON, mage.cards.b.BogRats.class)); cards.add(new SetCardInfo("Book of Rass", 75, Rarity.RARE, mage.cards.b.BookOfRass.class)); cards.add(new SetCardInfo("Boomerang", 16, Rarity.COMMON, mage.cards.b.Boomerang.class)); + cards.add(new SetCardInfo("Bronze Horse", 76, Rarity.RARE, mage.cards.b.BronzeHorse.class)); cards.add(new SetCardInfo("Cat Warriors", 30, Rarity.COMMON, mage.cards.c.CatWarriors.class)); cards.add(new SetCardInfo("Chromium", 109, Rarity.RARE, mage.cards.c.Chromium.class)); cards.add(new SetCardInfo("City of Brass", 92, Rarity.RARE, mage.cards.c.CityOfBrass.class)); diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java index 68a33d49747..134bb3b75cb 100644 --- a/Mage.Sets/src/mage/sets/Legends.java +++ b/Mage.Sets/src/mage/sets/Legends.java @@ -29,6 +29,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Acid Rain", 44, Rarity.RARE, mage.cards.a.AcidRain.class)); cards.add(new SetCardInfo("Active Volcano", 130, Rarity.COMMON, mage.cards.a.ActiveVolcano.class)); cards.add(new SetCardInfo("Adun Oakenshield", 216, Rarity.RARE, mage.cards.a.AdunOakenshield.class)); + cards.add(new SetCardInfo("Adventurers' Guildhouse", 300, Rarity.UNCOMMON, mage.cards.a.AdventurersGuildhouse.class)); cards.add(new SetCardInfo("Aerathi Berserker", 131, Rarity.UNCOMMON, mage.cards.a.AerathiBerserker.class)); cards.add(new SetCardInfo("Aisling Leprechaun", 173, Rarity.COMMON, mage.cards.a.AislingLeprechaun.class)); cards.add(new SetCardInfo("Akron Legionnaire", 1, Rarity.RARE, mage.cards.a.AkronLegionnaire.class)); @@ -58,8 +59,10 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Blue Mana Battery", 275, Rarity.UNCOMMON, mage.cards.b.BlueManaBattery.class)); cards.add(new SetCardInfo("Boomerang", 48, Rarity.COMMON, mage.cards.b.Boomerang.class)); cards.add(new SetCardInfo("Boris Devilboon", 223, Rarity.RARE, mage.cards.b.BorisDevilboon.class)); + cards.add(new SetCardInfo("Bronze Horse", 276, Rarity.RARE, mage.cards.b.BronzeHorse.class)); cards.add(new SetCardInfo("Carrion Ants", 90, Rarity.RARE, mage.cards.c.CarrionAnts.class)); cards.add(new SetCardInfo("Cat Warriors", 177, Rarity.COMMON, mage.cards.c.CatWarriors.class)); + cards.add(new SetCardInfo("Cathedral of Serra", 301, Rarity.UNCOMMON, mage.cards.c.CathedralOfSerra.class)); cards.add(new SetCardInfo("Caverns of Despair", 136, Rarity.RARE, mage.cards.c.CavernsOfDespair.class)); cards.add(new SetCardInfo("Chain Lightning", 137, Rarity.COMMON, mage.cards.c.ChainLightning.class)); cards.add(new SetCardInfo("Chains of Mephistopheles", 91, Rarity.RARE, mage.cards.c.ChainsOfMephistopheles.class)); @@ -88,8 +91,10 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Durkwood Boars", 182, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); cards.add(new SetCardInfo("Dwarven Song", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenSong.class)); cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.RARE, mage.cards.e.ElderLandWurm.class)); + cards.add(new SetCardInfo("Elder Spawn", 52, Rarity.RARE, mage.cards.e.ElderSpawn.class)); cards.add(new SetCardInfo("Elven Riders", 183, Rarity.RARE, mage.cards.e.ElvenRiders.class)); cards.add(new SetCardInfo("Emerald Dragonfly", 184, Rarity.COMMON, mage.cards.e.EmeraldDragonfly.class)); + cards.add(new SetCardInfo("Enchanted Being", 12, Rarity.COMMON, mage.cards.e.EnchantedBeing.class)); cards.add(new SetCardInfo("Enchantment Alteration", 53, Rarity.COMMON, mage.cards.e.EnchantmentAlteration.class)); cards.add(new SetCardInfo("Energy Tap", 54, Rarity.COMMON, mage.cards.e.EnergyTap.class)); cards.add(new SetCardInfo("Eternal Warrior", 144, Rarity.UNCOMMON, mage.cards.e.EternalWarrior.class)); @@ -102,6 +107,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Flash Flood", 57, Rarity.COMMON, mage.cards.f.FlashFlood.class)); cards.add(new SetCardInfo("Floral Spuzzem", 187, Rarity.UNCOMMON, mage.cards.f.FloralSpuzzem.class)); cards.add(new SetCardInfo("Force Spike", 58, Rarity.COMMON, mage.cards.f.ForceSpike.class)); + cards.add(new SetCardInfo("Forethought Amulet", 277, Rarity.RARE, mage.cards.f.ForethoughtAmulet.class)); cards.add(new SetCardInfo("Fortified Area", 14, Rarity.UNCOMMON, mage.cards.f.FortifiedArea.class)); cards.add(new SetCardInfo("Frost Giant", 148, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class)); cards.add(new SetCardInfo("Gabriel Angelfire", 226, Rarity.RARE, mage.cards.g.GabrielAngelfire.class)); @@ -159,6 +165,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Kobold Overlord", 155, Rarity.RARE, mage.cards.k.KoboldOverlord.class)); cards.add(new SetCardInfo("Kobold Taskmaster", 156, Rarity.UNCOMMON, mage.cards.k.KoboldTaskmaster.class)); cards.add(new SetCardInfo("Kobolds of Kher Keep", 157, Rarity.COMMON, mage.cards.k.KoboldsOfKherKeep.class)); + cards.add(new SetCardInfo("Kry Shield", 282, Rarity.UNCOMMON, mage.cards.k.KryShield.class)); cards.add(new SetCardInfo("Lady Caleria", 239, Rarity.RARE, mage.cards.l.LadyCaleria.class)); cards.add(new SetCardInfo("Lady Evangela", 240, Rarity.RARE, mage.cards.l.LadyEvangela.class)); cards.add(new SetCardInfo("Lady Orca", 241, Rarity.UNCOMMON, mage.cards.l.LadyOrca.class)); @@ -175,10 +182,12 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Mana Matrix", 285, Rarity.RARE, mage.cards.m.ManaMatrix.class)); cards.add(new SetCardInfo("Marble Priest", 286, Rarity.UNCOMMON, mage.cards.m.MarblePriest.class)); cards.add(new SetCardInfo("Marhault Elsdragon", 244, Rarity.UNCOMMON, mage.cards.m.MarhaultElsdragon.class)); + cards.add(new SetCardInfo("Master of the Hunt", 194, Rarity.RARE, mage.cards.m.MasterOfTheHunt.class)); cards.add(new SetCardInfo("Mirror Universe", 287, Rarity.RARE, mage.cards.m.MirrorUniverse.class)); cards.add(new SetCardInfo("Moat", 28, Rarity.RARE, mage.cards.m.Moat.class)); cards.add(new SetCardInfo("Mold Demon", 112, Rarity.RARE, mage.cards.m.MoldDemon.class)); cards.add(new SetCardInfo("Moss Monster", 195, Rarity.COMMON, mage.cards.m.MossMonster.class)); + cards.add(new SetCardInfo("Mountain Stronghold", 304, Rarity.UNCOMMON, mage.cards.m.MountainStronghold.class)); cards.add(new SetCardInfo("Mountain Yeti", 159, Rarity.UNCOMMON, mage.cards.m.MountainYeti.class)); cards.add(new SetCardInfo("Nebuchadnezzar", 245, Rarity.RARE, mage.cards.n.Nebuchadnezzar.class)); cards.add(new SetCardInfo("Nether Void", 113, Rarity.RARE, mage.cards.n.NetherVoid.class)); @@ -217,6 +226,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Remove Soul", 72, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); cards.add(new SetCardInfo("Reset", 73, Rarity.UNCOMMON, mage.cards.r.Reset.class)); cards.add(new SetCardInfo("Revelation", 202, Rarity.RARE, mage.cards.r.Revelation.class)); + cards.add(new SetCardInfo("Reverberation", 74, Rarity.RARE, mage.cards.r.Reverberation.class)); cards.add(new SetCardInfo("Righteous Avengers", 34, Rarity.UNCOMMON, mage.cards.r.RighteousAvengers.class)); cards.add(new SetCardInfo("Ring of Immortals", 293, Rarity.RARE, mage.cards.r.RingOfImmortals.class)); cards.add(new SetCardInfo("Riven Turnbull", 254, Rarity.UNCOMMON, mage.cards.r.RivenTurnbull.class)); @@ -224,10 +234,12 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Rubinia Soulsinger", 256, Rarity.RARE, mage.cards.r.RubiniaSoulsinger.class)); cards.add(new SetCardInfo("Rust", 203, Rarity.COMMON, mage.cards.r.Rust.class)); cards.add(new SetCardInfo("Sea Kings' Blessing", 75, Rarity.UNCOMMON, mage.cards.s.SeaKingsBlessing.class)); + cards.add(new SetCardInfo("Seafarer's Quay", 306, Rarity.UNCOMMON, mage.cards.s.SeafarersQuay.class)); cards.add(new SetCardInfo("Seeker", 35, Rarity.UNCOMMON, mage.cards.s.Seeker.class)); cards.add(new SetCardInfo("Segovian Leviathan", 76, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class)); cards.add(new SetCardInfo("Sentinel", 294, Rarity.RARE, mage.cards.s.Sentinel.class)); cards.add(new SetCardInfo("Serpent Generator", 295, Rarity.RARE, mage.cards.s.SerpentGenerator.class)); + cards.add(new SetCardInfo("Shelkin Brownie", 204, Rarity.COMMON, mage.cards.s.ShelkinBrownie.class)); cards.add(new SetCardInfo("Shield Wall", 36, Rarity.UNCOMMON, mage.cards.s.ShieldWall.class)); cards.add(new SetCardInfo("Shimian Night Stalker", 116, Rarity.UNCOMMON, mage.cards.s.ShimianNightStalker.class)); cards.add(new SetCardInfo("Sir Shandlar of Eberyn", 257, Rarity.UNCOMMON, mage.cards.s.SirShandlarOfEberyn.class)); @@ -241,6 +253,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Stangg", 260, Rarity.RARE, mage.cards.s.Stangg.class)); cards.add(new SetCardInfo("Storm Seeker", 205, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class)); cards.add(new SetCardInfo("Storm World", 165, Rarity.RARE, mage.cards.s.StormWorld.class)); + cards.add(new SetCardInfo("Subdue", 206, Rarity.COMMON, mage.cards.s.Subdue.class)); cards.add(new SetCardInfo("Sunastian Falconer", 261, Rarity.UNCOMMON, mage.cards.s.SunastianFalconer.class)); cards.add(new SetCardInfo("Sword of the Ages", 296, Rarity.RARE, mage.cards.s.SwordOfTheAges.class)); cards.add(new SetCardInfo("Sylvan Library", 207, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class)); @@ -257,6 +270,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Thunder Spirit", 39, Rarity.RARE, mage.cards.t.ThunderSpirit.class)); cards.add(new SetCardInfo("Time Elemental", 81, Rarity.RARE, mage.cards.t.TimeElemental.class)); cards.add(new SetCardInfo("Tobias Andrion", 264, Rarity.UNCOMMON, mage.cards.t.TobiasAndrion.class)); + cards.add(new SetCardInfo("Tolaria", 308, Rarity.UNCOMMON, mage.cards.t.Tolaria.class)); cards.add(new SetCardInfo("Tor Wauki", 265, Rarity.UNCOMMON, mage.cards.t.TorWauki.class)); cards.add(new SetCardInfo("Torsten Von Ursus", 266, Rarity.UNCOMMON, mage.cards.t.TorstenVonUrsus.class)); cards.add(new SetCardInfo("Touch of Darkness", 122, Rarity.UNCOMMON, mage.cards.t.TouchOfDarkness.class)); @@ -266,6 +280,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Tundra Wolves", 40, Rarity.COMMON, mage.cards.t.TundraWolves.class)); cards.add(new SetCardInfo("Typhoon", 209, Rarity.RARE, mage.cards.t.Typhoon.class)); cards.add(new SetCardInfo("Undertow", 82, Rarity.UNCOMMON, mage.cards.u.Undertow.class)); + cards.add(new SetCardInfo("Unholy Citadel", 309, Rarity.UNCOMMON, mage.cards.u.UnholyCitadel.class)); cards.add(new SetCardInfo("Underworld Dreams", 124, Rarity.UNCOMMON, mage.cards.u.UnderworldDreams.class)); cards.add(new SetCardInfo("Untamed Wilds", 210, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); cards.add(new SetCardInfo("Ur-Drago", 268, Rarity.RARE, mage.cards.u.UrDrago.class)); @@ -281,6 +296,7 @@ public final class Legends extends ExpansionSet { cards.add(new SetCardInfo("Wall of Light", 43, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class)); cards.add(new SetCardInfo("Wall of Opposition", 171, Rarity.RARE, mage.cards.w.WallOfOpposition.class)); cards.add(new SetCardInfo("Wall of Putrid Flesh", 127, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class)); + cards.add(new SetCardInfo("Wall of Tombstones", 129, Rarity.UNCOMMON, mage.cards.w.WallOfTombstones.class)); cards.add(new SetCardInfo("Wall of Vapor", 84, Rarity.COMMON, mage.cards.w.WallOfVapor.class)); cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class)); cards.add(new SetCardInfo("Whirling Dervish", 211, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class)); From 77ab63000150798a390f55107d1acf838f5e0cba Mon Sep 17 00:00:00 2001 From: jeffwadsworth Date: Sun, 25 Nov 2018 21:38:07 -0600 Subject: [PATCH 29/50] - Added Duplicity. --- Mage.Sets/src/mage/cards/d/Duplicity.java | 200 ++++++ Mage.Sets/src/mage/sets/Tempest.java | 737 +++++++++++----------- 2 files changed, 569 insertions(+), 368 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/Duplicity.java diff --git a/Mage.Sets/src/mage/cards/d/Duplicity.java b/Mage.Sets/src/mage/cards/d/Duplicity.java new file mode 100644 index 00000000000..ec2655933c0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/Duplicity.java @@ -0,0 +1,200 @@ +package mage.cards.d; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author jeffwadsworth + */ +public final class Duplicity extends CardImpl { + + public Duplicity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); + + // When Duplicity enters the battlefield, exile the top five cards of your library face down. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DuplicityEffect(), false)); + + // At the beginning of your upkeep, you may exile all cards from your hand face down. If you do, put all other cards you own exiled with Duplicity into your hand. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DuplicityExileHandEffect(), TargetController.YOU, true)); + + // At the beginning of your end step, discard a card. + this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DiscardControllerEffect(1), false)); + + // When you lose control of Duplicity, put all cards exiled with Duplicity into their owner's graveyard. + this.addAbility(new LoseControlDuplicity()); + + } + + public Duplicity(final Duplicity card) { + super(card); + } + + @Override + public Duplicity copy() { + return new Duplicity(this); + } +} + +class DuplicityEffect extends OneShotEffect { + + public DuplicityEffect() { + super(Outcome.Exile); + staticText = "exile the top five cards of your library face down"; + } + + public DuplicityEffect(final DuplicityEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + if (controller.getLibrary().hasCards()) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsToExile = controller.getLibrary().getTopCards(game, 5); + for (Card card : cardsToExile) { + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); + card.setFaceDown(true, game); + } + } + return true; + } + return false; + } + + @Override + public DuplicityEffect copy() { + return new DuplicityEffect(this); + } +} + +class DuplicityExileHandEffect extends OneShotEffect { + + public DuplicityExileHandEffect() { + super(Outcome.Exile); + staticText = "you may exile all cards from your hand face down. If you do, put all other cards you own exiled with {this} into your hand"; + } + + public DuplicityExileHandEffect(final DuplicityExileHandEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + if (!controller.getHand().isEmpty()) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsFromHandToExile = controller.getHand().getCards(game); + for (Card card : cardsFromHandToExile) { + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); + card.setFaceDown(true, game); + } + Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); + Set cardsToReturnToHandFromExile = new HashSet<>(); + for (Card card : cardsInExile) { + if (!cardsFromHandToExile.contains(card)) { + cardsToReturnToHandFromExile.add(card); + } + } + controller.moveCards(cardsToReturnToHandFromExile, Zone.HAND, source, game); + } + return true; + } + return false; + } + + @Override + public DuplicityExileHandEffect copy() { + return new DuplicityExileHandEffect(this); + } +} + +class LoseControlDuplicity extends DelayedTriggeredAbility { + + public LoseControlDuplicity() { + super(new PutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false); + } + + public LoseControlDuplicity(final LoseControlDuplicity ability) { + super(ability); + } + + @Override + public LoseControlDuplicity copy() { + return new LoseControlDuplicity(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LOST_CONTROL; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getPlayerId().equals(controllerId); + } + + @Override + public String getRule() { + return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard."; + } +} + +class PutExiledCardsInOwnersGraveyard extends OneShotEffect { + + public PutExiledCardsInOwnersGraveyard() { + super(Outcome.Neutral); + staticText = " put all cards exiled with {this} into their owner's graveyard."; + } + + public PutExiledCardsInOwnersGraveyard(final PutExiledCardsInOwnersGraveyard effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); + controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED); + return true; + } + return false; + } + + @Override + public PutExiledCardsInOwnersGraveyard copy() { + return new PutExiledCardsInOwnersGraveyard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Tempest.java b/Mage.Sets/src/mage/sets/Tempest.java index 5269f4c17c7..e1ec411d32e 100644 --- a/Mage.Sets/src/mage/sets/Tempest.java +++ b/Mage.Sets/src/mage/sets/Tempest.java @@ -1,368 +1,369 @@ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -public final class Tempest extends ExpansionSet { - - private static final Tempest instance = new Tempest(); - - public static Tempest getInstance() { - return instance; - } - - private Tempest() { - super("Tempest", "TMP", ExpansionSet.buildDate(1997, 10, 1), SetType.EXPANSION); - this.blockName = "Tempest"; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abandon Hope", 107, Rarity.UNCOMMON, mage.cards.a.AbandonHope.class)); - cards.add(new SetCardInfo("Advance Scout", 1, Rarity.COMMON, mage.cards.a.AdvanceScout.class)); - cards.add(new SetCardInfo("Aftershock", 160, Rarity.COMMON, mage.cards.a.Aftershock.class)); - cards.add(new SetCardInfo("Altar of Dementia", 276, Rarity.RARE, mage.cards.a.AltarOfDementia.class)); - cards.add(new SetCardInfo("Aluren", 213, Rarity.RARE, mage.cards.a.Aluren.class)); - cards.add(new SetCardInfo("Ancient Runes", 161, Rarity.UNCOMMON, mage.cards.a.AncientRunes.class)); - cards.add(new SetCardInfo("Ancient Tomb", 315, Rarity.UNCOMMON, mage.cards.a.AncientTomb.class)); - cards.add(new SetCardInfo("Angelic Protector", 2, Rarity.UNCOMMON, mage.cards.a.AngelicProtector.class)); - cards.add(new SetCardInfo("Anoint", 3, Rarity.COMMON, mage.cards.a.Anoint.class)); - cards.add(new SetCardInfo("Apes of Rath", 214, Rarity.UNCOMMON, mage.cards.a.ApesOfRath.class)); - cards.add(new SetCardInfo("Apocalypse", 162, Rarity.RARE, mage.cards.a.Apocalypse.class)); - cards.add(new SetCardInfo("Armor Sliver", 4, Rarity.UNCOMMON, mage.cards.a.ArmorSliver.class)); - cards.add(new SetCardInfo("Armored Pegasus", 5, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); - cards.add(new SetCardInfo("Auratog", 6, Rarity.RARE, mage.cards.a.Auratog.class)); - cards.add(new SetCardInfo("Avenging Angel", 7, Rarity.RARE, mage.cards.a.AvengingAngel.class)); - cards.add(new SetCardInfo("Barbed Sliver", 163, Rarity.UNCOMMON, mage.cards.b.BarbedSliver.class)); - cards.add(new SetCardInfo("Bayou Dragonfly", 215, Rarity.COMMON, mage.cards.b.BayouDragonfly.class)); - cards.add(new SetCardInfo("Bellowing Fiend", 108, Rarity.RARE, mage.cards.b.BellowingFiend.class)); - cards.add(new SetCardInfo("Benthic Behemoth", 54, Rarity.RARE, mage.cards.b.BenthicBehemoth.class)); - cards.add(new SetCardInfo("Blood Frenzy", 164, Rarity.COMMON, mage.cards.b.BloodFrenzy.class)); - cards.add(new SetCardInfo("Blood Pet", 109, Rarity.COMMON, mage.cards.b.BloodPet.class)); - cards.add(new SetCardInfo("Boil", 165, Rarity.UNCOMMON, mage.cards.b.Boil.class)); - cards.add(new SetCardInfo("Booby Trap", 277, Rarity.RARE, mage.cards.b.BoobyTrap.class)); - cards.add(new SetCardInfo("Bottle Gnomes", 278, Rarity.UNCOMMON, mage.cards.b.BottleGnomes.class)); - cards.add(new SetCardInfo("Bounty Hunter", 110, Rarity.RARE, mage.cards.b.BountyHunter.class)); - cards.add(new SetCardInfo("Broken Fall", 216, Rarity.COMMON, mage.cards.b.BrokenFall.class)); - cards.add(new SetCardInfo("Caldera Lake", 316, Rarity.RARE, mage.cards.c.CalderaLake.class)); - cards.add(new SetCardInfo("Canopy Spider", 217, Rarity.COMMON, mage.cards.c.CanopySpider.class)); - cards.add(new SetCardInfo("Canyon Drake", 166, Rarity.RARE, mage.cards.c.CanyonDrake.class)); - cards.add(new SetCardInfo("Canyon Wildcat", 167, Rarity.COMMON, mage.cards.c.CanyonWildcat.class)); - cards.add(new SetCardInfo("Capsize", 55, Rarity.COMMON, mage.cards.c.Capsize.class)); - cards.add(new SetCardInfo("Carrionette", 111, Rarity.RARE, mage.cards.c.Carrionette.class)); - cards.add(new SetCardInfo("Chaotic Goo", 168, Rarity.RARE, mage.cards.c.ChaoticGoo.class)); - cards.add(new SetCardInfo("Charging Rhino", 218, Rarity.UNCOMMON, mage.cards.c.ChargingRhino.class)); - cards.add(new SetCardInfo("Chill", 56, Rarity.UNCOMMON, mage.cards.c.Chill.class)); - cards.add(new SetCardInfo("Choke", 219, Rarity.UNCOMMON, mage.cards.c.Choke.class)); - cards.add(new SetCardInfo("Cinder Marsh", 317, Rarity.UNCOMMON, mage.cards.c.CinderMarsh.class)); - cards.add(new SetCardInfo("Circle of Protection: Black", 8, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class)); - cards.add(new SetCardInfo("Circle of Protection: Blue", 9, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlue.class)); - cards.add(new SetCardInfo("Circle of Protection: Green", 10, Rarity.COMMON, mage.cards.c.CircleOfProtectionGreen.class)); - cards.add(new SetCardInfo("Circle of Protection: Red", 11, Rarity.COMMON, mage.cards.c.CircleOfProtectionRed.class)); - cards.add(new SetCardInfo("Circle of Protection: Shadow", 12, Rarity.COMMON, mage.cards.c.CircleOfProtectionShadow.class)); - cards.add(new SetCardInfo("Circle of Protection: White", 13, Rarity.COMMON, mage.cards.c.CircleOfProtectionWhite.class)); - cards.add(new SetCardInfo("Clergy en-Vec", 14, Rarity.COMMON, mage.cards.c.ClergyEnVec.class)); - cards.add(new SetCardInfo("Clot Sliver", 112, Rarity.COMMON, mage.cards.c.ClotSliver.class)); - cards.add(new SetCardInfo("Cloudchaser Eagle", 15, Rarity.COMMON, mage.cards.c.CloudchaserEagle.class)); - cards.add(new SetCardInfo("Coercion", 113, Rarity.COMMON, mage.cards.c.Coercion.class)); - cards.add(new SetCardInfo("Coffin Queen", 114, Rarity.RARE, mage.cards.c.CoffinQueen.class)); - cards.add(new SetCardInfo("Coiled Tinviper", 279, Rarity.COMMON, mage.cards.c.CoiledTinviper.class)); - cards.add(new SetCardInfo("Cold Storage", 280, Rarity.RARE, mage.cards.c.ColdStorage.class)); - cards.add(new SetCardInfo("Commander Greven il-Vec", 115, Rarity.RARE, mage.cards.c.CommanderGrevenIlVec.class)); - cards.add(new SetCardInfo("Corpse Dance", 116, Rarity.RARE, mage.cards.c.CorpseDance.class)); - cards.add(new SetCardInfo("Counterspell", 57, Rarity.COMMON, mage.cards.c.Counterspell.class)); - cards.add(new SetCardInfo("Crazed Armodon", 220, Rarity.RARE, mage.cards.c.CrazedArmodon.class)); - cards.add(new SetCardInfo("Crown of Flames", 169, Rarity.COMMON, mage.cards.c.CrownOfFlames.class)); - cards.add(new SetCardInfo("Cursed Scroll", 281, Rarity.RARE, mage.cards.c.CursedScroll.class)); - cards.add(new SetCardInfo("Dark Banishing", 117, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); - cards.add(new SetCardInfo("Dark Ritual", 118, Rarity.COMMON, mage.cards.d.DarkRitual.class)); - cards.add(new SetCardInfo("Darkling Stalker", 119, Rarity.COMMON, mage.cards.d.DarklingStalker.class)); - cards.add(new SetCardInfo("Dauthi Embrace", 120, Rarity.UNCOMMON, mage.cards.d.DauthiEmbrace.class)); - cards.add(new SetCardInfo("Dauthi Ghoul", 121, Rarity.UNCOMMON, mage.cards.d.DauthiGhoul.class)); - cards.add(new SetCardInfo("Dauthi Horror", 122, Rarity.COMMON, mage.cards.d.DauthiHorror.class)); - cards.add(new SetCardInfo("Dauthi Marauder", 123, Rarity.COMMON, mage.cards.d.DauthiMarauder.class)); - cards.add(new SetCardInfo("Dauthi Mercenary", 124, Rarity.UNCOMMON, mage.cards.d.DauthiMercenary.class)); - cards.add(new SetCardInfo("Dauthi Mindripper", 125, Rarity.UNCOMMON, mage.cards.d.DauthiMindripper.class)); - cards.add(new SetCardInfo("Dauthi Slayer", 126, Rarity.COMMON, mage.cards.d.DauthiSlayer.class)); - cards.add(new SetCardInfo("Deadshot", 170, Rarity.RARE, mage.cards.d.Deadshot.class)); - cards.add(new SetCardInfo("Death Pits of Rath", 127, Rarity.RARE, mage.cards.d.DeathPitsOfRath.class)); - cards.add(new SetCardInfo("Diabolic Edict", 128, Rarity.COMMON, mage.cards.d.DiabolicEdict.class)); - cards.add(new SetCardInfo("Dirtcowl Wurm", 221, Rarity.RARE, mage.cards.d.DirtcowlWurm.class)); - cards.add(new SetCardInfo("Disenchant", 16, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Dismiss", 58, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); - cards.add(new SetCardInfo("Disturbed Burial", 129, Rarity.COMMON, mage.cards.d.DisturbedBurial.class)); - cards.add(new SetCardInfo("Dracoplasm", 266, Rarity.RARE, mage.cards.d.Dracoplasm.class)); - cards.add(new SetCardInfo("Dread of Night", 130, Rarity.UNCOMMON, mage.cards.d.DreadOfNight.class)); - cards.add(new SetCardInfo("Dream Cache", 59, Rarity.COMMON, mage.cards.d.DreamCache.class)); - cards.add(new SetCardInfo("Dregs of Sorrow", 131, Rarity.RARE, mage.cards.d.DregsOfSorrow.class)); - cards.add(new SetCardInfo("Earthcraft", 222, Rarity.RARE, mage.cards.e.Earthcraft.class)); - cards.add(new SetCardInfo("Echo Chamber", 282, Rarity.RARE, mage.cards.e.EchoChamber.class)); - cards.add(new SetCardInfo("Eladamri's Vineyard", 223, Rarity.RARE, mage.cards.e.EladamrisVineyard.class)); - cards.add(new SetCardInfo("Eladamri, Lord of Leaves", 224, Rarity.RARE, mage.cards.e.EladamriLordOfLeaves.class)); - cards.add(new SetCardInfo("Elite Javelineer", 17, Rarity.COMMON, mage.cards.e.EliteJavelineer.class)); - cards.add(new SetCardInfo("Elven Warhounds", 225, Rarity.RARE, mage.cards.e.ElvenWarhounds.class)); - cards.add(new SetCardInfo("Elvish Fury", 226, Rarity.COMMON, mage.cards.e.ElvishFury.class)); - cards.add(new SetCardInfo("Emerald Medallion", 283, Rarity.RARE, mage.cards.e.EmeraldMedallion.class)); - cards.add(new SetCardInfo("Emmessi Tome", 284, Rarity.RARE, mage.cards.e.EmmessiTome.class)); - cards.add(new SetCardInfo("Endless Scream", 132, Rarity.COMMON, mage.cards.e.EndlessScream.class)); - cards.add(new SetCardInfo("Energizer", 285, Rarity.RARE, mage.cards.e.Energizer.class)); - cards.add(new SetCardInfo("Enfeeblement", 133, Rarity.COMMON, mage.cards.e.Enfeeblement.class)); - cards.add(new SetCardInfo("Enraging Licid", 171, Rarity.UNCOMMON, mage.cards.e.EnragingLicid.class)); - cards.add(new SetCardInfo("Essence Bottle", 286, Rarity.UNCOMMON, mage.cards.e.EssenceBottle.class)); - cards.add(new SetCardInfo("Evincar's Justice", 134, Rarity.COMMON, mage.cards.e.EvincarsJustice.class)); - cards.add(new SetCardInfo("Excavator", 287, Rarity.UNCOMMON, mage.cards.e.Excavator.class)); - cards.add(new SetCardInfo("Extinction", 135, Rarity.RARE, mage.cards.e.Extinction.class)); - cards.add(new SetCardInfo("Fevered Convulsions", 136, Rarity.RARE, mage.cards.f.FeveredConvulsions.class)); - cards.add(new SetCardInfo("Field of Souls", 18, Rarity.RARE, mage.cards.f.FieldOfSouls.class)); - cards.add(new SetCardInfo("Fighting Drake", 63, Rarity.UNCOMMON, mage.cards.f.FightingDrake.class)); - cards.add(new SetCardInfo("Firefly", 172, Rarity.UNCOMMON, mage.cards.f.Firefly.class)); - cards.add(new SetCardInfo("Fireslinger", 173, Rarity.COMMON, mage.cards.f.Fireslinger.class)); - cards.add(new SetCardInfo("Flailing Drake", 227, Rarity.UNCOMMON, mage.cards.f.FlailingDrake.class)); - cards.add(new SetCardInfo("Flickering Ward", 19, Rarity.UNCOMMON, mage.cards.f.FlickeringWard.class)); - cards.add(new SetCardInfo("Flowstone Giant", 174, Rarity.COMMON, mage.cards.f.FlowstoneGiant.class)); - cards.add(new SetCardInfo("Flowstone Salamander", 175, Rarity.UNCOMMON, mage.cards.f.FlowstoneSalamander.class)); - cards.add(new SetCardInfo("Flowstone Sculpture", 288, Rarity.RARE, mage.cards.f.FlowstoneSculpture.class)); - cards.add(new SetCardInfo("Flowstone Wyvern", 176, Rarity.RARE, mage.cards.f.FlowstoneWyvern.class)); - cards.add(new SetCardInfo("Fool's Tome", 289, Rarity.RARE, mage.cards.f.FoolsTome.class)); - cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Frog Tongue", 228, Rarity.COMMON, mage.cards.f.FrogTongue.class)); - cards.add(new SetCardInfo("Fugitive Druid", 229, Rarity.RARE, mage.cards.f.FugitiveDruid.class)); - cards.add(new SetCardInfo("Furnace of Rath", 177, Rarity.RARE, mage.cards.f.FurnaceOfRath.class)); - cards.add(new SetCardInfo("Fylamarid", 64, Rarity.UNCOMMON, mage.cards.f.Fylamarid.class)); - cards.add(new SetCardInfo("Gallantry", 20, Rarity.UNCOMMON, mage.cards.g.Gallantry.class)); - cards.add(new SetCardInfo("Gaseous Form", 65, Rarity.COMMON, mage.cards.g.GaseousForm.class)); - cards.add(new SetCardInfo("Gerrard's Battle Cry", 21, Rarity.RARE, mage.cards.g.GerrardsBattleCry.class)); - cards.add(new SetCardInfo("Ghost Town", 318, Rarity.UNCOMMON, mage.cards.g.GhostTown.class)); - cards.add(new SetCardInfo("Giant Crab", 66, Rarity.COMMON, mage.cards.g.GiantCrab.class)); - cards.add(new SetCardInfo("Giant Strength", 178, Rarity.COMMON, mage.cards.g.GiantStrength.class)); - cards.add(new SetCardInfo("Goblin Bombardment", 179, Rarity.UNCOMMON, mage.cards.g.GoblinBombardment.class)); - cards.add(new SetCardInfo("Gravedigger", 137, Rarity.COMMON, mage.cards.g.Gravedigger.class)); - cards.add(new SetCardInfo("Grindstone", 290, Rarity.RARE, mage.cards.g.Grindstone.class)); - cards.add(new SetCardInfo("Hand to Hand", 180, Rarity.RARE, mage.cards.h.HandToHand.class)); - cards.add(new SetCardInfo("Hanna's Custody", 22, Rarity.RARE, mage.cards.h.HannasCustody.class)); - cards.add(new SetCardInfo("Harrow", 230, Rarity.UNCOMMON, mage.cards.h.Harrow.class)); - cards.add(new SetCardInfo("Havoc", 181, Rarity.UNCOMMON, mage.cards.h.Havoc.class)); - cards.add(new SetCardInfo("Heart Sliver", 182, Rarity.COMMON, mage.cards.h.HeartSliver.class)); - cards.add(new SetCardInfo("Heartwood Dryad", 231, Rarity.COMMON, mage.cards.h.HeartwoodDryad.class)); - cards.add(new SetCardInfo("Heartwood Giant", 232, Rarity.RARE, mage.cards.h.HeartwoodGiant.class)); - cards.add(new SetCardInfo("Heartwood Treefolk", 233, Rarity.UNCOMMON, mage.cards.h.HeartwoodTreefolk.class)); - cards.add(new SetCardInfo("Helm of Possession", 291, Rarity.RARE, mage.cards.h.HelmOfPossession.class)); - cards.add(new SetCardInfo("Hero's Resolve", 23, Rarity.COMMON, mage.cards.h.HerosResolve.class)); - cards.add(new SetCardInfo("Horned Sliver", 234, Rarity.UNCOMMON, mage.cards.h.HornedSliver.class)); - cards.add(new SetCardInfo("Horned Turtle", 67, Rarity.COMMON, mage.cards.h.HornedTurtle.class)); - cards.add(new SetCardInfo("Humility", 24, Rarity.RARE, mage.cards.h.Humility.class)); - cards.add(new SetCardInfo("Imps' Taunt", 138, Rarity.UNCOMMON, mage.cards.i.ImpsTaunt.class)); - cards.add(new SetCardInfo("Insight", 68, Rarity.UNCOMMON, mage.cards.i.Insight.class)); - cards.add(new SetCardInfo("Interdict", 69, Rarity.UNCOMMON, mage.cards.i.Interdict.class)); - cards.add(new SetCardInfo("Intuition", 70, Rarity.RARE, mage.cards.i.Intuition.class)); - cards.add(new SetCardInfo("Invulnerability", 25, Rarity.UNCOMMON, mage.cards.i.Invulnerability.class)); - cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Jackal Pup", 183, Rarity.UNCOMMON, mage.cards.j.JackalPup.class)); - cards.add(new SetCardInfo("Jet Medallion", 292, Rarity.RARE, mage.cards.j.JetMedallion.class)); - cards.add(new SetCardInfo("Jinxed Idol", 293, Rarity.RARE, mage.cards.j.JinxedIdol.class)); - cards.add(new SetCardInfo("Kezzerdrix", 139, Rarity.RARE, mage.cards.k.Kezzerdrix.class)); - cards.add(new SetCardInfo("Kindle", 184, Rarity.COMMON, mage.cards.k.Kindle.class)); - cards.add(new SetCardInfo("Knight of Dawn", 26, Rarity.UNCOMMON, mage.cards.k.KnightOfDawn.class)); - cards.add(new SetCardInfo("Knight of Dusk", 140, Rarity.UNCOMMON, mage.cards.k.KnightOfDusk.class)); - cards.add(new SetCardInfo("Krakilin", 235, Rarity.UNCOMMON, mage.cards.k.Krakilin.class)); - cards.add(new SetCardInfo("Leeching Licid", 141, Rarity.UNCOMMON, mage.cards.l.LeechingLicid.class)); - cards.add(new SetCardInfo("Legacy's Allure", 71, Rarity.UNCOMMON, mage.cards.l.LegacysAllure.class)); - cards.add(new SetCardInfo("Legerdemain", 72, Rarity.UNCOMMON, mage.cards.l.Legerdemain.class)); - cards.add(new SetCardInfo("Light of Day", 27, Rarity.UNCOMMON, mage.cards.l.LightOfDay.class)); - cards.add(new SetCardInfo("Lightning Blast", 185, Rarity.COMMON, mage.cards.l.LightningBlast.class)); - cards.add(new SetCardInfo("Lightning Elemental", 186, Rarity.COMMON, mage.cards.l.LightningElemental.class)); - cards.add(new SetCardInfo("Living Death", 142, Rarity.RARE, mage.cards.l.LivingDeath.class)); - cards.add(new SetCardInfo("Lobotomy", 267, Rarity.UNCOMMON, mage.cards.l.Lobotomy.class)); - cards.add(new SetCardInfo("Lotus Petal", 294, Rarity.COMMON, mage.cards.l.LotusPetal.class)); - cards.add(new SetCardInfo("Lowland Giant", 187, Rarity.COMMON, mage.cards.l.LowlandGiant.class)); - cards.add(new SetCardInfo("Maddening Imp", 143, Rarity.RARE, mage.cards.m.MaddeningImp.class)); - cards.add(new SetCardInfo("Magmasaur", 188, Rarity.RARE, mage.cards.m.Magmasaur.class)); - cards.add(new SetCardInfo("Mana Severance", 73, Rarity.RARE, mage.cards.m.ManaSeverance.class)); - cards.add(new SetCardInfo("Manakin", 296, Rarity.COMMON, mage.cards.m.Manakin.class)); - cards.add(new SetCardInfo("Manta Riders", 74, Rarity.COMMON, mage.cards.m.MantaRiders.class)); - cards.add(new SetCardInfo("Marble Titan", 28, Rarity.RARE, mage.cards.m.MarbleTitan.class)); - cards.add(new SetCardInfo("Marsh Lurker", 144, Rarity.COMMON, mage.cards.m.MarshLurker.class)); - cards.add(new SetCardInfo("Master Decoy", 29, Rarity.COMMON, mage.cards.m.MasterDecoy.class)); - cards.add(new SetCardInfo("Mawcor", 75, Rarity.RARE, mage.cards.m.Mawcor.class)); - cards.add(new SetCardInfo("Maze of Shadows", 319, Rarity.UNCOMMON, mage.cards.m.MazeOfShadows.class)); - cards.add(new SetCardInfo("Meditate", 76, Rarity.RARE, mage.cards.m.Meditate.class)); - cards.add(new SetCardInfo("Metallic Sliver", 297, Rarity.COMMON, mage.cards.m.MetallicSliver.class)); - cards.add(new SetCardInfo("Mindwhip Sliver", 145, Rarity.UNCOMMON, mage.cards.m.MindwhipSliver.class)); - cards.add(new SetCardInfo("Minion of the Wastes", 146, Rarity.RARE, mage.cards.m.MinionOfTheWastes.class)); - cards.add(new SetCardInfo("Mirri's Guile", 236, Rarity.RARE, mage.cards.m.MirrisGuile.class)); - cards.add(new SetCardInfo("Mnemonic Sliver", 77, Rarity.UNCOMMON, mage.cards.m.MnemonicSliver.class)); - cards.add(new SetCardInfo("Mogg Cannon", 298, Rarity.UNCOMMON, mage.cards.m.MoggCannon.class)); - cards.add(new SetCardInfo("Mogg Conscripts", 189, Rarity.COMMON, mage.cards.m.MoggConscripts.class)); - cards.add(new SetCardInfo("Mogg Fanatic", 190, Rarity.COMMON, mage.cards.m.MoggFanatic.class)); - cards.add(new SetCardInfo("Mogg Hollows", 320, Rarity.UNCOMMON, mage.cards.m.MoggHollows.class)); - cards.add(new SetCardInfo("Mogg Raider", 191, Rarity.COMMON, mage.cards.m.MoggRaider.class)); - cards.add(new SetCardInfo("Mogg Squad", 192, Rarity.UNCOMMON, mage.cards.m.MoggSquad.class)); - cards.add(new SetCardInfo("Mongrel Pack", 237, Rarity.RARE, mage.cards.m.MongrelPack.class)); - cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mounted Archers", 30, Rarity.COMMON, mage.cards.m.MountedArchers.class)); - cards.add(new SetCardInfo("Muscle Sliver", 238, Rarity.COMMON, mage.cards.m.MuscleSliver.class)); - cards.add(new SetCardInfo("Natural Spring", 239, Rarity.COMMON, mage.cards.n.NaturalSpring.class)); - cards.add(new SetCardInfo("Nature's Revolt", 240, Rarity.RARE, mage.cards.n.NaturesRevolt.class)); - cards.add(new SetCardInfo("Needle Storm", 241, Rarity.UNCOMMON, mage.cards.n.NeedleStorm.class)); - cards.add(new SetCardInfo("Nurturing Licid", 242, Rarity.UNCOMMON, mage.cards.n.NurturingLicid.class)); - cards.add(new SetCardInfo("Opportunist", 194, Rarity.UNCOMMON, mage.cards.o.Opportunist.class)); - cards.add(new SetCardInfo("Oracle en-Vec", 31, Rarity.RARE, mage.cards.o.OracleEnVec.class)); - cards.add(new SetCardInfo("Orim's Prayer", 32, Rarity.UNCOMMON, mage.cards.o.OrimsPrayer.class)); - cards.add(new SetCardInfo("Orim, Samite Healer", 33, Rarity.RARE, mage.cards.o.OrimSamiteHealer.class)); - cards.add(new SetCardInfo("Overrun", 243, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); - cards.add(new SetCardInfo("Pacifism", 34, Rarity.COMMON, mage.cards.p.Pacifism.class)); - cards.add(new SetCardInfo("Pallimud", 195, Rarity.RARE, mage.cards.p.Pallimud.class)); - cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.UNCOMMON, mage.cards.p.PatchworkGnomes.class)); - cards.add(new SetCardInfo("Pearl Medallion", 300, Rarity.RARE, mage.cards.p.PearlMedallion.class)); - cards.add(new SetCardInfo("Pegasus Refuge", 35, Rarity.RARE, mage.cards.p.PegasusRefuge.class)); - cards.add(new SetCardInfo("Perish", 147, Rarity.UNCOMMON, mage.cards.p.Perish.class)); - cards.add(new SetCardInfo("Phyrexian Grimoire", 301, Rarity.RARE, mage.cards.p.PhyrexianGrimoire.class)); - cards.add(new SetCardInfo("Phyrexian Hulk", 302, Rarity.UNCOMMON, mage.cards.p.PhyrexianHulk.class)); - cards.add(new SetCardInfo("Pincher Beetles", 244, Rarity.COMMON, mage.cards.p.PincherBeetles.class)); - cards.add(new SetCardInfo("Pine Barrens", 321, Rarity.RARE, mage.cards.p.PineBarrens.class)); - cards.add(new SetCardInfo("Pit Imp", 148, Rarity.COMMON, mage.cards.p.PitImp.class)); - cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Power Sink", 78, Rarity.COMMON, mage.cards.p.PowerSink.class)); - cards.add(new SetCardInfo("Precognition", 79, Rarity.RARE, mage.cards.p.Precognition.class)); - cards.add(new SetCardInfo("Propaganda", 80, Rarity.UNCOMMON, mage.cards.p.Propaganda.class)); - cards.add(new SetCardInfo("Puppet Strings", 304, Rarity.UNCOMMON, mage.cards.p.PuppetStrings.class)); - cards.add(new SetCardInfo("Quickening Licid", 36, Rarity.UNCOMMON, mage.cards.q.QuickeningLicid.class)); - cards.add(new SetCardInfo("Rain of Tears", 149, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); - cards.add(new SetCardInfo("Rampant Growth", 245, Rarity.COMMON, mage.cards.r.RampantGrowth.class)); - cards.add(new SetCardInfo("Ranger en-Vec", 268, Rarity.UNCOMMON, mage.cards.r.RangerEnVec.class)); - cards.add(new SetCardInfo("Rathi Dragon", 196, Rarity.RARE, mage.cards.r.RathiDragon.class)); - cards.add(new SetCardInfo("Rats of Rath", 150, Rarity.COMMON, mage.cards.r.RatsOfRath.class)); - cards.add(new SetCardInfo("Reality Anchor", 246, Rarity.COMMON, mage.cards.r.RealityAnchor.class)); - cards.add(new SetCardInfo("Reanimate", 151, Rarity.UNCOMMON, mage.cards.r.Reanimate.class)); - cards.add(new SetCardInfo("Reap", 247, Rarity.UNCOMMON, mage.cards.r.Reap.class)); - cards.add(new SetCardInfo("Reckless Spite", 152, Rarity.UNCOMMON, mage.cards.r.RecklessSpite.class)); - cards.add(new SetCardInfo("Recycle", 248, Rarity.RARE, mage.cards.r.Recycle.class)); - cards.add(new SetCardInfo("Reflecting Pool", 322, Rarity.RARE, mage.cards.r.ReflectingPool.class)); - cards.add(new SetCardInfo("Renegade Warlord", 197, Rarity.UNCOMMON, mage.cards.r.RenegadeWarlord.class)); - cards.add(new SetCardInfo("Repentance", 37, Rarity.UNCOMMON, mage.cards.r.Repentance.class)); - cards.add(new SetCardInfo("Respite", 249, Rarity.COMMON, mage.cards.r.Respite.class)); - cards.add(new SetCardInfo("Rolling Thunder", 198, Rarity.COMMON, mage.cards.r.RollingThunder.class)); - cards.add(new SetCardInfo("Root Maze", 250, Rarity.RARE, mage.cards.r.RootMaze.class)); - cards.add(new SetCardInfo("Rootbreaker Wurm", 251, Rarity.COMMON, mage.cards.r.RootbreakerWurm.class)); - cards.add(new SetCardInfo("Rootwalla", 252, Rarity.COMMON, mage.cards.r.Rootwalla.class)); - cards.add(new SetCardInfo("Rootwater Depths", 323, Rarity.UNCOMMON, mage.cards.r.RootwaterDepths.class)); - cards.add(new SetCardInfo("Rootwater Diver", 81, Rarity.UNCOMMON, mage.cards.r.RootwaterDiver.class)); - cards.add(new SetCardInfo("Rootwater Hunter", 82, Rarity.COMMON, mage.cards.r.RootwaterHunter.class)); - cards.add(new SetCardInfo("Rootwater Matriarch", 83, Rarity.RARE, mage.cards.r.RootwaterMatriarch.class)); - cards.add(new SetCardInfo("Rootwater Shaman", 84, Rarity.RARE, mage.cards.r.RootwaterShaman.class)); - cards.add(new SetCardInfo("Ruby Medallion", 305, Rarity.RARE, mage.cards.r.RubyMedallion.class)); - cards.add(new SetCardInfo("Sacred Guide", 38, Rarity.RARE, mage.cards.s.SacredGuide.class)); - cards.add(new SetCardInfo("Sadistic Glee", 153, Rarity.COMMON, mage.cards.s.SadisticGlee.class)); - cards.add(new SetCardInfo("Safeguard", 39, Rarity.RARE, mage.cards.s.Safeguard.class)); - cards.add(new SetCardInfo("Salt Flats", 324, Rarity.RARE, mage.cards.s.SaltFlats.class)); - cards.add(new SetCardInfo("Sandstone Warrior", 199, Rarity.COMMON, mage.cards.s.SandstoneWarrior.class)); - cards.add(new SetCardInfo("Sapphire Medallion", 306, Rarity.RARE, mage.cards.s.SapphireMedallion.class)); - cards.add(new SetCardInfo("Sarcomancy", 154, Rarity.RARE, mage.cards.s.Sarcomancy.class)); - cards.add(new SetCardInfo("Scabland", 325, Rarity.RARE, mage.cards.s.Scabland.class)); - cards.add(new SetCardInfo("Scalding Tongs", 307, Rarity.RARE, mage.cards.s.ScaldingTongs.class)); - cards.add(new SetCardInfo("Scorched Earth", 200, Rarity.RARE, mage.cards.s.ScorchedEarth.class)); - cards.add(new SetCardInfo("Scragnoth", 253, Rarity.UNCOMMON, mage.cards.s.Scragnoth.class)); - cards.add(new SetCardInfo("Screeching Harpy", 155, Rarity.UNCOMMON, mage.cards.s.ScreechingHarpy.class)); - cards.add(new SetCardInfo("Scroll Rack", 308, Rarity.RARE, mage.cards.s.ScrollRack.class)); - cards.add(new SetCardInfo("Sea Monster", 85, Rarity.COMMON, mage.cards.s.SeaMonster.class)); - cards.add(new SetCardInfo("Searing Touch", 201, Rarity.UNCOMMON, mage.cards.s.SearingTouch.class)); - cards.add(new SetCardInfo("Seeker of Skybreak", 254, Rarity.COMMON, mage.cards.s.SeekerOfSkybreak.class)); - cards.add(new SetCardInfo("Segmented Wurm", 269, Rarity.UNCOMMON, mage.cards.s.SegmentedWurm.class)); - cards.add(new SetCardInfo("Selenia, Dark Angel", 270, Rarity.RARE, mage.cards.s.SeleniaDarkAngel.class)); - cards.add(new SetCardInfo("Serene Offering", 40, Rarity.UNCOMMON, mage.cards.s.SereneOffering.class)); - cards.add(new SetCardInfo("Servant of Volrath", 156, Rarity.COMMON, mage.cards.s.ServantOfVolrath.class)); - cards.add(new SetCardInfo("Shadow Rift", 86, Rarity.COMMON, mage.cards.s.ShadowRift.class)); - cards.add(new SetCardInfo("Shadowstorm", 202, Rarity.UNCOMMON, mage.cards.s.Shadowstorm.class)); - cards.add(new SetCardInfo("Shatter", 203, Rarity.COMMON, mage.cards.s.Shatter.class)); - cards.add(new SetCardInfo("Shimmering Wings", 87, Rarity.COMMON, mage.cards.s.ShimmeringWings.class)); - cards.add(new SetCardInfo("Shocker", 204, Rarity.RARE, mage.cards.s.Shocker.class)); - cards.add(new SetCardInfo("Sky Spirit", 271, Rarity.UNCOMMON, mage.cards.s.SkySpirit.class)); - cards.add(new SetCardInfo("Skyshroud Condor", 88, Rarity.UNCOMMON, mage.cards.s.SkyshroudCondor.class)); - cards.add(new SetCardInfo("Skyshroud Elf", 255, Rarity.COMMON, mage.cards.s.SkyshroudElf.class)); - cards.add(new SetCardInfo("Skyshroud Forest", 326, Rarity.RARE, mage.cards.s.SkyshroudForest.class)); - cards.add(new SetCardInfo("Skyshroud Ranger", 256, Rarity.COMMON, mage.cards.s.SkyshroudRanger.class)); - cards.add(new SetCardInfo("Skyshroud Troll", 257, Rarity.COMMON, mage.cards.s.SkyshroudTroll.class)); - cards.add(new SetCardInfo("Skyshroud Vampire", 157, Rarity.UNCOMMON, mage.cards.s.SkyshroudVampire.class)); - cards.add(new SetCardInfo("Soltari Crusader", 41, Rarity.UNCOMMON, mage.cards.s.SoltariCrusader.class)); - cards.add(new SetCardInfo("Soltari Emissary", 42, Rarity.RARE, mage.cards.s.SoltariEmissary.class)); - cards.add(new SetCardInfo("Soltari Foot Soldier", 43, Rarity.COMMON, mage.cards.s.SoltariFootSoldier.class)); - cards.add(new SetCardInfo("Soltari Guerrillas", 272, Rarity.RARE, mage.cards.s.SoltariGuerrillas.class)); - cards.add(new SetCardInfo("Soltari Lancer", 44, Rarity.COMMON, mage.cards.s.SoltariLancer.class)); - cards.add(new SetCardInfo("Soltari Monk", 45, Rarity.UNCOMMON, mage.cards.s.SoltariMonk.class)); - cards.add(new SetCardInfo("Soltari Priest", 46, Rarity.UNCOMMON, mage.cards.s.SoltariPriest.class)); - cards.add(new SetCardInfo("Soltari Trooper", 47, Rarity.COMMON, mage.cards.s.SoltariTrooper.class)); - cards.add(new SetCardInfo("Souldrinker", 158, Rarity.UNCOMMON, mage.cards.s.Souldrinker.class)); - cards.add(new SetCardInfo("Spell Blast", 89, Rarity.COMMON, mage.cards.s.SpellBlast.class)); - cards.add(new SetCardInfo("Spike Drone", 258, Rarity.COMMON, mage.cards.s.SpikeDrone.class)); - cards.add(new SetCardInfo("Spinal Graft", 159, Rarity.COMMON, mage.cards.s.SpinalGraft.class)); - cards.add(new SetCardInfo("Spirit Mirror", 48, Rarity.RARE, mage.cards.s.SpiritMirror.class)); - cards.add(new SetCardInfo("Spontaneous Combustion", 273, Rarity.UNCOMMON, mage.cards.s.SpontaneousCombustion.class)); - cards.add(new SetCardInfo("Squee's Toy", 309, Rarity.COMMON, mage.cards.s.SqueesToy.class)); - cards.add(new SetCardInfo("Stalking Stones", 327, Rarity.UNCOMMON, mage.cards.s.StalkingStones.class)); - cards.add(new SetCardInfo("Starke of Rath", 205, Rarity.RARE, mage.cards.s.StarkeOfRath.class)); - cards.add(new SetCardInfo("Static Orb", 310, Rarity.RARE, mage.cards.s.StaticOrb.class)); - cards.add(new SetCardInfo("Staunch Defenders", 49, Rarity.UNCOMMON, mage.cards.s.StaunchDefenders.class)); - cards.add(new SetCardInfo("Steal Enchantment", 90, Rarity.UNCOMMON, mage.cards.s.StealEnchantment.class)); - cards.add(new SetCardInfo("Stinging Licid", 91, Rarity.UNCOMMON, mage.cards.s.StingingLicid.class)); - cards.add(new SetCardInfo("Stone Rain", 206, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Storm Front", 259, Rarity.UNCOMMON, mage.cards.s.StormFront.class)); - cards.add(new SetCardInfo("Stun", 207, Rarity.COMMON, mage.cards.s.Stun.class)); - cards.add(new SetCardInfo("Sudden Impact", 208, Rarity.UNCOMMON, mage.cards.s.SuddenImpact.class)); - cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tahngarth's Rage", 209, Rarity.UNCOMMON, mage.cards.t.TahngarthsRage.class)); - cards.add(new SetCardInfo("Talon Sliver", 50, Rarity.COMMON, mage.cards.t.TalonSliver.class)); - cards.add(new SetCardInfo("Telethopter", 311, Rarity.UNCOMMON, mage.cards.t.Telethopter.class)); - cards.add(new SetCardInfo("Thalakos Dreamsower", 92, Rarity.UNCOMMON, mage.cards.t.ThalakosDreamsower.class)); - cards.add(new SetCardInfo("Thalakos Lowlands", 328, Rarity.UNCOMMON, mage.cards.t.ThalakosLowlands.class)); - cards.add(new SetCardInfo("Thalakos Mistfolk", 93, Rarity.COMMON, mage.cards.t.ThalakosMistfolk.class)); - cards.add(new SetCardInfo("Thalakos Seer", 94, Rarity.COMMON, mage.cards.t.ThalakosSeer.class)); - cards.add(new SetCardInfo("Thalakos Sentry", 95, Rarity.COMMON, mage.cards.t.ThalakosSentry.class)); - cards.add(new SetCardInfo("Thumbscrews", 312, Rarity.RARE, mage.cards.t.Thumbscrews.class)); - cards.add(new SetCardInfo("Time Ebb", 96, Rarity.COMMON, mage.cards.t.TimeEbb.class)); - cards.add(new SetCardInfo("Time Warp", 97, Rarity.RARE, mage.cards.t.TimeWarp.class)); - cards.add(new SetCardInfo("Tooth and Claw", 210, Rarity.RARE, mage.cards.t.ToothAndClaw.class)); - cards.add(new SetCardInfo("Torture Chamber", 313, Rarity.RARE, mage.cards.t.TortureChamber.class)); - cards.add(new SetCardInfo("Tradewind Rider", 98, Rarity.RARE, mage.cards.t.TradewindRider.class)); - cards.add(new SetCardInfo("Trained Armodon", 260, Rarity.COMMON, mage.cards.t.TrainedArmodon.class)); - cards.add(new SetCardInfo("Tranquility", 261, Rarity.COMMON, mage.cards.t.Tranquility.class)); - cards.add(new SetCardInfo("Trumpeting Armodon", 262, Rarity.UNCOMMON, mage.cards.t.TrumpetingArmodon.class)); - cards.add(new SetCardInfo("Twitch", 99, Rarity.COMMON, mage.cards.t.Twitch.class)); - cards.add(new SetCardInfo("Unstable Shapeshifter", 100, Rarity.RARE, mage.cards.u.UnstableShapeshifter.class)); - cards.add(new SetCardInfo("Vec Townships", 329, Rarity.UNCOMMON, mage.cards.v.VecTownships.class)); - cards.add(new SetCardInfo("Verdant Force", 263, Rarity.RARE, mage.cards.v.VerdantForce.class)); - cards.add(new SetCardInfo("Verdigris", 264, Rarity.UNCOMMON, mage.cards.v.Verdigris.class)); - cards.add(new SetCardInfo("Vhati il-Dal", 274, Rarity.RARE, mage.cards.v.VhatiIlDal.class)); - cards.add(new SetCardInfo("Volrath's Curse", 101, Rarity.COMMON, mage.cards.v.VolrathsCurse.class)); - cards.add(new SetCardInfo("Wall of Diffusion", 211, Rarity.COMMON, mage.cards.w.WallOfDiffusion.class)); - cards.add(new SetCardInfo("Warmth", 51, Rarity.UNCOMMON, mage.cards.w.Warmth.class)); - cards.add(new SetCardInfo("Wasteland", 330, Rarity.UNCOMMON, mage.cards.w.Wasteland.class)); - cards.add(new SetCardInfo("Watchdog", 314, Rarity.UNCOMMON, mage.cards.w.Watchdog.class)); - cards.add(new SetCardInfo("Whispers of the Muse", 103, Rarity.UNCOMMON, mage.cards.w.WhispersOfTheMuse.class)); - cards.add(new SetCardInfo("Wild Wurm", 212, Rarity.UNCOMMON, mage.cards.w.WildWurm.class)); - cards.add(new SetCardInfo("Wind Dancer", 104, Rarity.UNCOMMON, mage.cards.w.WindDancer.class)); - cards.add(new SetCardInfo("Wind Drake", 105, Rarity.COMMON, mage.cards.w.WindDrake.class)); - cards.add(new SetCardInfo("Winds of Rath", 52, Rarity.RARE, mage.cards.w.WindsOfRath.class)); - cards.add(new SetCardInfo("Winged Sliver", 106, Rarity.COMMON, mage.cards.w.WingedSliver.class)); - cards.add(new SetCardInfo("Winter's Grasp", 265, Rarity.UNCOMMON, mage.cards.w.WintersGrasp.class)); - cards.add(new SetCardInfo("Wood Sage", 275, Rarity.RARE, mage.cards.w.WoodSage.class)); - cards.add(new SetCardInfo("Worthy Cause", 53, Rarity.UNCOMMON, mage.cards.w.WorthyCause.class)); - } -} +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +public final class Tempest extends ExpansionSet { + + private static final Tempest instance = new Tempest(); + + public static Tempest getInstance() { + return instance; + } + + private Tempest() { + super("Tempest", "TMP", ExpansionSet.buildDate(1997, 10, 1), SetType.EXPANSION); + this.blockName = "Tempest"; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abandon Hope", 107, Rarity.UNCOMMON, mage.cards.a.AbandonHope.class)); + cards.add(new SetCardInfo("Advance Scout", 1, Rarity.COMMON, mage.cards.a.AdvanceScout.class)); + cards.add(new SetCardInfo("Aftershock", 160, Rarity.COMMON, mage.cards.a.Aftershock.class)); + cards.add(new SetCardInfo("Altar of Dementia", 276, Rarity.RARE, mage.cards.a.AltarOfDementia.class)); + cards.add(new SetCardInfo("Aluren", 213, Rarity.RARE, mage.cards.a.Aluren.class)); + cards.add(new SetCardInfo("Ancient Runes", 161, Rarity.UNCOMMON, mage.cards.a.AncientRunes.class)); + cards.add(new SetCardInfo("Ancient Tomb", 315, Rarity.UNCOMMON, mage.cards.a.AncientTomb.class)); + cards.add(new SetCardInfo("Angelic Protector", 2, Rarity.UNCOMMON, mage.cards.a.AngelicProtector.class)); + cards.add(new SetCardInfo("Anoint", 3, Rarity.COMMON, mage.cards.a.Anoint.class)); + cards.add(new SetCardInfo("Apes of Rath", 214, Rarity.UNCOMMON, mage.cards.a.ApesOfRath.class)); + cards.add(new SetCardInfo("Apocalypse", 162, Rarity.RARE, mage.cards.a.Apocalypse.class)); + cards.add(new SetCardInfo("Armor Sliver", 4, Rarity.UNCOMMON, mage.cards.a.ArmorSliver.class)); + cards.add(new SetCardInfo("Armored Pegasus", 5, Rarity.COMMON, mage.cards.a.ArmoredPegasus.class)); + cards.add(new SetCardInfo("Auratog", 6, Rarity.RARE, mage.cards.a.Auratog.class)); + cards.add(new SetCardInfo("Avenging Angel", 7, Rarity.RARE, mage.cards.a.AvengingAngel.class)); + cards.add(new SetCardInfo("Barbed Sliver", 163, Rarity.UNCOMMON, mage.cards.b.BarbedSliver.class)); + cards.add(new SetCardInfo("Bayou Dragonfly", 215, Rarity.COMMON, mage.cards.b.BayouDragonfly.class)); + cards.add(new SetCardInfo("Bellowing Fiend", 108, Rarity.RARE, mage.cards.b.BellowingFiend.class)); + cards.add(new SetCardInfo("Benthic Behemoth", 54, Rarity.RARE, mage.cards.b.BenthicBehemoth.class)); + cards.add(new SetCardInfo("Blood Frenzy", 164, Rarity.COMMON, mage.cards.b.BloodFrenzy.class)); + cards.add(new SetCardInfo("Blood Pet", 109, Rarity.COMMON, mage.cards.b.BloodPet.class)); + cards.add(new SetCardInfo("Boil", 165, Rarity.UNCOMMON, mage.cards.b.Boil.class)); + cards.add(new SetCardInfo("Booby Trap", 277, Rarity.RARE, mage.cards.b.BoobyTrap.class)); + cards.add(new SetCardInfo("Bottle Gnomes", 278, Rarity.UNCOMMON, mage.cards.b.BottleGnomes.class)); + cards.add(new SetCardInfo("Bounty Hunter", 110, Rarity.RARE, mage.cards.b.BountyHunter.class)); + cards.add(new SetCardInfo("Broken Fall", 216, Rarity.COMMON, mage.cards.b.BrokenFall.class)); + cards.add(new SetCardInfo("Caldera Lake", 316, Rarity.RARE, mage.cards.c.CalderaLake.class)); + cards.add(new SetCardInfo("Canopy Spider", 217, Rarity.COMMON, mage.cards.c.CanopySpider.class)); + cards.add(new SetCardInfo("Canyon Drake", 166, Rarity.RARE, mage.cards.c.CanyonDrake.class)); + cards.add(new SetCardInfo("Canyon Wildcat", 167, Rarity.COMMON, mage.cards.c.CanyonWildcat.class)); + cards.add(new SetCardInfo("Capsize", 55, Rarity.COMMON, mage.cards.c.Capsize.class)); + cards.add(new SetCardInfo("Carrionette", 111, Rarity.RARE, mage.cards.c.Carrionette.class)); + cards.add(new SetCardInfo("Chaotic Goo", 168, Rarity.RARE, mage.cards.c.ChaoticGoo.class)); + cards.add(new SetCardInfo("Charging Rhino", 218, Rarity.UNCOMMON, mage.cards.c.ChargingRhino.class)); + cards.add(new SetCardInfo("Chill", 56, Rarity.UNCOMMON, mage.cards.c.Chill.class)); + cards.add(new SetCardInfo("Choke", 219, Rarity.UNCOMMON, mage.cards.c.Choke.class)); + cards.add(new SetCardInfo("Cinder Marsh", 317, Rarity.UNCOMMON, mage.cards.c.CinderMarsh.class)); + cards.add(new SetCardInfo("Circle of Protection: Black", 8, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class)); + cards.add(new SetCardInfo("Circle of Protection: Blue", 9, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlue.class)); + cards.add(new SetCardInfo("Circle of Protection: Green", 10, Rarity.COMMON, mage.cards.c.CircleOfProtectionGreen.class)); + cards.add(new SetCardInfo("Circle of Protection: Red", 11, Rarity.COMMON, mage.cards.c.CircleOfProtectionRed.class)); + cards.add(new SetCardInfo("Circle of Protection: Shadow", 12, Rarity.COMMON, mage.cards.c.CircleOfProtectionShadow.class)); + cards.add(new SetCardInfo("Circle of Protection: White", 13, Rarity.COMMON, mage.cards.c.CircleOfProtectionWhite.class)); + cards.add(new SetCardInfo("Clergy en-Vec", 14, Rarity.COMMON, mage.cards.c.ClergyEnVec.class)); + cards.add(new SetCardInfo("Clot Sliver", 112, Rarity.COMMON, mage.cards.c.ClotSliver.class)); + cards.add(new SetCardInfo("Cloudchaser Eagle", 15, Rarity.COMMON, mage.cards.c.CloudchaserEagle.class)); + cards.add(new SetCardInfo("Coercion", 113, Rarity.COMMON, mage.cards.c.Coercion.class)); + cards.add(new SetCardInfo("Coffin Queen", 114, Rarity.RARE, mage.cards.c.CoffinQueen.class)); + cards.add(new SetCardInfo("Coiled Tinviper", 279, Rarity.COMMON, mage.cards.c.CoiledTinviper.class)); + cards.add(new SetCardInfo("Cold Storage", 280, Rarity.RARE, mage.cards.c.ColdStorage.class)); + cards.add(new SetCardInfo("Commander Greven il-Vec", 115, Rarity.RARE, mage.cards.c.CommanderGrevenIlVec.class)); + cards.add(new SetCardInfo("Corpse Dance", 116, Rarity.RARE, mage.cards.c.CorpseDance.class)); + cards.add(new SetCardInfo("Counterspell", 57, Rarity.COMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Crazed Armodon", 220, Rarity.RARE, mage.cards.c.CrazedArmodon.class)); + cards.add(new SetCardInfo("Crown of Flames", 169, Rarity.COMMON, mage.cards.c.CrownOfFlames.class)); + cards.add(new SetCardInfo("Cursed Scroll", 281, Rarity.RARE, mage.cards.c.CursedScroll.class)); + cards.add(new SetCardInfo("Dark Banishing", 117, Rarity.COMMON, mage.cards.d.DarkBanishing.class)); + cards.add(new SetCardInfo("Dark Ritual", 118, Rarity.COMMON, mage.cards.d.DarkRitual.class)); + cards.add(new SetCardInfo("Darkling Stalker", 119, Rarity.COMMON, mage.cards.d.DarklingStalker.class)); + cards.add(new SetCardInfo("Dauthi Embrace", 120, Rarity.UNCOMMON, mage.cards.d.DauthiEmbrace.class)); + cards.add(new SetCardInfo("Dauthi Ghoul", 121, Rarity.UNCOMMON, mage.cards.d.DauthiGhoul.class)); + cards.add(new SetCardInfo("Dauthi Horror", 122, Rarity.COMMON, mage.cards.d.DauthiHorror.class)); + cards.add(new SetCardInfo("Dauthi Marauder", 123, Rarity.COMMON, mage.cards.d.DauthiMarauder.class)); + cards.add(new SetCardInfo("Dauthi Mercenary", 124, Rarity.UNCOMMON, mage.cards.d.DauthiMercenary.class)); + cards.add(new SetCardInfo("Dauthi Mindripper", 125, Rarity.UNCOMMON, mage.cards.d.DauthiMindripper.class)); + cards.add(new SetCardInfo("Dauthi Slayer", 126, Rarity.COMMON, mage.cards.d.DauthiSlayer.class)); + cards.add(new SetCardInfo("Deadshot", 170, Rarity.RARE, mage.cards.d.Deadshot.class)); + cards.add(new SetCardInfo("Death Pits of Rath", 127, Rarity.RARE, mage.cards.d.DeathPitsOfRath.class)); + cards.add(new SetCardInfo("Diabolic Edict", 128, Rarity.COMMON, mage.cards.d.DiabolicEdict.class)); + cards.add(new SetCardInfo("Dirtcowl Wurm", 221, Rarity.RARE, mage.cards.d.DirtcowlWurm.class)); + cards.add(new SetCardInfo("Disenchant", 16, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Dismiss", 58, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); + cards.add(new SetCardInfo("Disturbed Burial", 129, Rarity.COMMON, mage.cards.d.DisturbedBurial.class)); + cards.add(new SetCardInfo("Dracoplasm", 266, Rarity.RARE, mage.cards.d.Dracoplasm.class)); + cards.add(new SetCardInfo("Dread of Night", 130, Rarity.UNCOMMON, mage.cards.d.DreadOfNight.class)); + cards.add(new SetCardInfo("Dream Cache", 59, Rarity.COMMON, mage.cards.d.DreamCache.class)); + cards.add(new SetCardInfo("Dregs of Sorrow", 131, Rarity.RARE, mage.cards.d.DregsOfSorrow.class)); + cards.add(new SetCardInfo("Duplicity", 60, Rarity.RARE, mage.cards.d.Duplicity.class)); + cards.add(new SetCardInfo("Earthcraft", 222, Rarity.RARE, mage.cards.e.Earthcraft.class)); + cards.add(new SetCardInfo("Echo Chamber", 282, Rarity.RARE, mage.cards.e.EchoChamber.class)); + cards.add(new SetCardInfo("Eladamri's Vineyard", 223, Rarity.RARE, mage.cards.e.EladamrisVineyard.class)); + cards.add(new SetCardInfo("Eladamri, Lord of Leaves", 224, Rarity.RARE, mage.cards.e.EladamriLordOfLeaves.class)); + cards.add(new SetCardInfo("Elite Javelineer", 17, Rarity.COMMON, mage.cards.e.EliteJavelineer.class)); + cards.add(new SetCardInfo("Elven Warhounds", 225, Rarity.RARE, mage.cards.e.ElvenWarhounds.class)); + cards.add(new SetCardInfo("Elvish Fury", 226, Rarity.COMMON, mage.cards.e.ElvishFury.class)); + cards.add(new SetCardInfo("Emerald Medallion", 283, Rarity.RARE, mage.cards.e.EmeraldMedallion.class)); + cards.add(new SetCardInfo("Emmessi Tome", 284, Rarity.RARE, mage.cards.e.EmmessiTome.class)); + cards.add(new SetCardInfo("Endless Scream", 132, Rarity.COMMON, mage.cards.e.EndlessScream.class)); + cards.add(new SetCardInfo("Energizer", 285, Rarity.RARE, mage.cards.e.Energizer.class)); + cards.add(new SetCardInfo("Enfeeblement", 133, Rarity.COMMON, mage.cards.e.Enfeeblement.class)); + cards.add(new SetCardInfo("Enraging Licid", 171, Rarity.UNCOMMON, mage.cards.e.EnragingLicid.class)); + cards.add(new SetCardInfo("Essence Bottle", 286, Rarity.UNCOMMON, mage.cards.e.EssenceBottle.class)); + cards.add(new SetCardInfo("Evincar's Justice", 134, Rarity.COMMON, mage.cards.e.EvincarsJustice.class)); + cards.add(new SetCardInfo("Excavator", 287, Rarity.UNCOMMON, mage.cards.e.Excavator.class)); + cards.add(new SetCardInfo("Extinction", 135, Rarity.RARE, mage.cards.e.Extinction.class)); + cards.add(new SetCardInfo("Fevered Convulsions", 136, Rarity.RARE, mage.cards.f.FeveredConvulsions.class)); + cards.add(new SetCardInfo("Field of Souls", 18, Rarity.RARE, mage.cards.f.FieldOfSouls.class)); + cards.add(new SetCardInfo("Fighting Drake", 63, Rarity.UNCOMMON, mage.cards.f.FightingDrake.class)); + cards.add(new SetCardInfo("Firefly", 172, Rarity.UNCOMMON, mage.cards.f.Firefly.class)); + cards.add(new SetCardInfo("Fireslinger", 173, Rarity.COMMON, mage.cards.f.Fireslinger.class)); + cards.add(new SetCardInfo("Flailing Drake", 227, Rarity.UNCOMMON, mage.cards.f.FlailingDrake.class)); + cards.add(new SetCardInfo("Flickering Ward", 19, Rarity.UNCOMMON, mage.cards.f.FlickeringWard.class)); + cards.add(new SetCardInfo("Flowstone Giant", 174, Rarity.COMMON, mage.cards.f.FlowstoneGiant.class)); + cards.add(new SetCardInfo("Flowstone Salamander", 175, Rarity.UNCOMMON, mage.cards.f.FlowstoneSalamander.class)); + cards.add(new SetCardInfo("Flowstone Sculpture", 288, Rarity.RARE, mage.cards.f.FlowstoneSculpture.class)); + cards.add(new SetCardInfo("Flowstone Wyvern", 176, Rarity.RARE, mage.cards.f.FlowstoneWyvern.class)); + cards.add(new SetCardInfo("Fool's Tome", 289, Rarity.RARE, mage.cards.f.FoolsTome.class)); + cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Frog Tongue", 228, Rarity.COMMON, mage.cards.f.FrogTongue.class)); + cards.add(new SetCardInfo("Fugitive Druid", 229, Rarity.RARE, mage.cards.f.FugitiveDruid.class)); + cards.add(new SetCardInfo("Furnace of Rath", 177, Rarity.RARE, mage.cards.f.FurnaceOfRath.class)); + cards.add(new SetCardInfo("Fylamarid", 64, Rarity.UNCOMMON, mage.cards.f.Fylamarid.class)); + cards.add(new SetCardInfo("Gallantry", 20, Rarity.UNCOMMON, mage.cards.g.Gallantry.class)); + cards.add(new SetCardInfo("Gaseous Form", 65, Rarity.COMMON, mage.cards.g.GaseousForm.class)); + cards.add(new SetCardInfo("Gerrard's Battle Cry", 21, Rarity.RARE, mage.cards.g.GerrardsBattleCry.class)); + cards.add(new SetCardInfo("Ghost Town", 318, Rarity.UNCOMMON, mage.cards.g.GhostTown.class)); + cards.add(new SetCardInfo("Giant Crab", 66, Rarity.COMMON, mage.cards.g.GiantCrab.class)); + cards.add(new SetCardInfo("Giant Strength", 178, Rarity.COMMON, mage.cards.g.GiantStrength.class)); + cards.add(new SetCardInfo("Goblin Bombardment", 179, Rarity.UNCOMMON, mage.cards.g.GoblinBombardment.class)); + cards.add(new SetCardInfo("Gravedigger", 137, Rarity.COMMON, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Grindstone", 290, Rarity.RARE, mage.cards.g.Grindstone.class)); + cards.add(new SetCardInfo("Hand to Hand", 180, Rarity.RARE, mage.cards.h.HandToHand.class)); + cards.add(new SetCardInfo("Hanna's Custody", 22, Rarity.RARE, mage.cards.h.HannasCustody.class)); + cards.add(new SetCardInfo("Harrow", 230, Rarity.UNCOMMON, mage.cards.h.Harrow.class)); + cards.add(new SetCardInfo("Havoc", 181, Rarity.UNCOMMON, mage.cards.h.Havoc.class)); + cards.add(new SetCardInfo("Heart Sliver", 182, Rarity.COMMON, mage.cards.h.HeartSliver.class)); + cards.add(new SetCardInfo("Heartwood Dryad", 231, Rarity.COMMON, mage.cards.h.HeartwoodDryad.class)); + cards.add(new SetCardInfo("Heartwood Giant", 232, Rarity.RARE, mage.cards.h.HeartwoodGiant.class)); + cards.add(new SetCardInfo("Heartwood Treefolk", 233, Rarity.UNCOMMON, mage.cards.h.HeartwoodTreefolk.class)); + cards.add(new SetCardInfo("Helm of Possession", 291, Rarity.RARE, mage.cards.h.HelmOfPossession.class)); + cards.add(new SetCardInfo("Hero's Resolve", 23, Rarity.COMMON, mage.cards.h.HerosResolve.class)); + cards.add(new SetCardInfo("Horned Sliver", 234, Rarity.UNCOMMON, mage.cards.h.HornedSliver.class)); + cards.add(new SetCardInfo("Horned Turtle", 67, Rarity.COMMON, mage.cards.h.HornedTurtle.class)); + cards.add(new SetCardInfo("Humility", 24, Rarity.RARE, mage.cards.h.Humility.class)); + cards.add(new SetCardInfo("Imps' Taunt", 138, Rarity.UNCOMMON, mage.cards.i.ImpsTaunt.class)); + cards.add(new SetCardInfo("Insight", 68, Rarity.UNCOMMON, mage.cards.i.Insight.class)); + cards.add(new SetCardInfo("Interdict", 69, Rarity.UNCOMMON, mage.cards.i.Interdict.class)); + cards.add(new SetCardInfo("Intuition", 70, Rarity.RARE, mage.cards.i.Intuition.class)); + cards.add(new SetCardInfo("Invulnerability", 25, Rarity.UNCOMMON, mage.cards.i.Invulnerability.class)); + cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jackal Pup", 183, Rarity.UNCOMMON, mage.cards.j.JackalPup.class)); + cards.add(new SetCardInfo("Jet Medallion", 292, Rarity.RARE, mage.cards.j.JetMedallion.class)); + cards.add(new SetCardInfo("Jinxed Idol", 293, Rarity.RARE, mage.cards.j.JinxedIdol.class)); + cards.add(new SetCardInfo("Kezzerdrix", 139, Rarity.RARE, mage.cards.k.Kezzerdrix.class)); + cards.add(new SetCardInfo("Kindle", 184, Rarity.COMMON, mage.cards.k.Kindle.class)); + cards.add(new SetCardInfo("Knight of Dawn", 26, Rarity.UNCOMMON, mage.cards.k.KnightOfDawn.class)); + cards.add(new SetCardInfo("Knight of Dusk", 140, Rarity.UNCOMMON, mage.cards.k.KnightOfDusk.class)); + cards.add(new SetCardInfo("Krakilin", 235, Rarity.UNCOMMON, mage.cards.k.Krakilin.class)); + cards.add(new SetCardInfo("Leeching Licid", 141, Rarity.UNCOMMON, mage.cards.l.LeechingLicid.class)); + cards.add(new SetCardInfo("Legacy's Allure", 71, Rarity.UNCOMMON, mage.cards.l.LegacysAllure.class)); + cards.add(new SetCardInfo("Legerdemain", 72, Rarity.UNCOMMON, mage.cards.l.Legerdemain.class)); + cards.add(new SetCardInfo("Light of Day", 27, Rarity.UNCOMMON, mage.cards.l.LightOfDay.class)); + cards.add(new SetCardInfo("Lightning Blast", 185, Rarity.COMMON, mage.cards.l.LightningBlast.class)); + cards.add(new SetCardInfo("Lightning Elemental", 186, Rarity.COMMON, mage.cards.l.LightningElemental.class)); + cards.add(new SetCardInfo("Living Death", 142, Rarity.RARE, mage.cards.l.LivingDeath.class)); + cards.add(new SetCardInfo("Lobotomy", 267, Rarity.UNCOMMON, mage.cards.l.Lobotomy.class)); + cards.add(new SetCardInfo("Lotus Petal", 294, Rarity.COMMON, mage.cards.l.LotusPetal.class)); + cards.add(new SetCardInfo("Lowland Giant", 187, Rarity.COMMON, mage.cards.l.LowlandGiant.class)); + cards.add(new SetCardInfo("Maddening Imp", 143, Rarity.RARE, mage.cards.m.MaddeningImp.class)); + cards.add(new SetCardInfo("Magmasaur", 188, Rarity.RARE, mage.cards.m.Magmasaur.class)); + cards.add(new SetCardInfo("Mana Severance", 73, Rarity.RARE, mage.cards.m.ManaSeverance.class)); + cards.add(new SetCardInfo("Manakin", 296, Rarity.COMMON, mage.cards.m.Manakin.class)); + cards.add(new SetCardInfo("Manta Riders", 74, Rarity.COMMON, mage.cards.m.MantaRiders.class)); + cards.add(new SetCardInfo("Marble Titan", 28, Rarity.RARE, mage.cards.m.MarbleTitan.class)); + cards.add(new SetCardInfo("Marsh Lurker", 144, Rarity.COMMON, mage.cards.m.MarshLurker.class)); + cards.add(new SetCardInfo("Master Decoy", 29, Rarity.COMMON, mage.cards.m.MasterDecoy.class)); + cards.add(new SetCardInfo("Mawcor", 75, Rarity.RARE, mage.cards.m.Mawcor.class)); + cards.add(new SetCardInfo("Maze of Shadows", 319, Rarity.UNCOMMON, mage.cards.m.MazeOfShadows.class)); + cards.add(new SetCardInfo("Meditate", 76, Rarity.RARE, mage.cards.m.Meditate.class)); + cards.add(new SetCardInfo("Metallic Sliver", 297, Rarity.COMMON, mage.cards.m.MetallicSliver.class)); + cards.add(new SetCardInfo("Mindwhip Sliver", 145, Rarity.UNCOMMON, mage.cards.m.MindwhipSliver.class)); + cards.add(new SetCardInfo("Minion of the Wastes", 146, Rarity.RARE, mage.cards.m.MinionOfTheWastes.class)); + cards.add(new SetCardInfo("Mirri's Guile", 236, Rarity.RARE, mage.cards.m.MirrisGuile.class)); + cards.add(new SetCardInfo("Mnemonic Sliver", 77, Rarity.UNCOMMON, mage.cards.m.MnemonicSliver.class)); + cards.add(new SetCardInfo("Mogg Cannon", 298, Rarity.UNCOMMON, mage.cards.m.MoggCannon.class)); + cards.add(new SetCardInfo("Mogg Conscripts", 189, Rarity.COMMON, mage.cards.m.MoggConscripts.class)); + cards.add(new SetCardInfo("Mogg Fanatic", 190, Rarity.COMMON, mage.cards.m.MoggFanatic.class)); + cards.add(new SetCardInfo("Mogg Hollows", 320, Rarity.UNCOMMON, mage.cards.m.MoggHollows.class)); + cards.add(new SetCardInfo("Mogg Raider", 191, Rarity.COMMON, mage.cards.m.MoggRaider.class)); + cards.add(new SetCardInfo("Mogg Squad", 192, Rarity.UNCOMMON, mage.cards.m.MoggSquad.class)); + cards.add(new SetCardInfo("Mongrel Pack", 237, Rarity.RARE, mage.cards.m.MongrelPack.class)); + cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mounted Archers", 30, Rarity.COMMON, mage.cards.m.MountedArchers.class)); + cards.add(new SetCardInfo("Muscle Sliver", 238, Rarity.COMMON, mage.cards.m.MuscleSliver.class)); + cards.add(new SetCardInfo("Natural Spring", 239, Rarity.COMMON, mage.cards.n.NaturalSpring.class)); + cards.add(new SetCardInfo("Nature's Revolt", 240, Rarity.RARE, mage.cards.n.NaturesRevolt.class)); + cards.add(new SetCardInfo("Needle Storm", 241, Rarity.UNCOMMON, mage.cards.n.NeedleStorm.class)); + cards.add(new SetCardInfo("Nurturing Licid", 242, Rarity.UNCOMMON, mage.cards.n.NurturingLicid.class)); + cards.add(new SetCardInfo("Opportunist", 194, Rarity.UNCOMMON, mage.cards.o.Opportunist.class)); + cards.add(new SetCardInfo("Oracle en-Vec", 31, Rarity.RARE, mage.cards.o.OracleEnVec.class)); + cards.add(new SetCardInfo("Orim's Prayer", 32, Rarity.UNCOMMON, mage.cards.o.OrimsPrayer.class)); + cards.add(new SetCardInfo("Orim, Samite Healer", 33, Rarity.RARE, mage.cards.o.OrimSamiteHealer.class)); + cards.add(new SetCardInfo("Overrun", 243, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); + cards.add(new SetCardInfo("Pacifism", 34, Rarity.COMMON, mage.cards.p.Pacifism.class)); + cards.add(new SetCardInfo("Pallimud", 195, Rarity.RARE, mage.cards.p.Pallimud.class)); + cards.add(new SetCardInfo("Patchwork Gnomes", 299, Rarity.UNCOMMON, mage.cards.p.PatchworkGnomes.class)); + cards.add(new SetCardInfo("Pearl Medallion", 300, Rarity.RARE, mage.cards.p.PearlMedallion.class)); + cards.add(new SetCardInfo("Pegasus Refuge", 35, Rarity.RARE, mage.cards.p.PegasusRefuge.class)); + cards.add(new SetCardInfo("Perish", 147, Rarity.UNCOMMON, mage.cards.p.Perish.class)); + cards.add(new SetCardInfo("Phyrexian Grimoire", 301, Rarity.RARE, mage.cards.p.PhyrexianGrimoire.class)); + cards.add(new SetCardInfo("Phyrexian Hulk", 302, Rarity.UNCOMMON, mage.cards.p.PhyrexianHulk.class)); + cards.add(new SetCardInfo("Pincher Beetles", 244, Rarity.COMMON, mage.cards.p.PincherBeetles.class)); + cards.add(new SetCardInfo("Pine Barrens", 321, Rarity.RARE, mage.cards.p.PineBarrens.class)); + cards.add(new SetCardInfo("Pit Imp", 148, Rarity.COMMON, mage.cards.p.PitImp.class)); + cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Power Sink", 78, Rarity.COMMON, mage.cards.p.PowerSink.class)); + cards.add(new SetCardInfo("Precognition", 79, Rarity.RARE, mage.cards.p.Precognition.class)); + cards.add(new SetCardInfo("Propaganda", 80, Rarity.UNCOMMON, mage.cards.p.Propaganda.class)); + cards.add(new SetCardInfo("Puppet Strings", 304, Rarity.UNCOMMON, mage.cards.p.PuppetStrings.class)); + cards.add(new SetCardInfo("Quickening Licid", 36, Rarity.UNCOMMON, mage.cards.q.QuickeningLicid.class)); + cards.add(new SetCardInfo("Rain of Tears", 149, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class)); + cards.add(new SetCardInfo("Rampant Growth", 245, Rarity.COMMON, mage.cards.r.RampantGrowth.class)); + cards.add(new SetCardInfo("Ranger en-Vec", 268, Rarity.UNCOMMON, mage.cards.r.RangerEnVec.class)); + cards.add(new SetCardInfo("Rathi Dragon", 196, Rarity.RARE, mage.cards.r.RathiDragon.class)); + cards.add(new SetCardInfo("Rats of Rath", 150, Rarity.COMMON, mage.cards.r.RatsOfRath.class)); + cards.add(new SetCardInfo("Reality Anchor", 246, Rarity.COMMON, mage.cards.r.RealityAnchor.class)); + cards.add(new SetCardInfo("Reanimate", 151, Rarity.UNCOMMON, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Reap", 247, Rarity.UNCOMMON, mage.cards.r.Reap.class)); + cards.add(new SetCardInfo("Reckless Spite", 152, Rarity.UNCOMMON, mage.cards.r.RecklessSpite.class)); + cards.add(new SetCardInfo("Recycle", 248, Rarity.RARE, mage.cards.r.Recycle.class)); + cards.add(new SetCardInfo("Reflecting Pool", 322, Rarity.RARE, mage.cards.r.ReflectingPool.class)); + cards.add(new SetCardInfo("Renegade Warlord", 197, Rarity.UNCOMMON, mage.cards.r.RenegadeWarlord.class)); + cards.add(new SetCardInfo("Repentance", 37, Rarity.UNCOMMON, mage.cards.r.Repentance.class)); + cards.add(new SetCardInfo("Respite", 249, Rarity.COMMON, mage.cards.r.Respite.class)); + cards.add(new SetCardInfo("Rolling Thunder", 198, Rarity.COMMON, mage.cards.r.RollingThunder.class)); + cards.add(new SetCardInfo("Root Maze", 250, Rarity.RARE, mage.cards.r.RootMaze.class)); + cards.add(new SetCardInfo("Rootbreaker Wurm", 251, Rarity.COMMON, mage.cards.r.RootbreakerWurm.class)); + cards.add(new SetCardInfo("Rootwalla", 252, Rarity.COMMON, mage.cards.r.Rootwalla.class)); + cards.add(new SetCardInfo("Rootwater Depths", 323, Rarity.UNCOMMON, mage.cards.r.RootwaterDepths.class)); + cards.add(new SetCardInfo("Rootwater Diver", 81, Rarity.UNCOMMON, mage.cards.r.RootwaterDiver.class)); + cards.add(new SetCardInfo("Rootwater Hunter", 82, Rarity.COMMON, mage.cards.r.RootwaterHunter.class)); + cards.add(new SetCardInfo("Rootwater Matriarch", 83, Rarity.RARE, mage.cards.r.RootwaterMatriarch.class)); + cards.add(new SetCardInfo("Rootwater Shaman", 84, Rarity.RARE, mage.cards.r.RootwaterShaman.class)); + cards.add(new SetCardInfo("Ruby Medallion", 305, Rarity.RARE, mage.cards.r.RubyMedallion.class)); + cards.add(new SetCardInfo("Sacred Guide", 38, Rarity.RARE, mage.cards.s.SacredGuide.class)); + cards.add(new SetCardInfo("Sadistic Glee", 153, Rarity.COMMON, mage.cards.s.SadisticGlee.class)); + cards.add(new SetCardInfo("Safeguard", 39, Rarity.RARE, mage.cards.s.Safeguard.class)); + cards.add(new SetCardInfo("Salt Flats", 324, Rarity.RARE, mage.cards.s.SaltFlats.class)); + cards.add(new SetCardInfo("Sandstone Warrior", 199, Rarity.COMMON, mage.cards.s.SandstoneWarrior.class)); + cards.add(new SetCardInfo("Sapphire Medallion", 306, Rarity.RARE, mage.cards.s.SapphireMedallion.class)); + cards.add(new SetCardInfo("Sarcomancy", 154, Rarity.RARE, mage.cards.s.Sarcomancy.class)); + cards.add(new SetCardInfo("Scabland", 325, Rarity.RARE, mage.cards.s.Scabland.class)); + cards.add(new SetCardInfo("Scalding Tongs", 307, Rarity.RARE, mage.cards.s.ScaldingTongs.class)); + cards.add(new SetCardInfo("Scorched Earth", 200, Rarity.RARE, mage.cards.s.ScorchedEarth.class)); + cards.add(new SetCardInfo("Scragnoth", 253, Rarity.UNCOMMON, mage.cards.s.Scragnoth.class)); + cards.add(new SetCardInfo("Screeching Harpy", 155, Rarity.UNCOMMON, mage.cards.s.ScreechingHarpy.class)); + cards.add(new SetCardInfo("Scroll Rack", 308, Rarity.RARE, mage.cards.s.ScrollRack.class)); + cards.add(new SetCardInfo("Sea Monster", 85, Rarity.COMMON, mage.cards.s.SeaMonster.class)); + cards.add(new SetCardInfo("Searing Touch", 201, Rarity.UNCOMMON, mage.cards.s.SearingTouch.class)); + cards.add(new SetCardInfo("Seeker of Skybreak", 254, Rarity.COMMON, mage.cards.s.SeekerOfSkybreak.class)); + cards.add(new SetCardInfo("Segmented Wurm", 269, Rarity.UNCOMMON, mage.cards.s.SegmentedWurm.class)); + cards.add(new SetCardInfo("Selenia, Dark Angel", 270, Rarity.RARE, mage.cards.s.SeleniaDarkAngel.class)); + cards.add(new SetCardInfo("Serene Offering", 40, Rarity.UNCOMMON, mage.cards.s.SereneOffering.class)); + cards.add(new SetCardInfo("Servant of Volrath", 156, Rarity.COMMON, mage.cards.s.ServantOfVolrath.class)); + cards.add(new SetCardInfo("Shadow Rift", 86, Rarity.COMMON, mage.cards.s.ShadowRift.class)); + cards.add(new SetCardInfo("Shadowstorm", 202, Rarity.UNCOMMON, mage.cards.s.Shadowstorm.class)); + cards.add(new SetCardInfo("Shatter", 203, Rarity.COMMON, mage.cards.s.Shatter.class)); + cards.add(new SetCardInfo("Shimmering Wings", 87, Rarity.COMMON, mage.cards.s.ShimmeringWings.class)); + cards.add(new SetCardInfo("Shocker", 204, Rarity.RARE, mage.cards.s.Shocker.class)); + cards.add(new SetCardInfo("Sky Spirit", 271, Rarity.UNCOMMON, mage.cards.s.SkySpirit.class)); + cards.add(new SetCardInfo("Skyshroud Condor", 88, Rarity.UNCOMMON, mage.cards.s.SkyshroudCondor.class)); + cards.add(new SetCardInfo("Skyshroud Elf", 255, Rarity.COMMON, mage.cards.s.SkyshroudElf.class)); + cards.add(new SetCardInfo("Skyshroud Forest", 326, Rarity.RARE, mage.cards.s.SkyshroudForest.class)); + cards.add(new SetCardInfo("Skyshroud Ranger", 256, Rarity.COMMON, mage.cards.s.SkyshroudRanger.class)); + cards.add(new SetCardInfo("Skyshroud Troll", 257, Rarity.COMMON, mage.cards.s.SkyshroudTroll.class)); + cards.add(new SetCardInfo("Skyshroud Vampire", 157, Rarity.UNCOMMON, mage.cards.s.SkyshroudVampire.class)); + cards.add(new SetCardInfo("Soltari Crusader", 41, Rarity.UNCOMMON, mage.cards.s.SoltariCrusader.class)); + cards.add(new SetCardInfo("Soltari Emissary", 42, Rarity.RARE, mage.cards.s.SoltariEmissary.class)); + cards.add(new SetCardInfo("Soltari Foot Soldier", 43, Rarity.COMMON, mage.cards.s.SoltariFootSoldier.class)); + cards.add(new SetCardInfo("Soltari Guerrillas", 272, Rarity.RARE, mage.cards.s.SoltariGuerrillas.class)); + cards.add(new SetCardInfo("Soltari Lancer", 44, Rarity.COMMON, mage.cards.s.SoltariLancer.class)); + cards.add(new SetCardInfo("Soltari Monk", 45, Rarity.UNCOMMON, mage.cards.s.SoltariMonk.class)); + cards.add(new SetCardInfo("Soltari Priest", 46, Rarity.UNCOMMON, mage.cards.s.SoltariPriest.class)); + cards.add(new SetCardInfo("Soltari Trooper", 47, Rarity.COMMON, mage.cards.s.SoltariTrooper.class)); + cards.add(new SetCardInfo("Souldrinker", 158, Rarity.UNCOMMON, mage.cards.s.Souldrinker.class)); + cards.add(new SetCardInfo("Spell Blast", 89, Rarity.COMMON, mage.cards.s.SpellBlast.class)); + cards.add(new SetCardInfo("Spike Drone", 258, Rarity.COMMON, mage.cards.s.SpikeDrone.class)); + cards.add(new SetCardInfo("Spinal Graft", 159, Rarity.COMMON, mage.cards.s.SpinalGraft.class)); + cards.add(new SetCardInfo("Spirit Mirror", 48, Rarity.RARE, mage.cards.s.SpiritMirror.class)); + cards.add(new SetCardInfo("Spontaneous Combustion", 273, Rarity.UNCOMMON, mage.cards.s.SpontaneousCombustion.class)); + cards.add(new SetCardInfo("Squee's Toy", 309, Rarity.COMMON, mage.cards.s.SqueesToy.class)); + cards.add(new SetCardInfo("Stalking Stones", 327, Rarity.UNCOMMON, mage.cards.s.StalkingStones.class)); + cards.add(new SetCardInfo("Starke of Rath", 205, Rarity.RARE, mage.cards.s.StarkeOfRath.class)); + cards.add(new SetCardInfo("Static Orb", 310, Rarity.RARE, mage.cards.s.StaticOrb.class)); + cards.add(new SetCardInfo("Staunch Defenders", 49, Rarity.UNCOMMON, mage.cards.s.StaunchDefenders.class)); + cards.add(new SetCardInfo("Steal Enchantment", 90, Rarity.UNCOMMON, mage.cards.s.StealEnchantment.class)); + cards.add(new SetCardInfo("Stinging Licid", 91, Rarity.UNCOMMON, mage.cards.s.StingingLicid.class)); + cards.add(new SetCardInfo("Stone Rain", 206, Rarity.COMMON, mage.cards.s.StoneRain.class)); + cards.add(new SetCardInfo("Storm Front", 259, Rarity.UNCOMMON, mage.cards.s.StormFront.class)); + cards.add(new SetCardInfo("Stun", 207, Rarity.COMMON, mage.cards.s.Stun.class)); + cards.add(new SetCardInfo("Sudden Impact", 208, Rarity.UNCOMMON, mage.cards.s.SuddenImpact.class)); + cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tahngarth's Rage", 209, Rarity.UNCOMMON, mage.cards.t.TahngarthsRage.class)); + cards.add(new SetCardInfo("Talon Sliver", 50, Rarity.COMMON, mage.cards.t.TalonSliver.class)); + cards.add(new SetCardInfo("Telethopter", 311, Rarity.UNCOMMON, mage.cards.t.Telethopter.class)); + cards.add(new SetCardInfo("Thalakos Dreamsower", 92, Rarity.UNCOMMON, mage.cards.t.ThalakosDreamsower.class)); + cards.add(new SetCardInfo("Thalakos Lowlands", 328, Rarity.UNCOMMON, mage.cards.t.ThalakosLowlands.class)); + cards.add(new SetCardInfo("Thalakos Mistfolk", 93, Rarity.COMMON, mage.cards.t.ThalakosMistfolk.class)); + cards.add(new SetCardInfo("Thalakos Seer", 94, Rarity.COMMON, mage.cards.t.ThalakosSeer.class)); + cards.add(new SetCardInfo("Thalakos Sentry", 95, Rarity.COMMON, mage.cards.t.ThalakosSentry.class)); + cards.add(new SetCardInfo("Thumbscrews", 312, Rarity.RARE, mage.cards.t.Thumbscrews.class)); + cards.add(new SetCardInfo("Time Ebb", 96, Rarity.COMMON, mage.cards.t.TimeEbb.class)); + cards.add(new SetCardInfo("Time Warp", 97, Rarity.RARE, mage.cards.t.TimeWarp.class)); + cards.add(new SetCardInfo("Tooth and Claw", 210, Rarity.RARE, mage.cards.t.ToothAndClaw.class)); + cards.add(new SetCardInfo("Torture Chamber", 313, Rarity.RARE, mage.cards.t.TortureChamber.class)); + cards.add(new SetCardInfo("Tradewind Rider", 98, Rarity.RARE, mage.cards.t.TradewindRider.class)); + cards.add(new SetCardInfo("Trained Armodon", 260, Rarity.COMMON, mage.cards.t.TrainedArmodon.class)); + cards.add(new SetCardInfo("Tranquility", 261, Rarity.COMMON, mage.cards.t.Tranquility.class)); + cards.add(new SetCardInfo("Trumpeting Armodon", 262, Rarity.UNCOMMON, mage.cards.t.TrumpetingArmodon.class)); + cards.add(new SetCardInfo("Twitch", 99, Rarity.COMMON, mage.cards.t.Twitch.class)); + cards.add(new SetCardInfo("Unstable Shapeshifter", 100, Rarity.RARE, mage.cards.u.UnstableShapeshifter.class)); + cards.add(new SetCardInfo("Vec Townships", 329, Rarity.UNCOMMON, mage.cards.v.VecTownships.class)); + cards.add(new SetCardInfo("Verdant Force", 263, Rarity.RARE, mage.cards.v.VerdantForce.class)); + cards.add(new SetCardInfo("Verdigris", 264, Rarity.UNCOMMON, mage.cards.v.Verdigris.class)); + cards.add(new SetCardInfo("Vhati il-Dal", 274, Rarity.RARE, mage.cards.v.VhatiIlDal.class)); + cards.add(new SetCardInfo("Volrath's Curse", 101, Rarity.COMMON, mage.cards.v.VolrathsCurse.class)); + cards.add(new SetCardInfo("Wall of Diffusion", 211, Rarity.COMMON, mage.cards.w.WallOfDiffusion.class)); + cards.add(new SetCardInfo("Warmth", 51, Rarity.UNCOMMON, mage.cards.w.Warmth.class)); + cards.add(new SetCardInfo("Wasteland", 330, Rarity.UNCOMMON, mage.cards.w.Wasteland.class)); + cards.add(new SetCardInfo("Watchdog", 314, Rarity.UNCOMMON, mage.cards.w.Watchdog.class)); + cards.add(new SetCardInfo("Whispers of the Muse", 103, Rarity.UNCOMMON, mage.cards.w.WhispersOfTheMuse.class)); + cards.add(new SetCardInfo("Wild Wurm", 212, Rarity.UNCOMMON, mage.cards.w.WildWurm.class)); + cards.add(new SetCardInfo("Wind Dancer", 104, Rarity.UNCOMMON, mage.cards.w.WindDancer.class)); + cards.add(new SetCardInfo("Wind Drake", 105, Rarity.COMMON, mage.cards.w.WindDrake.class)); + cards.add(new SetCardInfo("Winds of Rath", 52, Rarity.RARE, mage.cards.w.WindsOfRath.class)); + cards.add(new SetCardInfo("Winged Sliver", 106, Rarity.COMMON, mage.cards.w.WingedSliver.class)); + cards.add(new SetCardInfo("Winter's Grasp", 265, Rarity.UNCOMMON, mage.cards.w.WintersGrasp.class)); + cards.add(new SetCardInfo("Wood Sage", 275, Rarity.RARE, mage.cards.w.WoodSage.class)); + cards.add(new SetCardInfo("Worthy Cause", 53, Rarity.UNCOMMON, mage.cards.w.WorthyCause.class)); + } +} From c24077a5fb6930585a707734d4e443a1f65e981a Mon Sep 17 00:00:00 2001 From: L_J Date: Mon, 26 Nov 2018 12:47:41 +0000 Subject: [PATCH 30/50] Goblin Machinist fix Card didn't reveal the nonland card and put it on the bottom of library --- Mage.Sets/src/mage/cards/g/GoblinMachinist.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GoblinMachinist.java b/Mage.Sets/src/mage/cards/g/GoblinMachinist.java index 2e217d109bf..8ff675b00e9 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinMachinist.java +++ b/Mage.Sets/src/mage/cards/g/GoblinMachinist.java @@ -77,9 +77,9 @@ class GoblinMachinistEffect extends OneShotEffect { break; } } - controller.revealCards(source, cards, game); - controller.putCardsOnBottomOfLibrary(cards, game, source, true); } + controller.revealCards(source, cards, game); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } return false; From 6e2dde92aabf42da3178f584c73e9d08a651826e Mon Sep 17 00:00:00 2001 From: L_J Date: Mon, 26 Nov 2018 14:30:17 +0000 Subject: [PATCH 31/50] Implemented Canal Dredger --- Mage.Sets/src/mage/cards/c/CanalDredger.java | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CanalDredger.java diff --git a/Mage.Sets/src/mage/cards/c/CanalDredger.java b/Mage.Sets/src/mage/cards/c/CanalDredger.java new file mode 100644 index 00000000000..d1a8d2b7bbe --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CanalDredger.java @@ -0,0 +1,52 @@ + +package mage.cards.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.PutOnLibraryTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author L_J + */ +public final class CanalDredger extends CardImpl { + + public CanalDredger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}"); + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(1); + this.toughness = new MageInt(5); + + // TODO: Draft specific abilities not implemented + // Draft Canal Dredger face up. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Draft Canal Dredger face up."))); + + // Each player passes the last card from each booster pack to a player who drafted a card named Canal Dredger. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Each player passes the last card from each booster pack to a player who drafted a card named Canal Dredger."))); + + // {T}: Put target card from your graveyard on the bottom of your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(false), new TapSourceCost()); + ability.addTarget(new TargetCardInYourGraveyard()); + this.addAbility(ability); + } + + public CanalDredger(final CanalDredger card) { + super(card); + } + + @Override + public CanalDredger copy() { + return new CanalDredger(this); + } +} From 3fd738b5e5a2eb6ab92984013db9108940b0af8a Mon Sep 17 00:00:00 2001 From: L_J Date: Mon, 26 Nov 2018 14:30:58 +0000 Subject: [PATCH 32/50] Implemented Deal Broker --- Mage.Sets/src/mage/cards/d/DealBroker.java | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DealBroker.java diff --git a/Mage.Sets/src/mage/cards/d/DealBroker.java b/Mage.Sets/src/mage/cards/d/DealBroker.java new file mode 100644 index 00000000000..432f5836934 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DealBroker.java @@ -0,0 +1,50 @@ + +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; + +/** + * + * @author L_J + */ +public final class DealBroker extends CardImpl { + + public DealBroker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT, CardType.CREATURE},"{3}"); + this.subtype.add(SubType.CONSTRUCT); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // TODO: Draft specific abilities not implemented + // Draft Deal Broker face up. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Draft Deal Broker face up."))); + + // Immediately after the draft, you may reveal a card in your card pool. Each other player may offer you one card in their card pool in exchange. You may accept any one offer. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("Immediately after the draft, you may reveal a card in your card pool. " + + "Each other player may offer you one card in their card pool in exchange. You may accept any one offer."))); + + // {T}: Draw a card, then discard a card. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardControllerEffect(), new TapSourceCost())); + } + + public DealBroker(final DealBroker card) { + super(card); + } + + @Override + public DealBroker copy() { + return new DealBroker(this); + } + +} From 4844d439dbabe4e57357983aa4a30e0a7dd2f9c0 Mon Sep 17 00:00:00 2001 From: L_J Date: Mon, 26 Nov 2018 14:31:09 +0000 Subject: [PATCH 33/50] Implemented Canal Dredger and Deal Broker --- Mage.Sets/src/mage/sets/Conspiracy.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Conspiracy.java b/Mage.Sets/src/mage/sets/Conspiracy.java index 3e561263f15..bc992d21361 100644 --- a/Mage.Sets/src/mage/sets/Conspiracy.java +++ b/Mage.Sets/src/mage/sets/Conspiracy.java @@ -43,6 +43,7 @@ public final class Conspiracy extends ExpansionSet { cards.add(new SetCardInfo("Brainstorm", 91, Rarity.COMMON, mage.cards.b.Brainstorm.class)); cards.add(new SetCardInfo("Breakthrough", 92, Rarity.UNCOMMON, mage.cards.b.Breakthrough.class)); cards.add(new SetCardInfo("Brimstone Volley", 138, Rarity.COMMON, mage.cards.b.BrimstoneVolley.class)); + cards.add(new SetCardInfo("Canal Dredger", 55, Rarity.RARE, mage.cards.c.CanalDredger.class)); cards.add(new SetCardInfo("Charging Rhino", 159, Rarity.COMMON, mage.cards.c.ChargingRhino.class)); cards.add(new SetCardInfo("Chartooth Cougar", 139, Rarity.COMMON, mage.cards.c.ChartoothCougar.class)); cards.add(new SetCardInfo("Cinder Wall", 140, Rarity.COMMON, mage.cards.c.CinderWall.class)); @@ -57,6 +58,7 @@ public final class Conspiracy extends ExpansionSet { cards.add(new SetCardInfo("Custodi Squire", 18, Rarity.COMMON, mage.cards.c.CustodiSquire.class)); cards.add(new SetCardInfo("Dack Fayden", 42, Rarity.MYTHIC, mage.cards.d.DackFayden.class)); cards.add(new SetCardInfo("Dack's Duplicate", 43, Rarity.RARE, mage.cards.d.DacksDuplicate.class)); + cards.add(new SetCardInfo("Deal Broker", 61, Rarity.RARE, mage.cards.d.DealBroker.class)); cards.add(new SetCardInfo("Deathforge Shaman", 141, Rarity.UNCOMMON, mage.cards.d.DeathforgeShaman.class)); cards.add(new SetCardInfo("Deathreap Ritual", 44, Rarity.UNCOMMON, mage.cards.d.DeathreapRitual.class)); cards.add(new SetCardInfo("Deathrender", 197, Rarity.RARE, mage.cards.d.Deathrender.class)); From 126610b6a898dcc8ec8aac75ab64a0d556de0184 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 26 Nov 2018 16:16:59 +0100 Subject: [PATCH 34/50] Added handling of TargetCardInGraveyardOrBattlefield fpr TestPlayer. --- .../java/org/mage/test/player/TestPlayer.java | 478 +++++++++++++----- 1 file changed, 344 insertions(+), 134 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index ae5cdf3ca3f..46f890f9e27 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1,5 +1,9 @@ package org.mage.test.player; +import java.io.Serializable; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import mage.MageObject; import mage.MageObjectReference; import mage.ObjectColor; @@ -43,19 +47,12 @@ import mage.player.ai.ComputerPlayer; import mage.players.Library; import mage.players.ManaPool; import mage.players.Player; -import mage.players.PlayerList; import mage.players.net.UserData; import mage.target.*; import mage.target.common.*; import org.apache.log4j.Logger; import org.junit.Assert; import org.junit.Ignore; - -import java.io.Serializable; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*; /** @@ -132,7 +129,7 @@ public class TestPlayer implements Player { /** * @param maxCallsWithoutAction max number of priority passes a player may - * have for this test (default = 100) + * have for this test (default = 100) */ public void setMaxCallsWithoutAction(int maxCallsWithoutAction) { this.maxCallsWithoutAction = maxCallsWithoutAction; @@ -807,7 +804,7 @@ public class TestPlayer implements Player { // Loop through players and validate can attack/block this turn UUID defenderId = null; //List - for (Iterator it = actions.iterator(); it.hasNext(); ) { + for (Iterator it = actions.iterator(); it.hasNext();) { PlayerAction action = it.next(); if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) { String command = action.getAction(); @@ -1137,6 +1134,62 @@ public class TestPlayer implements Player { if (target.getTargetController() != null && target.getAbilityController() != null) { abilityControllerId = target.getAbilityController(); } + if (target instanceof TargetCardInGraveyardOrBattlefield) { + boolean removeTargetDefinition = false; + Filter filter = target.getFilter(); + for (String targetDefinition : targets) { + String[] targetList = targetDefinition.split("\\^"); + boolean targetFound = false; + for (String targetName : targetList) { + boolean originOnly = false; + boolean copyOnly = false; + if (targetName.endsWith("]")) { + if (targetName.endsWith("[no copy]")) { + originOnly = true; + targetName = targetName.substring(0, targetName.length() - 9); + } + if (targetName.endsWith("[only copy]")) { + copyOnly = true; + targetName = targetName.substring(0, targetName.length() - 11); + } + } + for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { + if (permanent.getName().equals(targetName) || (permanent.getName() + '-' + permanent.getExpansionSetCode()).equals(targetName)) { + if (filter.match(permanent, game) && target.canTarget(abilityControllerId, permanent.getId(), source, game) && !target.getTargets().contains(permanent.getId())) { + if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) { + target.add(permanent.getId(), game); + targetFound = true; + break; + } + } + } + } + if (!targetFound) { + for (UUID playerId : game.getState().getPlayersInRange(this.getId(), game)) { + Player player = game.getPlayer(playerId); + for (Card card : player.getGraveyard().getCards(((TargetCardInGraveyardOrBattlefield) target).getFilter(), game)) { + if (card.getName().equals(targetName) || (card.getName() + '-' + card.getExpansionSetCode()).equals(targetName)) { + if (((TargetCardInYourGraveyard) target).canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) { + target.add(card.getId(), game); + targetFound = true; + break; + } + } + } + } + } + if (targetFound) { + targetFound = false; + removeTargetDefinition = true; + } + + } + if (removeTargetDefinition) { + targets.remove(targetDefinition); + return true; + } + } + } if (target instanceof TargetPlayer || target instanceof TargetAnyTarget || target instanceof TargetCreatureOrPlayer @@ -1304,7 +1357,10 @@ public class TestPlayer implements Player { } @Override - public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) { + public boolean chooseTarget(Outcome outcome, Cards cards, + TargetCard target, Ability source, + Game game + ) { if (!targets.isEmpty()) { for (String targetDefinition : targets) { String[] targetList = targetDefinition.split("\\^"); @@ -1328,7 +1384,8 @@ public class TestPlayer implements Player { } @Override - public TriggeredAbility chooseTriggeredAbility(List abilities, Game game) { + public TriggeredAbility chooseTriggeredAbility(List abilities, Game game + ) { if (!choices.isEmpty()) { for (TriggeredAbility ability : abilities) { if (ability.toString().startsWith(choices.get(0))) { @@ -1341,12 +1398,18 @@ public class TestPlayer implements Player { } @Override - public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) { + public boolean chooseUse(Outcome outcome, String message, + Ability source, Game game + ) { return this.chooseUse(outcome, message, null, null, null, source, game); } @Override - public boolean chooseUse(Outcome outcome, String message, String secondMessage, String trueText, String falseText, Ability source, Game game) { + public boolean chooseUse(Outcome outcome, String message, + String secondMessage, String trueText, + String falseText, Ability source, + Game game + ) { if (message.equals("Scry 1?")) { return false; } @@ -1364,7 +1427,9 @@ public class TestPlayer implements Player { } @Override - public int announceXMana(int min, int max, String message, Game game, Ability ability) { + public int announceXMana(int min, int max, String message, + Game game, Ability ability + ) { if (!choices.isEmpty()) { for (String choice : choices) { if (choice.startsWith("X=")) { @@ -1378,7 +1443,10 @@ public class TestPlayer implements Player { } @Override - public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variablCost) { + public int announceXCost(int min, int max, String message, + Game game, Ability ability, + VariableCost variablCost + ) { if (!choices.isEmpty()) { if (choices.get(0).startsWith("X=")) { int xValue = Integer.parseInt(choices.get(0).substring(2)); @@ -1390,7 +1458,9 @@ public class TestPlayer implements Player { } @Override - public int getAmount(int min, int max, String message, Game game) { + public int getAmount(int min, int max, String message, + Game game + ) { if (!choices.isEmpty()) { if (choices.get(0).startsWith("X=")) { int xValue = Integer.parseInt(choices.get(0).substring(2)); @@ -1402,12 +1472,14 @@ public class TestPlayer implements Player { } @Override - public void addAbility(Ability ability) { + public void addAbility(Ability ability + ) { computerPlayer.addAbility(ability); } @Override - public boolean activateAbility(ActivatedAbility ability, Game game) { + public boolean activateAbility(ActivatedAbility ability, Game game + ) { return computerPlayer.activateAbility(ability, game); } @@ -1427,12 +1499,14 @@ public class TestPlayer implements Player { } @Override - public void won(Game game) { + public void won(Game game + ) { computerPlayer.won(game); } @Override - public void restore(Player player) { + public void restore(Player player + ) { this.modesSet.clear(); this.modesSet.addAll(((TestPlayer) player).modesSet); this.actions.clear(); @@ -1445,18 +1519,21 @@ public class TestPlayer implements Player { } @Override - public void useDeck(Deck deck, Game game) { + public void useDeck(Deck deck, Game game + ) { computerPlayer.useDeck(deck, game); } @Override - public void init(Game game) { + public void init(Game game + ) { initialTurns = 0; computerPlayer.init(game); } @Override - public void init(Game game, boolean testMode) { + public void init(Game game, boolean testMode + ) { initialTurns = 0; computerPlayer.init(game, testMode); } @@ -1472,12 +1549,14 @@ public class TestPlayer implements Player { } @Override - public void otherPlayerLeftGame(Game game) { + public void otherPlayerLeftGame(Game game + ) { computerPlayer.otherPlayerLeftGame(game); } @Override - public void beginTurn(Game game) { + public void beginTurn(Game game + ) { checkLegalMovesThisTurn(game); computerPlayer.beginTurn(game); } @@ -1498,12 +1577,14 @@ public class TestPlayer implements Player { } @Override - public void controlPlayersTurn(Game game, UUID playerId) { + public void controlPlayersTurn(Game game, UUID playerId + ) { computerPlayer.controlPlayersTurn(game, playerId); } @Override - public void setTurnControlledBy(UUID playerId) { + public void setTurnControlledBy(UUID playerId + ) { computerPlayer.setTurnControlledBy(playerId); } @@ -1523,77 +1604,98 @@ public class TestPlayer implements Player { } @Override - public void setGameUnderYourControl(boolean value) { + public void setGameUnderYourControl(boolean value + ) { computerPlayer.setGameUnderYourControl(value); } @Override - public void setGameUnderYourControl(boolean value, boolean fullRestore) { + public void setGameUnderYourControl(boolean value, boolean fullRestore + ) { computerPlayer.setGameUnderYourControl(value, fullRestore); } @Override - public void endOfTurn(Game game) { + public void endOfTurn(Game game + ) { computerPlayer.endOfTurn(game); } @Override - public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) { + public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, + Game game + ) { return computerPlayer.canBeTargetedBy(source, sourceControllerId, game); } @Override - public boolean hasProtectionFrom(MageObject source, Game game) { + public boolean hasProtectionFrom(MageObject source, Game game + ) { return computerPlayer.hasProtectionFrom(source, game); } @Override - public int drawCards(int num, Game game) { + public int drawCards(int num, Game game + ) { return computerPlayer.drawCards(num, game); } @Override - public int drawCards(int num, Game game, List appliedEffects) { + public int drawCards(int num, Game game, + List appliedEffects + ) { return computerPlayer.drawCards(num, game, appliedEffects); } @Override - public void discardToMax(Game game) { + public void discardToMax(Game game + ) { computerPlayer.discardToMax(game); } @Override - public boolean putInHand(Card card, Game game) { + public boolean putInHand(Card card, Game game + ) { return computerPlayer.putInHand(card, game); } @Override - public boolean removeFromHand(Card card, Game game) { + public boolean removeFromHand(Card card, Game game + ) { return computerPlayer.removeFromHand(card, game); } @Override - public boolean removeFromLibrary(Card card, Game game) { + public boolean removeFromLibrary(Card card, Game game + ) { return computerPlayer.removeFromLibrary(card, game); } @Override - public void discard(int amount, Ability source, Game game) { + public void discard(int amount, Ability source, + Game game + ) { computerPlayer.discard(amount, source, game); } @Override - public Card discardOne(boolean random, Ability source, Game game) { + public Card discardOne(boolean random, Ability source, + Game game + ) { return computerPlayer.discardOne(random, source, game); } @Override - public Cards discard(int amount, boolean random, Ability source, Game game) { + public Cards discard(int amount, boolean random, Ability source, + Game game + ) { return computerPlayer.discard(amount, random, source, game); } @Override - public boolean discard(Card card, Ability source, Game game) { + public boolean discard(Card card, Ability source, + Game game + ) { return computerPlayer.discard(card, source, game); } @@ -1603,52 +1705,67 @@ public class TestPlayer implements Player { } @Override - public boolean addAttachment(UUID permanentId, Game game) { + public boolean addAttachment(UUID permanentId, Game game + ) { return computerPlayer.addAttachment(permanentId, game); } @Override - public boolean removeAttachment(Permanent attachment, Game game) { + public boolean removeAttachment(Permanent attachment, Game game + ) { return computerPlayer.removeAttachment(attachment, game); } @Override - public boolean removeFromBattlefield(Permanent permanent, Game game) { + public boolean removeFromBattlefield(Permanent permanent, Game game + ) { return computerPlayer.removeFromBattlefield(permanent, game); } @Override - public boolean putInGraveyard(Card card, Game game) { + public boolean putInGraveyard(Card card, Game game + ) { return computerPlayer.putInGraveyard(card, game); } @Override - public boolean removeFromGraveyard(Card card, Game game) { + public boolean removeFromGraveyard(Card card, Game game + ) { return computerPlayer.removeFromGraveyard(card, game); } @Override - public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) { + public boolean putCardsOnBottomOfLibrary(Card card, Game game, + Ability source, boolean anyOrder + ) { return computerPlayer.putCardsOnBottomOfLibrary(card, game, source, anyOrder); } @Override - public boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) { + public boolean putCardsOnBottomOfLibrary(Cards cards, Game game, + Ability source, boolean anyOrder + ) { return computerPlayer.putCardsOnBottomOfLibrary(cards, game, source, anyOrder); } @Override - public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) { + public boolean putCardOnTopXOfLibrary(Card card, Game game, + Ability source, int xFromTheTop + ) { return computerPlayer.putCardOnTopXOfLibrary(card, game, source, xFromTheTop); } @Override - public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) { + public boolean putCardsOnTopOfLibrary(Cards cards, Game game, + Ability source, boolean anyOrder + ) { return computerPlayer.putCardsOnTopOfLibrary(cards, game, source, anyOrder); } @Override - public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs) { + public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, + Costs costs + ) { computerPlayer.setCastSourceIdWithAlternateMana(sourceId, manaCosts, costs); } @@ -1673,27 +1790,36 @@ public class TestPlayer implements Player { } @Override - public boolean cast(SpellAbility ability, Game game, boolean noMana, MageObjectReference reference) { + public boolean cast(SpellAbility ability, Game game, + boolean noMana, MageObjectReference reference + ) { return computerPlayer.cast(ability, game, noMana, reference); } @Override - public boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference) { + public boolean playCard(Card card, Game game, + boolean noMana, boolean ignoreTiming, MageObjectReference reference + ) { return computerPlayer.playCard(card, game, noMana, ignoreTiming, reference); } @Override - public boolean playLand(Card card, Game game, boolean ignoreTiming) { + public boolean playLand(Card card, Game game, + boolean ignoreTiming + ) { return computerPlayer.playLand(card, game, ignoreTiming); } @Override - public boolean triggerAbility(TriggeredAbility source, Game game) { + public boolean triggerAbility(TriggeredAbility source, Game game + ) { return computerPlayer.triggerAbility(source, game); } @Override - public LinkedHashMap getUseableActivatedAbilities(MageObject object, Zone zone, Game game) { + public LinkedHashMap getUseableActivatedAbilities(MageObject object, Zone zone, + Game game + ) { return computerPlayer.getUseableActivatedAbilities(object, zone, game); } @@ -1708,57 +1834,77 @@ public class TestPlayer implements Player { } @Override - public void shuffleLibrary(Ability source, Game game) { + public void shuffleLibrary(Ability source, Game game + ) { computerPlayer.shuffleLibrary(source, game); } @Override - public void revealCards(Ability source, Cards cards, Game game) { + public void revealCards(Ability source, Cards cards, + Game game + ) { computerPlayer.revealCards(source, cards, game); } @Override - public void revealCards(String name, Cards cards, Game game) { + public void revealCards(String name, Cards cards, + Game game + ) { computerPlayer.revealCards(name, cards, game); } @Override - public void revealCards(Ability source, String name, Cards cards, Game game) { + public void revealCards(Ability source, String name, + Cards cards, Game game + ) { computerPlayer.revealCards(name, cards, game); } @Override - public void revealCards(String name, Cards cards, Game game, boolean postToLog) { + public void revealCards(String name, Cards cards, + Game game, boolean postToLog + ) { computerPlayer.revealCards(name, cards, game, postToLog); } @Override - public void revealCards(Ability source, String name, Cards cards, Game game, boolean postToLog) { + public void revealCards(Ability source, String name, + Cards cards, Game game, + boolean postToLog + ) { computerPlayer.revealCards(name, cards, game, postToLog); } @Override - public void lookAtCards(String name, Cards cards, Game game) { + public void lookAtCards(String name, Cards cards, + Game game + ) { computerPlayer.lookAtCards(name, cards, game); } @Override - public void lookAtCards(Ability source, String name, Cards cards, Game game) { + public void lookAtCards(Ability source, String name, + Cards cards, Game game + ) { computerPlayer.lookAtCards(source, name, cards, game); } @Override - public void lookAtCards(String name, Card card, Game game) { + public void lookAtCards(String name, Card card, + Game game + ) { computerPlayer.lookAtCards(name, card, game); } @Override - public void phasing(Game game) { + public void phasing(Game game + ) { computerPlayer.phasing(game); } @Override - public void untap(Game game) { + public void untap(Game game + ) { computerPlayer.untap(game); } @@ -1813,22 +1959,28 @@ public class TestPlayer implements Player { } @Override - public void initLife(int life) { + public void initLife(int life + ) { computerPlayer.initLife(life); } @Override - public void setLife(int life, Game game, UUID sourceId) { + public void setLife(int life, Game game, + UUID sourceId + ) { computerPlayer.setLife(life, game, sourceId); } @Override - public void setLife(int life, Game game, Ability source) { + public void setLife(int life, Game game, + Ability source + ) { computerPlayer.setLife(life, game, source); } @Override - public void setLifeTotalCanChange(boolean lifeTotalCanChange) { + public void setLifeTotalCanChange(boolean lifeTotalCanChange + ) { computerPlayer.setLifeTotalCanChange(lifeTotalCanChange); } @@ -1848,12 +2000,15 @@ public class TestPlayer implements Player { } @Override - public void setCanLoseLife(boolean canLoseLife) { + public void setCanLoseLife(boolean canLoseLife + ) { computerPlayer.setCanLoseLife(canLoseLife); } @Override - public int loseLife(int amount, Game game, boolean atCombat) { + public int loseLife(int amount, Game game, + boolean atCombat + ) { return computerPlayer.loseLife(amount, game, atCombat); } @@ -1863,37 +2018,49 @@ public class TestPlayer implements Player { } @Override - public void setCanGainLife(boolean canGainLife) { + public void setCanGainLife(boolean canGainLife + ) { computerPlayer.setCanGainLife(canGainLife); } @Override - public int gainLife(int amount, Game game, Ability source) { + public int gainLife(int amount, Game game, + Ability source + ) { return computerPlayer.gainLife(amount, game, source); } @Override - public int gainLife(int amount, Game game, UUID sourceId) { + public int gainLife(int amount, Game game, + UUID sourceId + ) { return computerPlayer.gainLife(amount, game, sourceId); } @Override - public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable) { + public int damage(int damage, UUID sourceId, + Game game, boolean combatDamage, boolean preventable + ) { return computerPlayer.damage(damage, sourceId, game, combatDamage, preventable); } @Override - public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable, List appliedEffects) { + public int damage(int damage, UUID sourceId, + Game game, boolean combatDamage, boolean preventable, List appliedEffects + ) { return computerPlayer.damage(damage, sourceId, game, combatDamage, preventable, appliedEffects); } @Override - public boolean addCounters(Counter counter, Game game) { + public boolean addCounters(Counter counter, Game game + ) { return computerPlayer.addCounters(counter, game); } @Override - public void removeCounters(String name, int amount, Ability source, Game game) { + public void removeCounters(String name, int amount, Ability source, + Game game + ) { computerPlayer.removeCounters(name, amount, source, game); } @@ -1908,7 +2075,8 @@ public class TestPlayer implements Player { } @Override - public void setLandsPerTurn(int landsPerTurn) { + public void setLandsPerTurn(int landsPerTurn + ) { computerPlayer.setLandsPerTurn(landsPerTurn); } @@ -1918,7 +2086,8 @@ public class TestPlayer implements Player { } @Override - public void setLoyaltyUsePerTurn(int loyaltyUsePerTurn) { + public void setLoyaltyUsePerTurn(int loyaltyUsePerTurn + ) { computerPlayer.setLoyaltyUsePerTurn(loyaltyUsePerTurn); } @@ -1928,12 +2097,14 @@ public class TestPlayer implements Player { } @Override - public void setMaxHandSize(int maxHandSize) { + public void setMaxHandSize(int maxHandSize + ) { computerPlayer.setMaxHandSize(maxHandSize); } @Override - public void setMaxAttackedBy(int maxAttackedBy) { + public void setMaxAttackedBy(int maxAttackedBy + ) { computerPlayer.setMaxAttackedBy(maxAttackedBy); } @@ -1943,27 +2114,32 @@ public class TestPlayer implements Player { } @Override - public void setResponseString(String responseString) { + public void setResponseString(String responseString + ) { computerPlayer.setResponseString(responseString); } @Override - public void setResponseManaType(UUID manaTypePlayerId, ManaType responseManaType) { + public void setResponseManaType(UUID manaTypePlayerId, ManaType responseManaType + ) { computerPlayer.setResponseManaType(manaTypePlayerId, responseManaType); } @Override - public void setResponseUUID(UUID responseUUID) { + public void setResponseUUID(UUID responseUUID + ) { computerPlayer.setResponseUUID(responseUUID); } @Override - public void setResponseBoolean(Boolean responseBoolean) { + public void setResponseBoolean(Boolean responseBoolean + ) { computerPlayer.setResponseBoolean(responseBoolean); } @Override - public void setResponseInteger(Integer responseInteger) { + public void setResponseInteger(Integer responseInteger + ) { computerPlayer.setResponseInteger(responseInteger); } @@ -1973,7 +2149,8 @@ public class TestPlayer implements Player { } @Override - public void pass(Game game) { + public void pass(Game game + ) { computerPlayer.pass(game); } @@ -1993,27 +2170,33 @@ public class TestPlayer implements Player { } @Override - public void quit(Game game) { + public void quit(Game game + ) { computerPlayer.quit(game); } @Override - public void timerTimeout(Game game) { + public void timerTimeout(Game game + ) { computerPlayer.timerTimeout(game); } @Override - public void idleTimeout(Game game) { + public void idleTimeout(Game game + ) { computerPlayer.idleTimeout(game); } @Override - public void concede(Game game) { + public void concede(Game game + ) { computerPlayer.concede(game); } @Override - public void sendPlayerAction(mage.constants.PlayerAction playerAction, Game game, Object data) { + public void sendPlayerAction(mage.constants.PlayerAction playerAction, Game game, + Object data + ) { computerPlayer.sendPlayerAction(playerAction, game, data); } @@ -2028,7 +2211,8 @@ public class TestPlayer implements Player { } @Override - public void lost(Game game) { + public void lost(Game game + ) { computerPlayer.lost(game); } @@ -2038,17 +2222,20 @@ public class TestPlayer implements Player { } @Override - public void drew(Game game) { + public void drew(Game game + ) { computerPlayer.drew(game); } @Override - public void lostForced(Game game) { + public void lostForced(Game game + ) { computerPlayer.lostForced(game); } @Override - public boolean canLose(Game game) { + public boolean canLose(Game game + ) { return computerPlayer.canLose(game); } @@ -2073,77 +2260,100 @@ public class TestPlayer implements Player { } @Override - public void declareAttacker(UUID attackerId, UUID defenderId, Game game, boolean allowUndo) { + public void declareAttacker(UUID attackerId, UUID defenderId, + Game game, boolean allowUndo + ) { computerPlayer.declareAttacker(attackerId, defenderId, game, allowUndo); } @Override - public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game) { + public void declareBlocker(UUID defenderId, UUID blockerId, + UUID attackerId, Game game + ) { computerPlayer.declareBlocker(defenderId, blockerId, attackerId, game); } @Override - public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game, boolean allowUndo) { + public void declareBlocker(UUID defenderId, UUID blockerId, + UUID attackerId, Game game, + boolean allowUndo + ) { computerPlayer.declareBlocker(defenderId, blockerId, attackerId, game, allowUndo); } @Override - public boolean searchLibrary(TargetCardInLibrary target, Game game) { + public boolean searchLibrary(TargetCardInLibrary target, Game game + ) { return computerPlayer.searchLibrary(target, game); } @Override - public boolean searchLibrary(TargetCardInLibrary target, Game game, boolean triggerEvents) { + public boolean searchLibrary(TargetCardInLibrary target, Game game, + boolean triggerEvents + ) { return computerPlayer.searchLibrary(target, game, triggerEvents); } @Override - public boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId) { + public boolean searchLibrary(TargetCardInLibrary target, Game game, + UUID targetPlayerId + ) { return computerPlayer.searchLibrary(target, game, targetPlayerId); } @Override - public boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents) { + public boolean searchLibrary(TargetCardInLibrary target, Game game, + UUID targetPlayerId, boolean triggerEvents + ) { return computerPlayer.searchLibrary(target, game, targetPlayerId, triggerEvents); } @Override - public boolean flipCoin(Game game) { + public boolean flipCoin(Game game + ) { return computerPlayer.flipCoin(game); } @Override - public boolean flipCoin(Game game, ArrayList appliedEffects) { + public boolean flipCoin(Game game, ArrayList appliedEffects + ) { return computerPlayer.flipCoin(game, appliedEffects); } @Override - public int rollDice(Game game, int numSides) { + public int rollDice(Game game, int numSides + ) { return computerPlayer.rollDice(game, numSides); } @Override - public int rollDice(Game game, ArrayList appliedEffects, int numSides) { + public int rollDice(Game game, ArrayList appliedEffects, + int numSides + ) { return computerPlayer.rollDice(game, appliedEffects, numSides); } @Override - public List getAvailableAttackers(Game game) { + public List getAvailableAttackers(Game game + ) { return computerPlayer.getAvailableAttackers(game); } @Override - public List getAvailableAttackers(UUID defenderId, Game game) { + public List getAvailableAttackers(UUID defenderId, Game game + ) { return computerPlayer.getAvailableAttackers(defenderId, game); } @Override - public List getAvailableBlockers(Game game) { + public List getAvailableBlockers(Game game + ) { return computerPlayer.getAvailableBlockers(game); } @Override - public ManaOptions getManaAvailable(Game game) { + public ManaOptions getManaAvailable(Game game + ) { return computerPlayer.getManaAvailable(game); } @@ -2496,7 +2706,7 @@ public class TestPlayer implements Player { @Override public boolean choose(Outcome outcome, Target target, - UUID sourceId, Game game + UUID sourceId, Game game ) { // needed to call here the TestPlayer because it's overwitten return choose(outcome, target, sourceId, game, null); @@ -2504,7 +2714,7 @@ public class TestPlayer implements Player { @Override public boolean choose(Outcome outcome, Cards cards, - TargetCard target, Game game + TargetCard target, Game game ) { if (!choices.isEmpty()) { for (String choose2 : choices) { @@ -2536,7 +2746,7 @@ public class TestPlayer implements Player { @Override public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.chooseTargetAmount(outcome, target, source, game); } @@ -2549,15 +2759,15 @@ public class TestPlayer implements Player { @Override public boolean choosePile(Outcome outcome, String message, - List pile1, List pile2, - Game game + List pile1, List pile2, + Game game ) { return computerPlayer.choosePile(outcome, message, pile1, pile2, game); } @Override public boolean playMana(Ability ability, ManaCost unpaid, - String promptText, Game game + String promptText, Game game ) { groupsForTargetHandling = null; return computerPlayer.playMana(ability, unpaid, promptText, game); @@ -2571,15 +2781,15 @@ public class TestPlayer implements Player { @Override public UUID chooseBlockerOrder(List blockers, CombatGroup combatGroup, - List blockerOrder, Game game + List blockerOrder, Game game ) { return computerPlayer.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game); } @Override public void assignDamage(int damage, List targets, - String singleTargetName, UUID sourceId, - Game game + String singleTargetName, UUID sourceId, + Game game ) { computerPlayer.assignDamage(damage, targets, singleTargetName, sourceId, game); } @@ -2598,14 +2808,14 @@ public class TestPlayer implements Player { @Override public void pickCard(List cards, Deck deck, - Draft draft + Draft draft ) { computerPlayer.pickCard(cards, deck, draft); } @Override public boolean scry(int value, Ability source, - Game game + Game game ) { // Don't scry at the start of the game. if (game.getTurnNum() == 1 && game.getStep() == null) { @@ -2616,44 +2826,44 @@ public class TestPlayer implements Player { @Override public boolean surveil(int value, Ability source, - Game game + Game game ) { return computerPlayer.surveil(value, source, game); } @Override public boolean moveCards(Card card, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(card, toZone, source, game); } @Override public boolean moveCards(Card card, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } @Override public boolean moveCards(Cards cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(cards, toZone, source, game); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game + Ability source, Game game ) { return computerPlayer.moveCards(cards, toZone, source, game); } @Override public boolean moveCards(Set cards, Zone toZone, - Ability source, Game game, - boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects + Ability source, Game game, + boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects ) { return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } From 2323654a22dcfbafce4481620107771b97f2adc4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 26 Nov 2018 19:00:59 +0100 Subject: [PATCH 35/50] Fixed Duplicity casting costs. --- Mage.Sets/src/mage/cards/d/Duplicity.java | 400 +++++++++--------- .../src/mage/cards/p/ProwlingPangolin.java | 5 +- 2 files changed, 202 insertions(+), 203 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/Duplicity.java b/Mage.Sets/src/mage/cards/d/Duplicity.java index ec2655933c0..42fd7d75ab4 100644 --- a/Mage.Sets/src/mage/cards/d/Duplicity.java +++ b/Mage.Sets/src/mage/cards/d/Duplicity.java @@ -1,200 +1,200 @@ -package mage.cards.d; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.discard.DiscardControllerEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.util.CardUtil; - -/** - * - * @author jeffwadsworth - */ -public final class Duplicity extends CardImpl { - - public Duplicity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); - - // When Duplicity enters the battlefield, exile the top five cards of your library face down. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DuplicityEffect(), false)); - - // At the beginning of your upkeep, you may exile all cards from your hand face down. If you do, put all other cards you own exiled with Duplicity into your hand. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DuplicityExileHandEffect(), TargetController.YOU, true)); - - // At the beginning of your end step, discard a card. - this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DiscardControllerEffect(1), false)); - - // When you lose control of Duplicity, put all cards exiled with Duplicity into their owner's graveyard. - this.addAbility(new LoseControlDuplicity()); - - } - - public Duplicity(final Duplicity card) { - super(card); - } - - @Override - public Duplicity copy() { - return new Duplicity(this); - } -} - -class DuplicityEffect extends OneShotEffect { - - public DuplicityEffect() { - super(Outcome.Exile); - staticText = "exile the top five cards of your library face down"; - } - - public DuplicityEffect(final DuplicityEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null - && sourceObject != null) { - if (controller.getLibrary().hasCards()) { - UUID exileId = CardUtil.getCardExileZoneId(game, source); - Set cardsToExile = controller.getLibrary().getTopCards(game, 5); - for (Card card : cardsToExile) { - controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); - card.setFaceDown(true, game); - } - } - return true; - } - return false; - } - - @Override - public DuplicityEffect copy() { - return new DuplicityEffect(this); - } -} - -class DuplicityExileHandEffect extends OneShotEffect { - - public DuplicityExileHandEffect() { - super(Outcome.Exile); - staticText = "you may exile all cards from your hand face down. If you do, put all other cards you own exiled with {this} into your hand"; - } - - public DuplicityExileHandEffect(final DuplicityExileHandEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null - && sourceObject != null) { - if (!controller.getHand().isEmpty()) { - UUID exileId = CardUtil.getCardExileZoneId(game, source); - Set cardsFromHandToExile = controller.getHand().getCards(game); - for (Card card : cardsFromHandToExile) { - controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); - card.setFaceDown(true, game); - } - Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); - Set cardsToReturnToHandFromExile = new HashSet<>(); - for (Card card : cardsInExile) { - if (!cardsFromHandToExile.contains(card)) { - cardsToReturnToHandFromExile.add(card); - } - } - controller.moveCards(cardsToReturnToHandFromExile, Zone.HAND, source, game); - } - return true; - } - return false; - } - - @Override - public DuplicityExileHandEffect copy() { - return new DuplicityExileHandEffect(this); - } -} - -class LoseControlDuplicity extends DelayedTriggeredAbility { - - public LoseControlDuplicity() { - super(new PutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false); - } - - public LoseControlDuplicity(final LoseControlDuplicity ability) { - super(ability); - } - - @Override - public LoseControlDuplicity copy() { - return new LoseControlDuplicity(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.LOST_CONTROL; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return event.getPlayerId().equals(controllerId); - } - - @Override - public String getRule() { - return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard."; - } -} - -class PutExiledCardsInOwnersGraveyard extends OneShotEffect { - - public PutExiledCardsInOwnersGraveyard() { - super(Outcome.Neutral); - staticText = " put all cards exiled with {this} into their owner's graveyard."; - } - - public PutExiledCardsInOwnersGraveyard(final PutExiledCardsInOwnersGraveyard effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null - && sourceObject != null) { - UUID exileId = CardUtil.getCardExileZoneId(game, source); - Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); - controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED); - return true; - } - return false; - } - - @Override - public PutExiledCardsInOwnersGraveyard copy() { - return new PutExiledCardsInOwnersGraveyard(this); - } -} +package mage.cards.d; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author jeffwadsworth + */ +public final class Duplicity extends CardImpl { + + public Duplicity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); + + // When Duplicity enters the battlefield, exile the top five cards of your library face down. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DuplicityEffect(), false)); + + // At the beginning of your upkeep, you may exile all cards from your hand face down. If you do, put all other cards you own exiled with Duplicity into your hand. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DuplicityExileHandEffect(), TargetController.YOU, true)); + + // At the beginning of your end step, discard a card. + this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new DiscardControllerEffect(1), false)); + + // When you lose control of Duplicity, put all cards exiled with Duplicity into their owner's graveyard. + this.addAbility(new LoseControlDuplicity()); + + } + + public Duplicity(final Duplicity card) { + super(card); + } + + @Override + public Duplicity copy() { + return new Duplicity(this); + } +} + +class DuplicityEffect extends OneShotEffect { + + public DuplicityEffect() { + super(Outcome.Exile); + staticText = "exile the top five cards of your library face down"; + } + + public DuplicityEffect(final DuplicityEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + if (controller.getLibrary().hasCards()) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsToExile = controller.getLibrary().getTopCards(game, 5); + for (Card card : cardsToExile) { + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); + card.setFaceDown(true, game); + } + } + return true; + } + return false; + } + + @Override + public DuplicityEffect copy() { + return new DuplicityEffect(this); + } +} + +class DuplicityExileHandEffect extends OneShotEffect { + + public DuplicityExileHandEffect() { + super(Outcome.Exile); + staticText = "you may exile all cards from your hand face down. If you do, put all other cards you own exiled with {this} into your hand"; + } + + public DuplicityExileHandEffect(final DuplicityExileHandEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + if (!controller.getHand().isEmpty()) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsFromHandToExile = controller.getHand().getCards(game); + for (Card card : cardsFromHandToExile) { + controller.moveCardsToExile(card, source, game, true, exileId, sourceObject.getName()); + card.setFaceDown(true, game); + } + Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); + Set cardsToReturnToHandFromExile = new HashSet<>(); + for (Card card : cardsInExile) { + if (!cardsFromHandToExile.contains(card)) { + cardsToReturnToHandFromExile.add(card); + } + } + controller.moveCards(cardsToReturnToHandFromExile, Zone.HAND, source, game); + } + return true; + } + return false; + } + + @Override + public DuplicityExileHandEffect copy() { + return new DuplicityExileHandEffect(this); + } +} + +class LoseControlDuplicity extends DelayedTriggeredAbility { + + public LoseControlDuplicity() { + super(new PutExiledCardsInOwnersGraveyard(), Duration.EndOfGame, false); + } + + public LoseControlDuplicity(final LoseControlDuplicity ability) { + super(ability); + } + + @Override + public LoseControlDuplicity copy() { + return new LoseControlDuplicity(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LOST_CONTROL; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getPlayerId().equals(controllerId); + } + + @Override + public String getRule() { + return "When you lose control of {this}, put all cards exiled with {this} into their owner's graveyard."; + } +} + +class PutExiledCardsInOwnersGraveyard extends OneShotEffect { + + public PutExiledCardsInOwnersGraveyard() { + super(Outcome.Neutral); + staticText = " put all cards exiled with {this} into their owner's graveyard."; + } + + public PutExiledCardsInOwnersGraveyard(final PutExiledCardsInOwnersGraveyard effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null + && sourceObject != null) { + UUID exileId = CardUtil.getCardExileZoneId(game, source); + Set cardsInExile = game.getExile().getExileZone(exileId).getCards(game); + controller.moveCardsToGraveyardWithInfo(cardsInExile, source, game, Zone.EXILED); + return true; + } + return false; + } + + @Override + public PutExiledCardsInOwnersGraveyard copy() { + return new PutExiledCardsInOwnersGraveyard(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java b/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java index a6c373ffd12..e6eed743932 100644 --- a/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java +++ b/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java @@ -1,4 +1,3 @@ - package mage.cards.p; import java.util.UUID; @@ -11,8 +10,8 @@ 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.SubType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -26,7 +25,7 @@ import mage.target.common.TargetControlledPermanent; public final class ProwlingPangolin extends CardImpl { public ProwlingPangolin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.subtype.add(SubType.BEAST, SubType.PANGOLIN); this.power = new MageInt(6); this.toughness = new MageInt(5); From b7ebff4fa1b423544211c2b8fe2bdc80a83b09d9 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 26 Nov 2018 19:01:18 +0100 Subject: [PATCH 36/50] Fixed verify color check. --- .../java/mage/verify/VerifyCardDataTest.java | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index fb16264f15f..d170b83cd57 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -1,7 +1,18 @@ package mage.verify; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import mage.ObjectColor; -import mage.abilities.keyword.DevoidAbility; import mage.abilities.keyword.MultikickerAbility; import mage.cards.*; import mage.cards.basiclands.BasicLand; @@ -18,19 +29,6 @@ import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.DownloadPictures; import org.reflections.Reflections; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Paths; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - /** * @author JayDi85 */ @@ -108,7 +106,7 @@ public class VerifyCardDataTest { } private int failed = 0; - private ArrayList outputMessages = new ArrayList<>(); + private final ArrayList outputMessages = new ArrayList<>(); @Test public void verifyCards() throws IOException { @@ -353,7 +351,6 @@ public class VerifyCardDataTest { } // TODO: add test to check num cards for rarity (rarityStats > 0 and numRarity > 0) - printMessages(warningsList); printMessages(errorsList); if (errorsList.size() > 0) { @@ -368,7 +365,6 @@ public class VerifyCardDataTest { Collection sets = Sets.getInstance().values(); - // 1. wrong UsesVariousArt settings (set have duplicated card name without that setting -- e.g. cards will have same image) for (ExpansionSet set : sets) { @@ -572,18 +568,18 @@ public class VerifyCardDataTest { if (ref.colors != null) { expected.addAll(ref.colors); } - if(card.isFlipCard()){ + if (card.isFlipCard()) { expected.addAll(ref.colorIdentity); } ObjectColor color = card.getColor(null); if (expected.size() != color.getColorCount() - || (color.isBlack() && !expected.contains("B")) - || (color.isBlue() && !expected.contains("U")) - || (color.isGreen() && !expected.contains("G")) - || (color.isRed() && !expected.contains("R")) - || (color.isWhite() && !expected.contains("W"))) { + || (color.isBlack() && !expected.contains("Black")) + || (color.isBlue() && !expected.contains("Blue")) + || (color.isGreen() && !expected.contains("Green")) + || (color.isRed() && !expected.contains("Red")) + || (color.isWhite() && !expected.contains("White"))) { fail(card, "colors", color + " != " + expected); } } @@ -598,7 +594,7 @@ public class VerifyCardDataTest { // fix names (e.g. Urza’s to Urza's) if (expected != null && expected.contains("Urza’s")) { expected = new ArrayList<>(expected); - for (ListIterator it = ((List) expected).listIterator(); it.hasNext(); ) { + for (ListIterator it = ((List) expected).listIterator(); it.hasNext();) { if (it.next().equals("Urza’s")) { it.set("Urza's"); } From e6ce58d6bfe2c6375b7612f07d40da717a8bc29e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Mon, 26 Nov 2018 19:30:22 +0100 Subject: [PATCH 37/50] XMage 1.4.32V0 --- Mage.Client/pom.xml | 2 +- Mage.Common/pom.xml | 2 +- Mage.Common/src/main/java/mage/utils/MageVersion.java | 4 ++-- Mage.Plugins/Mage.Counter.Plugin/pom.xml | 2 +- Mage.Plugins/pom.xml | 2 +- Mage.Server.Console/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Limited/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml | 2 +- .../Mage.Game.FreeformCommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml | 2 +- .../Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.Human/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml | 2 +- Mage.Server.Plugins/pom.xml | 2 +- Mage.Server/pom.xml | 2 +- Mage.Sets/pom.xml | 2 +- Mage.Stats/pom.xml | 2 +- Mage.Tests/pom.xml | 2 +- Mage.Updater/pom.xml | 2 +- Mage.Verify/pom.xml | 4 ++-- Mage/pom.xml | 2 +- Mage/src/main/java/mage/cards/repository/CardRepository.java | 2 +- pom.xml | 4 ++-- 39 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 35baf24109c..893201b5c1e 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 org.mage diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml index a139eab9600..5eb7a110dab 100644 --- a/Mage.Common/pom.xml +++ b/Mage.Common/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-common diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 4a0feb9728e..d6628b39493 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -13,8 +13,8 @@ public class MageVersion implements Serializable, Comparable { */ public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; - public final static int MAGE_VERSION_PATCH = 31; - public final static String MAGE_VERSION_MINOR_PATCH = "V4"; + public final static int MAGE_VERSION_PATCH = 32; + public final static String MAGE_VERSION_MINOR_PATCH = "V0"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Plugins/Mage.Counter.Plugin/pom.xml b/Mage.Plugins/Mage.Counter.Plugin/pom.xml index a8af62ad9da..27f3f04daa8 100644 --- a/Mage.Plugins/Mage.Counter.Plugin/pom.xml +++ b/Mage.Plugins/Mage.Counter.Plugin/pom.xml @@ -7,7 +7,7 @@ org.mage mage-plugins - 1.4.31 + 1.4.32 mage-counter-plugin diff --git a/Mage.Plugins/pom.xml b/Mage.Plugins/pom.xml index 19abee5bda1..8ae91a6e66c 100644 --- a/Mage.Plugins/pom.xml +++ b/Mage.Plugins/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-plugins diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml index a48379e45c7..ecbbafcdb4c 100644 --- a/Mage.Server.Console/pom.xml +++ b/Mage.Server.Console/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 org.mage diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml index 34ac2c8b537..ae308a042c8 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-deck-constructed diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml index 831c92012e6..98e6f8d47fb 100644 --- a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-deck-limited diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml index be720b6a91e..c8e41100ec6 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-brawlduel diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml index 45666026043..6acd4acfc23 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-brawlfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml index 5b32376a59e..6a96d18e1ea 100644 --- a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-canadianhighlanderduel diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml index 3bc9525794c..6bdd993258d 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-commanderduel diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml index 1888b3a1fb6..159cbc07010 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-commanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml index 239c59dcdf3..9c8f09b34e8 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-freeforall diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml index eaa55ae4e9c..3c49cfae83e 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-freeformcommanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml index e4ec5b48a76..2c78b0d5ad6 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-momirduel diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml index e17bfe1289a..79f3c5abdf1 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-momirfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml index 60538dc66c3..f110bd92500 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-pennydreadfulcommanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml index 111fedc13fb..c0744d767fe 100644 --- a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-tinyleadersduel diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml index 5d5ba7eb623..9f0fcd6fc9d 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-game-twoplayerduel diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml index 75c0e758224..6bf13c4d634 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-ai-draftbot diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml index 9f8a8b0e53d..f5503335224 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-ai-ma diff --git a/Mage.Server.Plugins/Mage.Player.AI/pom.xml b/Mage.Server.Plugins/Mage.Player.AI/pom.xml index 81f988b7341..3d07accfddf 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-ai diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml index d8a75c7fde3..c3c78bb4e93 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-ai-mcts diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml index 1cc373afd2b..1a6103ef54d 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-aiminimax diff --git a/Mage.Server.Plugins/Mage.Player.Human/pom.xml b/Mage.Server.Plugins/Mage.Player.Human/pom.xml index b295f64ad4d..59ecd9969b5 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.Human/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-player-human diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml index f3cecab6e5f..8e791631f4f 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-tournament-boosterdraft diff --git a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml index bec51f060af..91a6ef148f1 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-tournament-constructed diff --git a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml index b9aab5d4f47..d51fc65a620 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.31 + 1.4.32 mage-tournament-sealed diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml index a3ac123d038..6e660046e92 100644 --- a/Mage.Server.Plugins/pom.xml +++ b/Mage.Server.Plugins/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-server-plugins diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index 91d840c5a8c..0f1f7462b2a 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-server diff --git a/Mage.Sets/pom.xml b/Mage.Sets/pom.xml index f478419c232..6f88ade019a 100644 --- a/Mage.Sets/pom.xml +++ b/Mage.Sets/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 org.mage diff --git a/Mage.Stats/pom.xml b/Mage.Stats/pom.xml index 394db54aa1a..6d51c6b7024 100644 --- a/Mage.Stats/pom.xml +++ b/Mage.Stats/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 org.mage diff --git a/Mage.Tests/pom.xml b/Mage.Tests/pom.xml index 1f5e3496407..210ea3d16e4 100644 --- a/Mage.Tests/pom.xml +++ b/Mage.Tests/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-tests diff --git a/Mage.Updater/pom.xml b/Mage.Updater/pom.xml index c9ab517c295..183b4f90e1e 100644 --- a/Mage.Updater/pom.xml +++ b/Mage.Updater/pom.xml @@ -5,7 +5,7 @@ mage-root org.mage - 1.4.31 + 1.4.32 4.0.0 diff --git a/Mage.Verify/pom.xml b/Mage.Verify/pom.xml index cb1f3be8672..fb561bf2371 100644 --- a/Mage.Verify/pom.xml +++ b/Mage.Verify/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage-verify @@ -49,7 +49,7 @@ org.mage mage-client - 1.4.31 + 1.4.32 diff --git a/Mage/pom.xml b/Mage/pom.xml index 5666f64aff8..ecb37107e1a 100644 --- a/Mage/pom.xml +++ b/Mage/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 mage diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index 229b6351a23..c4516c3ccd2 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -32,7 +32,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 51; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 122; + private static final long CARD_CONTENT_VERSION = 123; private Dao cardDao; private Set classNames; diff --git a/pom.xml b/pom.xml index 62c3c3a0d9a..ef3a97cfd4e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.31 + 1.4.32 pom Mage Root Mage Root POM @@ -84,7 +84,7 @@ - 1.4.31 + 1.4.32 UTF-8 From fbf2b5f7b6672652dc36899fb52fd7340fce2cc3 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 26 Nov 2018 15:34:07 -0600 Subject: [PATCH 38/50] - A few fixes for Jace, Architect of Thought. --- .../mage/cards/j/JaceArchitectOfThought.java | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index fbf022f466b..4f6b074b34f 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -1,4 +1,3 @@ - package mage.cards.j; import java.util.ArrayList; @@ -11,7 +10,6 @@ import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.Card; @@ -125,9 +123,9 @@ class JaceArchitectOfThoughtDelayedTriggeredAbility extends DelayedTriggeredAbil @Override public boolean checkTrigger(GameEvent event, Game game) { if (game.getOpponents(getControllerId()).contains(event.getPlayerId())) { - for (Effect effect : getEffects()) { + getEffects().forEach((effect) -> { effect.setTargetPointer(new FixedTarget(event.getSourceId())); - } + }); return true; } return false; @@ -186,7 +184,6 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect { if (opponent == null) { opponent = game.getPlayer(opponents.iterator().next()); } - TargetCard target = new TargetCard(0, allCards.size(), Zone.LIBRARY, new FilterCard("cards to put in the first pile")); target.setNotTarget(true); opponent.choose(Outcome.Neutral, allCards, target, game); @@ -212,9 +209,9 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect { private void postPileToLog(String pileName, Set cards, Game game) { StringBuilder message = new StringBuilder(pileName).append(": "); - for (Card card : cards) { + cards.forEach((card) -> { message.append(card.getName()).append(' '); - } + }); if (cards.isEmpty()) { message.append(" (empty)"); } @@ -255,9 +252,9 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { while (!playerList.isEmpty()) { FilterPlayer filter = new FilterPlayer(); List playerPredicates = new ArrayList<>(); - for (UUID playerId : playerList) { + playerList.forEach((playerId) -> { playerPredicates.add(new PlayerIdPredicate(playerId)); - } + }); filter.add(Predicates.or(playerPredicates)); TargetPlayer targetPlayer = new TargetPlayer(1, 1, true, filter); targetPlayer.setRequired(!checkList.containsAll(playerList)); @@ -275,7 +272,7 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { UUID targetId = target.getFirstTarget(); Card card = player.getLibrary().remove(targetId, game); if (card != null) { - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + controller.moveCardsToExile(card, source, game, true, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName()); playerList.remove(playerId); } } else { @@ -287,26 +284,23 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { } else { break; } - for (UUID playerId : playerList) { - Player player = game.getPlayer(playerId); - if (player == null || !player.canRespond()) { - playerList.remove(player); - } - } - } - for (UUID playerId : checkList) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.shuffleLibrary(source, game); - } + playerList.stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player == null + || !player.canRespond())).forEachOrdered((player) -> { + playerList.remove(player.getId()); + }); } + checkList.stream().map((playerId) -> game.getPlayer(playerId)).filter((player) -> (player != null)).forEachOrdered((player) -> { + player.shuffleLibrary(source, game); + }); ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; } FilterCard filter = new FilterCard("card to cast without mana costs"); TargetCardInExile target = new TargetCardInExile(filter, source.getSourceId()); - while (jaceExileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, jaceExileZone, target, game)) { + while (jaceExileZone.count(filter, game) > 0 + && controller.chooseUse(Outcome.Benefit, "Cast another spell from exile zone for free?", source, game)) { + controller.choose(Outcome.PlayForFree, jaceExileZone, target, game); Card card = game.getCard(target.getFirstTarget()); if (card != null) { if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) { From 8addea6891188f9a8f1ec7d799f4f547c3f4d03e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 27 Nov 2018 00:29:47 +0100 Subject: [PATCH 39/50] Removed debug message. --- .../main/java/mage/abilities/meta/OrTriggeredAbility.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java index 1f0723298d2..6882a8886ca 100644 --- a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java @@ -1,5 +1,8 @@ package mage.abilities.meta; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -8,10 +11,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.watchers.Watcher; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * A triggered ability that combines several others and triggers whenever one or * more of them would. The abilities passed in should have null as their effect, @@ -56,7 +55,6 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { for (TriggeredAbility ability : triggeredAbilities) { if (ability.checkEventType(event, game)) { - System.out.println("Correct event type (" + event.getType() + ")"); return true; } } From 6c55ede2c252239075dafb3c4bdaee648b770b95 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 27 Nov 2018 00:37:48 +0100 Subject: [PATCH 40/50] Removed debug message. --- Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java index 6882a8886ca..0a4a17cb4c2 100644 --- a/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/meta/OrTriggeredAbility.java @@ -67,11 +67,9 @@ public class OrTriggeredAbility extends TriggeredAbilityImpl { for (int i = 0; i < triggeredAbilities.length; i++) { TriggeredAbility ability = triggeredAbilities[i]; if (ability.checkEventType(event, game) && ability.checkTrigger(event, game)) { - System.out.println("Triggered from " + ability.getRule()); triggeringAbilities.add(i); toRet = true; } - System.out.println("Checked " + ability.getRule()); } return toRet; } From eb996716bc86288050ee445aff54da21931d9fb6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 26 Nov 2018 17:57:15 -0600 Subject: [PATCH 41/50] - Added Walking Dream and Mogg Bombers. --- Mage.Sets/src/mage/cards/m/MoggBombers.java | 60 ++++ Mage.Sets/src/mage/cards/w/WalkingDream.java | 59 ++++ Mage.Sets/src/mage/sets/Stronghold.java | 334 ++++++++++--------- 3 files changed, 287 insertions(+), 166 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/MoggBombers.java create mode 100644 Mage.Sets/src/mage/cards/w/WalkingDream.java diff --git a/Mage.Sets/src/mage/cards/m/MoggBombers.java b/Mage.Sets/src/mage/cards/m/MoggBombers.java new file mode 100644 index 00000000000..65700c1643e --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoggBombers.java @@ -0,0 +1,60 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class MoggBombers extends CardImpl { + + private static final String rule = "When another creature enters the battlefield, sacrifice {this} and it deals 3 damage to target player."; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public MoggBombers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When another creature enters the battlefield, sacrifice Mogg Bombers and it deals 3 damage to target player. + Effect sacrificeMoggBombers = new SacrificeSourceEffect(); + Effect damageTargetPlayer = new DamageTargetEffect(3); + Ability ability = new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, + sacrificeMoggBombers, + filter, false, rule); + ability.addEffect(damageTargetPlayer); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + } + + public MoggBombers(final MoggBombers card) { + super(card); + } + + @Override + public MoggBombers copy() { + return new MoggBombers(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WalkingDream.java b/Mage.Sets/src/mage/cards/w/WalkingDream.java new file mode 100644 index 00000000000..30cacb3dae8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WalkingDream.java @@ -0,0 +1,59 @@ +package mage.cards.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; +import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; +import mage.abilities.effects.ContinuousRuleModifyingEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.keyword.CantBeBlockedSourceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public final class WalkingDream extends CardImpl { + + private static final String rule = "{this} doesn't untap during your untap step if an opponent controls two or more creatures."; + + public WalkingDream(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.ILLUSION); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Walking Dream is unblockable. + this.addAbility(new CantBeBlockedSourceAbility()); + + // Walking Dream doesn't untap during your untap step if an opponent controls two or more creatures. + ContinuousRuleModifyingEffect dontUntap = new DontUntapInControllersUntapStepSourceEffect(false, true); + dontUntap.setText(rule); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousRuleModifyingEffect( + dontUntap, + new OpponentControlsPermanentCondition( + new FilterCreaturePermanent(), + ComparisonType.MORE_THAN, 1))); + this.addAbility(ability); + + } + + public WalkingDream(final WalkingDream card) { + super(card); + } + + @Override + public WalkingDream copy() { + return new WalkingDream(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Stronghold.java b/Mage.Sets/src/mage/sets/Stronghold.java index 03ae248545b..0fe9bdb4cad 100644 --- a/Mage.Sets/src/mage/sets/Stronghold.java +++ b/Mage.Sets/src/mage/sets/Stronghold.java @@ -1,166 +1,168 @@ - -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * @author North - */ -public final class Stronghold extends ExpansionSet { - - private static final Stronghold instance = new Stronghold(); - - public static Stronghold getInstance() { - return instance; - } - - private Stronghold() { - super("Stronghold", "STH", ExpansionSet.buildDate(1998, 3, 2), SetType.EXPANSION); - this.blockName = "Tempest"; - this.parentSet = Tempest.getInstance(); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Acidic Sliver", 126, Rarity.UNCOMMON, mage.cards.a.AcidicSliver.class)); - cards.add(new SetCardInfo("Amok", 76, Rarity.RARE, mage.cards.a.Amok.class)); - cards.add(new SetCardInfo("Awakening", 101, Rarity.RARE, mage.cards.a.Awakening.class)); - cards.add(new SetCardInfo("Bandage", 1, Rarity.COMMON, mage.cards.b.Bandage.class)); - cards.add(new SetCardInfo("Bottomless Pit", 51, Rarity.UNCOMMON, mage.cards.b.BottomlessPit.class)); - cards.add(new SetCardInfo("Brush with Death", 52, Rarity.COMMON, mage.cards.b.BrushWithDeath.class)); - cards.add(new SetCardInfo("Bullwhip", 132, Rarity.UNCOMMON, mage.cards.b.Bullwhip.class)); - cards.add(new SetCardInfo("Burgeoning", 102, Rarity.RARE, mage.cards.b.Burgeoning.class)); - cards.add(new SetCardInfo("Calming Licid", 2, Rarity.UNCOMMON, mage.cards.c.CalmingLicid.class)); - cards.add(new SetCardInfo("Cannibalize", 53, Rarity.COMMON, mage.cards.c.Cannibalize.class)); - cards.add(new SetCardInfo("Carnassid", 103, Rarity.RARE, mage.cards.c.Carnassid.class)); - cards.add(new SetCardInfo("Change of Heart", 3, Rarity.COMMON, mage.cards.c.ChangeOfHeart.class)); - cards.add(new SetCardInfo("Cloud Spirit", 26, Rarity.COMMON, mage.cards.c.CloudSpirit.class)); - cards.add(new SetCardInfo("Constant Mists", 104, Rarity.UNCOMMON, mage.cards.c.ConstantMists.class)); - cards.add(new SetCardInfo("Contemplation", 4, Rarity.UNCOMMON, mage.cards.c.Contemplation.class)); - cards.add(new SetCardInfo("Conviction", 5, Rarity.COMMON, mage.cards.c.Conviction.class)); - cards.add(new SetCardInfo("Convulsing Licid", 77, Rarity.UNCOMMON, mage.cards.c.ConvulsingLicid.class)); - cards.add(new SetCardInfo("Corrupting Licid", 54, Rarity.UNCOMMON, mage.cards.c.CorruptingLicid.class)); - cards.add(new SetCardInfo("Craven Giant", 78, Rarity.COMMON, mage.cards.c.CravenGiant.class)); - cards.add(new SetCardInfo("Crossbow Ambush", 105, Rarity.COMMON, mage.cards.c.CrossbowAmbush.class)); - cards.add(new SetCardInfo("Crovax the Cursed", 55, Rarity.RARE, mage.cards.c.CrovaxTheCursed.class)); - cards.add(new SetCardInfo("Crystalline Sliver", 127, Rarity.UNCOMMON, mage.cards.c.CrystallineSliver.class)); - cards.add(new SetCardInfo("Dauthi Trapper", 56, Rarity.UNCOMMON, mage.cards.d.DauthiTrapper.class)); - cards.add(new SetCardInfo("Death Stroke", 57, Rarity.COMMON, mage.cards.d.DeathStroke.class)); - cards.add(new SetCardInfo("Dream Halls", 28, Rarity.RARE, mage.cards.d.DreamHalls.class)); - cards.add(new SetCardInfo("Dream Prowler", 29, Rarity.COMMON, mage.cards.d.DreamProwler.class)); - cards.add(new SetCardInfo("Duct Crawler", 79, Rarity.COMMON, mage.cards.d.DuctCrawler.class)); - cards.add(new SetCardInfo("Dungeon Shade", 58, Rarity.COMMON, mage.cards.d.DungeonShade.class)); - cards.add(new SetCardInfo("Elven Rite", 106, Rarity.UNCOMMON, mage.cards.e.ElvenRite.class)); - cards.add(new SetCardInfo("Endangered Armodon", 107, Rarity.COMMON, mage.cards.e.EndangeredArmodon.class)); - cards.add(new SetCardInfo("Ensnaring Bridge", 133, Rarity.RARE, mage.cards.e.EnsnaringBridge.class)); - cards.add(new SetCardInfo("Evacuation", 30, Rarity.RARE, mage.cards.e.Evacuation.class)); - cards.add(new SetCardInfo("Fanning the Flames", 80, Rarity.UNCOMMON, mage.cards.f.FanningTheFlames.class)); - cards.add(new SetCardInfo("Flame Wave", 81, Rarity.UNCOMMON, mage.cards.f.FlameWave.class)); - cards.add(new SetCardInfo("Fling", 82, Rarity.COMMON, mage.cards.f.Fling.class)); - cards.add(new SetCardInfo("Flowstone Blade", 83, Rarity.COMMON, mage.cards.f.FlowstoneBlade.class)); - cards.add(new SetCardInfo("Flowstone Hellion", 84, Rarity.UNCOMMON, mage.cards.f.FlowstoneHellion.class)); - cards.add(new SetCardInfo("Flowstone Mauler", 85, Rarity.RARE, mage.cards.f.FlowstoneMauler.class)); - cards.add(new SetCardInfo("Flowstone Shambler", 86, Rarity.COMMON, mage.cards.f.FlowstoneShambler.class)); - cards.add(new SetCardInfo("Foul Imp", 59, Rarity.COMMON, mage.cards.f.FoulImp.class)); - cards.add(new SetCardInfo("Furnace Spirit", 87, Rarity.COMMON, mage.cards.f.FurnaceSpirit.class)); - cards.add(new SetCardInfo("Gliding Licid", 31, Rarity.UNCOMMON, mage.cards.g.GlidingLicid.class)); - cards.add(new SetCardInfo("Grave Pact", 60, Rarity.RARE, mage.cards.g.GravePact.class)); - cards.add(new SetCardInfo("Hammerhead Shark", 32, Rarity.COMMON, mage.cards.h.HammerheadShark.class)); - cards.add(new SetCardInfo("Heartstone", 134, Rarity.UNCOMMON, mage.cards.h.Heartstone.class)); - cards.add(new SetCardInfo("Heat of Battle", 88, Rarity.UNCOMMON, mage.cards.h.HeatOfBattle.class)); - cards.add(new SetCardInfo("Hermit Druid", 108, Rarity.RARE, mage.cards.h.HermitDruid.class)); - cards.add(new SetCardInfo("Hesitation", 33, Rarity.UNCOMMON, mage.cards.h.Hesitation.class)); - cards.add(new SetCardInfo("Hibernation Sliver", 128, Rarity.UNCOMMON, mage.cards.h.HibernationSliver.class)); - cards.add(new SetCardInfo("Honor Guard", 7, Rarity.COMMON, mage.cards.h.HonorGuard.class)); - cards.add(new SetCardInfo("Horn of Greed", 135, Rarity.RARE, mage.cards.h.HornOfGreed.class)); - cards.add(new SetCardInfo("Hornet Cannon", 136, Rarity.UNCOMMON, mage.cards.h.HornetCannon.class)); - cards.add(new SetCardInfo("Intruder Alarm", 34, Rarity.RARE, mage.cards.i.IntruderAlarm.class)); - cards.add(new SetCardInfo("Invasion Plans", 89, Rarity.RARE, mage.cards.i.InvasionPlans.class)); - cards.add(new SetCardInfo("Jinxed Ring", 137, Rarity.RARE, mage.cards.j.JinxedRing.class)); - cards.add(new SetCardInfo("Lab Rats", 61, Rarity.COMMON, mage.cards.l.LabRats.class)); - cards.add(new SetCardInfo("Lancers en-Kor", 8, Rarity.UNCOMMON, mage.cards.l.LancersEnKor.class)); - cards.add(new SetCardInfo("Leap", 35, Rarity.COMMON, mage.cards.l.Leap.class)); - cards.add(new SetCardInfo("Lowland Basilisk", 109, Rarity.COMMON, mage.cards.l.LowlandBasilisk.class)); - cards.add(new SetCardInfo("Mana Leak", 36, Rarity.COMMON, mage.cards.m.ManaLeak.class)); - cards.add(new SetCardInfo("Mask of the Mimic", 37, Rarity.UNCOMMON, mage.cards.m.MaskOfTheMimic.class)); - cards.add(new SetCardInfo("Megrim", 62, Rarity.UNCOMMON, mage.cards.m.Megrim.class)); - cards.add(new SetCardInfo("Mind Games", 38, Rarity.COMMON, mage.cards.m.MindGames.class)); - cards.add(new SetCardInfo("Mind Peel", 63, Rarity.UNCOMMON, mage.cards.m.MindPeel.class)); - cards.add(new SetCardInfo("Mindwarper", 64, Rarity.RARE, mage.cards.m.Mindwarper.class)); - cards.add(new SetCardInfo("Mob Justice", 90, Rarity.COMMON, mage.cards.m.MobJustice.class)); - cards.add(new SetCardInfo("Mogg Flunkies", 92, Rarity.COMMON, mage.cards.m.MoggFlunkies.class)); - cards.add(new SetCardInfo("Mogg Infestation", 93, Rarity.RARE, mage.cards.m.MoggInfestation.class)); - cards.add(new SetCardInfo("Mogg Maniac", 94, Rarity.UNCOMMON, mage.cards.m.MoggManiac.class)); - cards.add(new SetCardInfo("Morgue Thrull", 65, Rarity.COMMON, mage.cards.m.MorgueThrull.class)); - cards.add(new SetCardInfo("Mortuary", 66, Rarity.RARE, mage.cards.m.Mortuary.class)); - cards.add(new SetCardInfo("Mox Diamond", 138, Rarity.RARE, mage.cards.m.MoxDiamond.class)); - cards.add(new SetCardInfo("Mulch", 110, Rarity.COMMON, mage.cards.m.Mulch.class)); - cards.add(new SetCardInfo("Nomads en-Kor", 9, Rarity.COMMON, mage.cards.n.NomadsEnKor.class)); - cards.add(new SetCardInfo("Overgrowth", 111, Rarity.COMMON, mage.cards.o.Overgrowth.class)); - cards.add(new SetCardInfo("Portcullis", 139, Rarity.RARE, mage.cards.p.Portcullis.class)); - cards.add(new SetCardInfo("Primal Rage", 112, Rarity.UNCOMMON, mage.cards.p.PrimalRage.class)); - cards.add(new SetCardInfo("Provoke", 113, Rarity.COMMON, mage.cards.p.Provoke.class)); - cards.add(new SetCardInfo("Pursuit of Knowledge", 10, Rarity.RARE, mage.cards.p.PursuitOfKnowledge.class)); - cards.add(new SetCardInfo("Rabid Rats", 67, Rarity.COMMON, mage.cards.r.RabidRats.class)); - cards.add(new SetCardInfo("Reins of Power", 41, Rarity.RARE, mage.cards.r.ReinsOfPower.class)); - cards.add(new SetCardInfo("Revenant", 68, Rarity.RARE, mage.cards.r.Revenant.class)); - cards.add(new SetCardInfo("Rolling Stones", 11, Rarity.RARE, mage.cards.r.RollingStones.class)); - cards.add(new SetCardInfo("Ruination", 95, Rarity.RARE, mage.cards.r.Ruination.class)); - cards.add(new SetCardInfo("Sacred Ground", 12, Rarity.RARE, mage.cards.s.SacredGround.class)); - cards.add(new SetCardInfo("Scapegoat", 14, Rarity.UNCOMMON, mage.cards.s.Scapegoat.class)); - cards.add(new SetCardInfo("Seething Anger", 96, Rarity.COMMON, mage.cards.s.SeethingAnger.class)); - cards.add(new SetCardInfo("Serpent Warrior", 69, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); - cards.add(new SetCardInfo("Shaman en-Kor", 15, Rarity.RARE, mage.cards.s.ShamanEnKor.class)); - cards.add(new SetCardInfo("Shard Phoenix", 97, Rarity.RARE, mage.cards.s.ShardPhoenix.class)); - cards.add(new SetCardInfo("Shifting Wall", 140, Rarity.UNCOMMON, mage.cards.s.ShiftingWall.class)); - cards.add(new SetCardInfo("Shock", 98, Rarity.COMMON, mage.cards.s.Shock.class)); - cards.add(new SetCardInfo("Sift", 42, Rarity.COMMON, mage.cards.s.Sift.class)); - cards.add(new SetCardInfo("Silver Wyvern", 43, Rarity.RARE, mage.cards.s.SilverWyvern.class)); - cards.add(new SetCardInfo("Skyshroud Archer", 114, Rarity.COMMON, mage.cards.s.SkyshroudArcher.class)); - cards.add(new SetCardInfo("Skyshroud Falcon", 16, Rarity.COMMON, mage.cards.s.SkyshroudFalcon.class)); - cards.add(new SetCardInfo("Skyshroud Troopers", 115, Rarity.COMMON, mage.cards.s.SkyshroudTroopers.class)); - cards.add(new SetCardInfo("Sliver Queen", 129, Rarity.RARE, mage.cards.s.SliverQueen.class)); - cards.add(new SetCardInfo("Smite", 17, Rarity.COMMON, mage.cards.s.Smite.class)); - cards.add(new SetCardInfo("Soltari Champion", 18, Rarity.RARE, mage.cards.s.SoltariChampion.class)); - cards.add(new SetCardInfo("Spike Breeder", 116, Rarity.RARE, mage.cards.s.SpikeBreeder.class)); - cards.add(new SetCardInfo("Spike Colony", 117, Rarity.COMMON, mage.cards.s.SpikeColony.class)); - cards.add(new SetCardInfo("Spike Feeder", 118, Rarity.UNCOMMON, mage.cards.s.SpikeFeeder.class)); - cards.add(new SetCardInfo("Spike Soldier", 119, Rarity.UNCOMMON, mage.cards.s.SpikeSoldier.class)); - cards.add(new SetCardInfo("Spike Worker", 120, Rarity.COMMON, mage.cards.s.SpikeWorker.class)); - cards.add(new SetCardInfo("Spindrift Drake", 44, Rarity.COMMON, mage.cards.s.SpindriftDrake.class)); - cards.add(new SetCardInfo("Spined Sliver", 130, Rarity.UNCOMMON, mage.cards.s.SpinedSliver.class)); - cards.add(new SetCardInfo("Spined Wurm", 121, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); - cards.add(new SetCardInfo("Spirit en-Kor", 19, Rarity.COMMON, mage.cards.s.SpiritEnKor.class)); - cards.add(new SetCardInfo("Spitting Hydra", 99, Rarity.RARE, mage.cards.s.SpittingHydra.class)); - cards.add(new SetCardInfo("Stronghold Assassin", 71, Rarity.RARE, mage.cards.s.StrongholdAssassin.class)); - cards.add(new SetCardInfo("Stronghold Taskmaster", 72, Rarity.UNCOMMON, mage.cards.s.StrongholdTaskmaster.class)); - cards.add(new SetCardInfo("Sword of the Chosen", 141, Rarity.RARE, mage.cards.s.SwordOfTheChosen.class)); - cards.add(new SetCardInfo("Temper", 20, Rarity.UNCOMMON, mage.cards.t.Temper.class)); - cards.add(new SetCardInfo("Tempting Licid", 122, Rarity.UNCOMMON, mage.cards.t.TemptingLicid.class)); - cards.add(new SetCardInfo("Thalakos Deceiver", 45, Rarity.RARE, mage.cards.t.ThalakosDeceiver.class)); - cards.add(new SetCardInfo("Tidal Surge", 46, Rarity.COMMON, mage.cards.t.TidalSurge.class)); - cards.add(new SetCardInfo("Tidal Warrior", 47, Rarity.COMMON, mage.cards.t.TidalWarrior.class)); - cards.add(new SetCardInfo("Torment", 73, Rarity.COMMON, mage.cards.t.Torment.class)); - cards.add(new SetCardInfo("Tortured Existence", 74, Rarity.COMMON, mage.cards.t.TorturedExistence.class)); - cards.add(new SetCardInfo("Venerable Monk", 21, Rarity.COMMON, mage.cards.v.VenerableMonk.class)); - cards.add(new SetCardInfo("Verdant Touch", 123, Rarity.RARE, mage.cards.v.VerdantTouch.class)); - cards.add(new SetCardInfo("Victual Sliver", 131, Rarity.UNCOMMON, mage.cards.v.VictualSliver.class)); - cards.add(new SetCardInfo("Volrath's Gardens", 124, Rarity.RARE, mage.cards.v.VolrathsGardens.class)); - cards.add(new SetCardInfo("Volrath's Laboratory", 142, Rarity.RARE, mage.cards.v.VolrathsLaboratory.class)); - cards.add(new SetCardInfo("Volrath's Shapeshifter", 48, Rarity.RARE, mage.cards.v.VolrathsShapeshifter.class)); - cards.add(new SetCardInfo("Volrath's Stronghold", 143, Rarity.RARE, mage.cards.v.VolrathsStronghold.class)); - cards.add(new SetCardInfo("Wall of Blossoms", 125, Rarity.UNCOMMON, mage.cards.w.WallOfBlossoms.class)); - cards.add(new SetCardInfo("Wall of Essence", 22, Rarity.UNCOMMON, mage.cards.w.WallOfEssence.class)); - cards.add(new SetCardInfo("Wall of Razors", 100, Rarity.UNCOMMON, mage.cards.w.WallOfRazors.class)); - cards.add(new SetCardInfo("Wall of Souls", 75, Rarity.UNCOMMON, mage.cards.w.WallOfSouls.class)); - cards.add(new SetCardInfo("Wall of Tears", 50, Rarity.UNCOMMON, mage.cards.w.WallOfTears.class)); - cards.add(new SetCardInfo("Warrior Angel", 24, Rarity.RARE, mage.cards.w.WarriorAngel.class)); - cards.add(new SetCardInfo("Warrior en-Kor", 23, Rarity.UNCOMMON, mage.cards.w.WarriorEnKor.class)); - cards.add(new SetCardInfo("Youthful Knight", 25, Rarity.COMMON, mage.cards.y.YouthfulKnight.class)); - } -} + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author North + */ +public final class Stronghold extends ExpansionSet { + + private static final Stronghold instance = new Stronghold(); + + public static Stronghold getInstance() { + return instance; + } + + private Stronghold() { + super("Stronghold", "STH", ExpansionSet.buildDate(1998, 3, 2), SetType.EXPANSION); + this.blockName = "Tempest"; + this.parentSet = Tempest.getInstance(); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Acidic Sliver", 126, Rarity.UNCOMMON, mage.cards.a.AcidicSliver.class)); + cards.add(new SetCardInfo("Amok", 76, Rarity.RARE, mage.cards.a.Amok.class)); + cards.add(new SetCardInfo("Awakening", 101, Rarity.RARE, mage.cards.a.Awakening.class)); + cards.add(new SetCardInfo("Bandage", 1, Rarity.COMMON, mage.cards.b.Bandage.class)); + cards.add(new SetCardInfo("Bottomless Pit", 51, Rarity.UNCOMMON, mage.cards.b.BottomlessPit.class)); + cards.add(new SetCardInfo("Brush with Death", 52, Rarity.COMMON, mage.cards.b.BrushWithDeath.class)); + cards.add(new SetCardInfo("Bullwhip", 132, Rarity.UNCOMMON, mage.cards.b.Bullwhip.class)); + cards.add(new SetCardInfo("Burgeoning", 102, Rarity.RARE, mage.cards.b.Burgeoning.class)); + cards.add(new SetCardInfo("Calming Licid", 2, Rarity.UNCOMMON, mage.cards.c.CalmingLicid.class)); + cards.add(new SetCardInfo("Cannibalize", 53, Rarity.COMMON, mage.cards.c.Cannibalize.class)); + cards.add(new SetCardInfo("Carnassid", 103, Rarity.RARE, mage.cards.c.Carnassid.class)); + cards.add(new SetCardInfo("Change of Heart", 3, Rarity.COMMON, mage.cards.c.ChangeOfHeart.class)); + cards.add(new SetCardInfo("Cloud Spirit", 26, Rarity.COMMON, mage.cards.c.CloudSpirit.class)); + cards.add(new SetCardInfo("Constant Mists", 104, Rarity.UNCOMMON, mage.cards.c.ConstantMists.class)); + cards.add(new SetCardInfo("Contemplation", 4, Rarity.UNCOMMON, mage.cards.c.Contemplation.class)); + cards.add(new SetCardInfo("Conviction", 5, Rarity.COMMON, mage.cards.c.Conviction.class)); + cards.add(new SetCardInfo("Convulsing Licid", 77, Rarity.UNCOMMON, mage.cards.c.ConvulsingLicid.class)); + cards.add(new SetCardInfo("Corrupting Licid", 54, Rarity.UNCOMMON, mage.cards.c.CorruptingLicid.class)); + cards.add(new SetCardInfo("Craven Giant", 78, Rarity.COMMON, mage.cards.c.CravenGiant.class)); + cards.add(new SetCardInfo("Crossbow Ambush", 105, Rarity.COMMON, mage.cards.c.CrossbowAmbush.class)); + cards.add(new SetCardInfo("Crovax the Cursed", 55, Rarity.RARE, mage.cards.c.CrovaxTheCursed.class)); + cards.add(new SetCardInfo("Crystalline Sliver", 127, Rarity.UNCOMMON, mage.cards.c.CrystallineSliver.class)); + cards.add(new SetCardInfo("Dauthi Trapper", 56, Rarity.UNCOMMON, mage.cards.d.DauthiTrapper.class)); + cards.add(new SetCardInfo("Death Stroke", 57, Rarity.COMMON, mage.cards.d.DeathStroke.class)); + cards.add(new SetCardInfo("Dream Halls", 28, Rarity.RARE, mage.cards.d.DreamHalls.class)); + cards.add(new SetCardInfo("Dream Prowler", 29, Rarity.COMMON, mage.cards.d.DreamProwler.class)); + cards.add(new SetCardInfo("Duct Crawler", 79, Rarity.COMMON, mage.cards.d.DuctCrawler.class)); + cards.add(new SetCardInfo("Dungeon Shade", 58, Rarity.COMMON, mage.cards.d.DungeonShade.class)); + cards.add(new SetCardInfo("Elven Rite", 106, Rarity.UNCOMMON, mage.cards.e.ElvenRite.class)); + cards.add(new SetCardInfo("Endangered Armodon", 107, Rarity.COMMON, mage.cards.e.EndangeredArmodon.class)); + cards.add(new SetCardInfo("Ensnaring Bridge", 133, Rarity.RARE, mage.cards.e.EnsnaringBridge.class)); + cards.add(new SetCardInfo("Evacuation", 30, Rarity.RARE, mage.cards.e.Evacuation.class)); + cards.add(new SetCardInfo("Fanning the Flames", 80, Rarity.UNCOMMON, mage.cards.f.FanningTheFlames.class)); + cards.add(new SetCardInfo("Flame Wave", 81, Rarity.UNCOMMON, mage.cards.f.FlameWave.class)); + cards.add(new SetCardInfo("Fling", 82, Rarity.COMMON, mage.cards.f.Fling.class)); + cards.add(new SetCardInfo("Flowstone Blade", 83, Rarity.COMMON, mage.cards.f.FlowstoneBlade.class)); + cards.add(new SetCardInfo("Flowstone Hellion", 84, Rarity.UNCOMMON, mage.cards.f.FlowstoneHellion.class)); + cards.add(new SetCardInfo("Flowstone Mauler", 85, Rarity.RARE, mage.cards.f.FlowstoneMauler.class)); + cards.add(new SetCardInfo("Flowstone Shambler", 86, Rarity.COMMON, mage.cards.f.FlowstoneShambler.class)); + cards.add(new SetCardInfo("Foul Imp", 59, Rarity.COMMON, mage.cards.f.FoulImp.class)); + cards.add(new SetCardInfo("Furnace Spirit", 87, Rarity.COMMON, mage.cards.f.FurnaceSpirit.class)); + cards.add(new SetCardInfo("Gliding Licid", 31, Rarity.UNCOMMON, mage.cards.g.GlidingLicid.class)); + cards.add(new SetCardInfo("Grave Pact", 60, Rarity.RARE, mage.cards.g.GravePact.class)); + cards.add(new SetCardInfo("Hammerhead Shark", 32, Rarity.COMMON, mage.cards.h.HammerheadShark.class)); + cards.add(new SetCardInfo("Heartstone", 134, Rarity.UNCOMMON, mage.cards.h.Heartstone.class)); + cards.add(new SetCardInfo("Heat of Battle", 88, Rarity.UNCOMMON, mage.cards.h.HeatOfBattle.class)); + cards.add(new SetCardInfo("Hermit Druid", 108, Rarity.RARE, mage.cards.h.HermitDruid.class)); + cards.add(new SetCardInfo("Hesitation", 33, Rarity.UNCOMMON, mage.cards.h.Hesitation.class)); + cards.add(new SetCardInfo("Hibernation Sliver", 128, Rarity.UNCOMMON, mage.cards.h.HibernationSliver.class)); + cards.add(new SetCardInfo("Honor Guard", 7, Rarity.COMMON, mage.cards.h.HonorGuard.class)); + cards.add(new SetCardInfo("Horn of Greed", 135, Rarity.RARE, mage.cards.h.HornOfGreed.class)); + cards.add(new SetCardInfo("Hornet Cannon", 136, Rarity.UNCOMMON, mage.cards.h.HornetCannon.class)); + cards.add(new SetCardInfo("Intruder Alarm", 34, Rarity.RARE, mage.cards.i.IntruderAlarm.class)); + cards.add(new SetCardInfo("Invasion Plans", 89, Rarity.RARE, mage.cards.i.InvasionPlans.class)); + cards.add(new SetCardInfo("Jinxed Ring", 137, Rarity.RARE, mage.cards.j.JinxedRing.class)); + cards.add(new SetCardInfo("Lab Rats", 61, Rarity.COMMON, mage.cards.l.LabRats.class)); + cards.add(new SetCardInfo("Lancers en-Kor", 8, Rarity.UNCOMMON, mage.cards.l.LancersEnKor.class)); + cards.add(new SetCardInfo("Leap", 35, Rarity.COMMON, mage.cards.l.Leap.class)); + cards.add(new SetCardInfo("Lowland Basilisk", 109, Rarity.COMMON, mage.cards.l.LowlandBasilisk.class)); + cards.add(new SetCardInfo("Mana Leak", 36, Rarity.COMMON, mage.cards.m.ManaLeak.class)); + cards.add(new SetCardInfo("Mask of the Mimic", 37, Rarity.UNCOMMON, mage.cards.m.MaskOfTheMimic.class)); + cards.add(new SetCardInfo("Megrim", 62, Rarity.UNCOMMON, mage.cards.m.Megrim.class)); + cards.add(new SetCardInfo("Mind Games", 38, Rarity.COMMON, mage.cards.m.MindGames.class)); + cards.add(new SetCardInfo("Mind Peel", 63, Rarity.UNCOMMON, mage.cards.m.MindPeel.class)); + cards.add(new SetCardInfo("Mindwarper", 64, Rarity.RARE, mage.cards.m.Mindwarper.class)); + cards.add(new SetCardInfo("Mob Justice", 90, Rarity.COMMON, mage.cards.m.MobJustice.class)); + cards.add(new SetCardInfo("Mogg Bombers", 91, Rarity.COMMON, mage.cards.m.MoggBombers.class)); + cards.add(new SetCardInfo("Mogg Flunkies", 92, Rarity.COMMON, mage.cards.m.MoggFlunkies.class)); + cards.add(new SetCardInfo("Mogg Infestation", 93, Rarity.RARE, mage.cards.m.MoggInfestation.class)); + cards.add(new SetCardInfo("Mogg Maniac", 94, Rarity.UNCOMMON, mage.cards.m.MoggManiac.class)); + cards.add(new SetCardInfo("Morgue Thrull", 65, Rarity.COMMON, mage.cards.m.MorgueThrull.class)); + cards.add(new SetCardInfo("Mortuary", 66, Rarity.RARE, mage.cards.m.Mortuary.class)); + cards.add(new SetCardInfo("Mox Diamond", 138, Rarity.RARE, mage.cards.m.MoxDiamond.class)); + cards.add(new SetCardInfo("Mulch", 110, Rarity.COMMON, mage.cards.m.Mulch.class)); + cards.add(new SetCardInfo("Nomads en-Kor", 9, Rarity.COMMON, mage.cards.n.NomadsEnKor.class)); + cards.add(new SetCardInfo("Overgrowth", 111, Rarity.COMMON, mage.cards.o.Overgrowth.class)); + cards.add(new SetCardInfo("Portcullis", 139, Rarity.RARE, mage.cards.p.Portcullis.class)); + cards.add(new SetCardInfo("Primal Rage", 112, Rarity.UNCOMMON, mage.cards.p.PrimalRage.class)); + cards.add(new SetCardInfo("Provoke", 113, Rarity.COMMON, mage.cards.p.Provoke.class)); + cards.add(new SetCardInfo("Pursuit of Knowledge", 10, Rarity.RARE, mage.cards.p.PursuitOfKnowledge.class)); + cards.add(new SetCardInfo("Rabid Rats", 67, Rarity.COMMON, mage.cards.r.RabidRats.class)); + cards.add(new SetCardInfo("Reins of Power", 41, Rarity.RARE, mage.cards.r.ReinsOfPower.class)); + cards.add(new SetCardInfo("Revenant", 68, Rarity.RARE, mage.cards.r.Revenant.class)); + cards.add(new SetCardInfo("Rolling Stones", 11, Rarity.RARE, mage.cards.r.RollingStones.class)); + cards.add(new SetCardInfo("Ruination", 95, Rarity.RARE, mage.cards.r.Ruination.class)); + cards.add(new SetCardInfo("Sacred Ground", 12, Rarity.RARE, mage.cards.s.SacredGround.class)); + cards.add(new SetCardInfo("Scapegoat", 14, Rarity.UNCOMMON, mage.cards.s.Scapegoat.class)); + cards.add(new SetCardInfo("Seething Anger", 96, Rarity.COMMON, mage.cards.s.SeethingAnger.class)); + cards.add(new SetCardInfo("Serpent Warrior", 69, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); + cards.add(new SetCardInfo("Shaman en-Kor", 15, Rarity.RARE, mage.cards.s.ShamanEnKor.class)); + cards.add(new SetCardInfo("Shard Phoenix", 97, Rarity.RARE, mage.cards.s.ShardPhoenix.class)); + cards.add(new SetCardInfo("Shifting Wall", 140, Rarity.UNCOMMON, mage.cards.s.ShiftingWall.class)); + cards.add(new SetCardInfo("Shock", 98, Rarity.COMMON, mage.cards.s.Shock.class)); + cards.add(new SetCardInfo("Sift", 42, Rarity.COMMON, mage.cards.s.Sift.class)); + cards.add(new SetCardInfo("Silver Wyvern", 43, Rarity.RARE, mage.cards.s.SilverWyvern.class)); + cards.add(new SetCardInfo("Skyshroud Archer", 114, Rarity.COMMON, mage.cards.s.SkyshroudArcher.class)); + cards.add(new SetCardInfo("Skyshroud Falcon", 16, Rarity.COMMON, mage.cards.s.SkyshroudFalcon.class)); + cards.add(new SetCardInfo("Skyshroud Troopers", 115, Rarity.COMMON, mage.cards.s.SkyshroudTroopers.class)); + cards.add(new SetCardInfo("Sliver Queen", 129, Rarity.RARE, mage.cards.s.SliverQueen.class)); + cards.add(new SetCardInfo("Smite", 17, Rarity.COMMON, mage.cards.s.Smite.class)); + cards.add(new SetCardInfo("Soltari Champion", 18, Rarity.RARE, mage.cards.s.SoltariChampion.class)); + cards.add(new SetCardInfo("Spike Breeder", 116, Rarity.RARE, mage.cards.s.SpikeBreeder.class)); + cards.add(new SetCardInfo("Spike Colony", 117, Rarity.COMMON, mage.cards.s.SpikeColony.class)); + cards.add(new SetCardInfo("Spike Feeder", 118, Rarity.UNCOMMON, mage.cards.s.SpikeFeeder.class)); + cards.add(new SetCardInfo("Spike Soldier", 119, Rarity.UNCOMMON, mage.cards.s.SpikeSoldier.class)); + cards.add(new SetCardInfo("Spike Worker", 120, Rarity.COMMON, mage.cards.s.SpikeWorker.class)); + cards.add(new SetCardInfo("Spindrift Drake", 44, Rarity.COMMON, mage.cards.s.SpindriftDrake.class)); + cards.add(new SetCardInfo("Spined Sliver", 130, Rarity.UNCOMMON, mage.cards.s.SpinedSliver.class)); + cards.add(new SetCardInfo("Spined Wurm", 121, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); + cards.add(new SetCardInfo("Spirit en-Kor", 19, Rarity.COMMON, mage.cards.s.SpiritEnKor.class)); + cards.add(new SetCardInfo("Spitting Hydra", 99, Rarity.RARE, mage.cards.s.SpittingHydra.class)); + cards.add(new SetCardInfo("Stronghold Assassin", 71, Rarity.RARE, mage.cards.s.StrongholdAssassin.class)); + cards.add(new SetCardInfo("Stronghold Taskmaster", 72, Rarity.UNCOMMON, mage.cards.s.StrongholdTaskmaster.class)); + cards.add(new SetCardInfo("Sword of the Chosen", 141, Rarity.RARE, mage.cards.s.SwordOfTheChosen.class)); + cards.add(new SetCardInfo("Temper", 20, Rarity.UNCOMMON, mage.cards.t.Temper.class)); + cards.add(new SetCardInfo("Tempting Licid", 122, Rarity.UNCOMMON, mage.cards.t.TemptingLicid.class)); + cards.add(new SetCardInfo("Thalakos Deceiver", 45, Rarity.RARE, mage.cards.t.ThalakosDeceiver.class)); + cards.add(new SetCardInfo("Tidal Surge", 46, Rarity.COMMON, mage.cards.t.TidalSurge.class)); + cards.add(new SetCardInfo("Tidal Warrior", 47, Rarity.COMMON, mage.cards.t.TidalWarrior.class)); + cards.add(new SetCardInfo("Torment", 73, Rarity.COMMON, mage.cards.t.Torment.class)); + cards.add(new SetCardInfo("Tortured Existence", 74, Rarity.COMMON, mage.cards.t.TorturedExistence.class)); + cards.add(new SetCardInfo("Venerable Monk", 21, Rarity.COMMON, mage.cards.v.VenerableMonk.class)); + cards.add(new SetCardInfo("Verdant Touch", 123, Rarity.RARE, mage.cards.v.VerdantTouch.class)); + cards.add(new SetCardInfo("Victual Sliver", 131, Rarity.UNCOMMON, mage.cards.v.VictualSliver.class)); + cards.add(new SetCardInfo("Volrath's Gardens", 124, Rarity.RARE, mage.cards.v.VolrathsGardens.class)); + cards.add(new SetCardInfo("Volrath's Laboratory", 142, Rarity.RARE, mage.cards.v.VolrathsLaboratory.class)); + cards.add(new SetCardInfo("Volrath's Shapeshifter", 48, Rarity.RARE, mage.cards.v.VolrathsShapeshifter.class)); + cards.add(new SetCardInfo("Volrath's Stronghold", 143, Rarity.RARE, mage.cards.v.VolrathsStronghold.class)); + cards.add(new SetCardInfo("Walking Dream", 49, Rarity.UNCOMMON, mage.cards.w.WalkingDream.class)); + cards.add(new SetCardInfo("Wall of Blossoms", 125, Rarity.UNCOMMON, mage.cards.w.WallOfBlossoms.class)); + cards.add(new SetCardInfo("Wall of Essence", 22, Rarity.UNCOMMON, mage.cards.w.WallOfEssence.class)); + cards.add(new SetCardInfo("Wall of Razors", 100, Rarity.UNCOMMON, mage.cards.w.WallOfRazors.class)); + cards.add(new SetCardInfo("Wall of Souls", 75, Rarity.UNCOMMON, mage.cards.w.WallOfSouls.class)); + cards.add(new SetCardInfo("Wall of Tears", 50, Rarity.UNCOMMON, mage.cards.w.WallOfTears.class)); + cards.add(new SetCardInfo("Warrior Angel", 24, Rarity.RARE, mage.cards.w.WarriorAngel.class)); + cards.add(new SetCardInfo("Warrior en-Kor", 23, Rarity.UNCOMMON, mage.cards.w.WarriorEnKor.class)); + cards.add(new SetCardInfo("Youthful Knight", 25, Rarity.COMMON, mage.cards.y.YouthfulKnight.class)); + } +} From 09a5ece9f301eb10110a06e2812b26ef6025c7be Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 27 Nov 2018 16:09:43 +0100 Subject: [PATCH 42/50] Fixed color check and added missing attribute to verify. --- Mage.Verify/src/main/java/mage/verify/JsonCard.java | 2 ++ .../src/test/java/mage/verify/VerifyCardDataTest.java | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Mage.Verify/src/main/java/mage/verify/JsonCard.java b/Mage.Verify/src/main/java/mage/verify/JsonCard.java index c7a0c49a4b5..ef857d8d751 100644 --- a/Mage.Verify/src/main/java/mage/verify/JsonCard.java +++ b/Mage.Verify/src/main/java/mage/verify/JsonCard.java @@ -3,6 +3,7 @@ package mage.verify; import java.util.List; class JsonCard { + public String uuid; public String convertedManaCost; public List foreignData; @@ -56,4 +57,5 @@ class JsonCard { public boolean timeshifted; public String borderColor; public boolean isOversized; + public String faceConvertedManaCost; } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index d170b83cd57..0ebbe0f3e40 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -575,11 +575,11 @@ public class VerifyCardDataTest { ObjectColor color = card.getColor(null); if (expected.size() != color.getColorCount() - || (color.isBlack() && !expected.contains("Black")) - || (color.isBlue() && !expected.contains("Blue")) - || (color.isGreen() && !expected.contains("Green")) - || (color.isRed() && !expected.contains("Red")) - || (color.isWhite() && !expected.contains("White"))) { + || (color.isBlack() && !expected.contains("B")) + || (color.isBlue() && !expected.contains("U")) + || (color.isGreen() && !expected.contains("G")) + || (color.isRed() && !expected.contains("R")) + || (color.isWhite() && !expected.contains("W"))) { fail(card, "colors", color + " != " + expected); } } From 258bb2b62382ad2ef3c3a968f543519ba25cba26 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 28 Nov 2018 15:43:28 -0600 Subject: [PATCH 43/50] - Added Skeleton Scavengers and Contempt. --- Mage.Sets/src/mage/cards/c/Contempt.java | 93 +++++++++++++ .../src/mage/cards/s/SkeletonScavengers.java | 129 ++++++++++++++++++ Mage.Sets/src/mage/sets/Stronghold.java | 2 + 3 files changed, 224 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/Contempt.java create mode 100644 Mage.Sets/src/mage/cards/s/SkeletonScavengers.java diff --git a/Mage.Sets/src/mage/cards/c/Contempt.java b/Mage.Sets/src/mage/cards/c/Contempt.java new file mode 100644 index 00000000000..1aa4800d05e --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/Contempt.java @@ -0,0 +1,93 @@ +package mage.cards.c; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author jeffwadsworth + */ +public final class Contempt extends CardImpl { + + public Contempt(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Whenever enchanted creature attacks, return it and Contempt to their owners' hands at end of combat. + this.addAbility(new AttacksAttachedTriggeredAbility(new ContemptEffect())); + + } + + public Contempt(final Contempt card) { + super(card); + } + + @Override + public Contempt copy() { + return new Contempt(this); + } +} + +class ContemptEffect extends OneShotEffect { + + ContemptEffect() { + super(Outcome.Detriment); + this.staticText = "return it and {this} to their owners' hands at end of combat."; + } + + ContemptEffect(final ContemptEffect effect) { + super(effect); + } + + @Override + public ContemptEffect copy() { + return new ContemptEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent contempt = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (contempt != null) { + Permanent attachedToPermanent = game.getPermanent(contempt.getAttachedTo()); + if (attachedToPermanent != null) { + Effect effect = new ReturnToHandTargetEffect(); + effect.setTargetPointer(new FixedTarget( + attachedToPermanent.getId())).setText("return " + + attachedToPermanent.getName() + " to owner's hand."); + AtTheEndOfCombatDelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(effect); + game.addDelayedTriggeredAbility(ability, source); + } + Effect effect = new ReturnToHandSourceEffect(); + AtTheEndOfCombatDelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(effect); + game.addDelayedTriggeredAbility(ability, source); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java b/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java new file mode 100644 index 00000000000..c15d68bdd04 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SkeletonScavengers.java @@ -0,0 +1,129 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public final class SkeletonScavengers extends CardImpl { + + public SkeletonScavengers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.SKELETON); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + // Skeleton Scavengers enters the battlefield with a +1/+1 counter on it. + this.addAbility(new AsEntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))); + + // Pay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it. + this.addAbility(new SimpleActivatedAbility(new SkeletonScavengersEffect(), new DynamicValueGenericManaCost(new CountersSourceCount(CounterType.P1P1)))); + + } + + public SkeletonScavengers(final SkeletonScavengers card) { + super(card); + } + + @Override + public SkeletonScavengers copy() { + return new SkeletonScavengers(this); + } +} + +class DynamicValueGenericManaCost extends CostImpl { + + DynamicValue amount; + + public DynamicValueGenericManaCost(DynamicValue amount) { + this.amount = amount; + setText(); + } + + public DynamicValueGenericManaCost(DynamicValueGenericManaCost cost) { + super(cost); + this.amount = cost.amount; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Player controller = game.getPlayer(controllerId); + if (controller == null) { + return false; + } + int convertedCost = amount.calculate(game, ability, null); + Cost cost = new GenericManaCost(convertedCost); + return cost.canPay(ability, sourceId, controllerId, game); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + Player controller = game.getPlayer(controllerId); + int convertedCost = amount.calculate(game, ability, null); + Cost cost = new GenericManaCost(convertedCost); + if (controller != null) { + paid = cost.pay(ability, game, sourceId, controllerId, noMana); + } + return paid; + } + + @Override + public DynamicValueGenericManaCost copy() { + return new DynamicValueGenericManaCost(this); + } + + private void setText() { + text = ("Pay {1} for each +1/+1 counter on {this}"); + } +} + +class SkeletonScavengersEffect extends OneShotEffect { + + SkeletonScavengersEffect() { + super(Outcome.Benefit); + this.staticText = "Regenerate {this}. When it regenerates this way, put a +1/+1 counter on it"; + } + + SkeletonScavengersEffect(final SkeletonScavengersEffect effect) { + super(effect); + } + + @Override + public SkeletonScavengersEffect copy() { + return new SkeletonScavengersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent skeletonScavengers = game.getPermanent(source.getSourceId()); + if (skeletonScavengers != null) { + if (new RegenerateSourceEffect().apply(game, source)) { + return new AddCountersSourceEffect(CounterType.P1P1.createInstance()).apply(game, source); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Stronghold.java b/Mage.Sets/src/mage/sets/Stronghold.java index 0fe9bdb4cad..d07dc5677bf 100644 --- a/Mage.Sets/src/mage/sets/Stronghold.java +++ b/Mage.Sets/src/mage/sets/Stronghold.java @@ -42,6 +42,7 @@ public final class Stronghold extends ExpansionSet { cards.add(new SetCardInfo("Cloud Spirit", 26, Rarity.COMMON, mage.cards.c.CloudSpirit.class)); cards.add(new SetCardInfo("Constant Mists", 104, Rarity.UNCOMMON, mage.cards.c.ConstantMists.class)); cards.add(new SetCardInfo("Contemplation", 4, Rarity.UNCOMMON, mage.cards.c.Contemplation.class)); + cards.add(new SetCardInfo("Contempt", 27, Rarity.COMMON, mage.cards.c.Contempt.class)); cards.add(new SetCardInfo("Conviction", 5, Rarity.COMMON, mage.cards.c.Conviction.class)); cards.add(new SetCardInfo("Convulsing Licid", 77, Rarity.UNCOMMON, mage.cards.c.ConvulsingLicid.class)); cards.add(new SetCardInfo("Corrupting Licid", 54, Rarity.UNCOMMON, mage.cards.c.CorruptingLicid.class)); @@ -122,6 +123,7 @@ public final class Stronghold extends ExpansionSet { cards.add(new SetCardInfo("Shock", 98, Rarity.COMMON, mage.cards.s.Shock.class)); cards.add(new SetCardInfo("Sift", 42, Rarity.COMMON, mage.cards.s.Sift.class)); cards.add(new SetCardInfo("Silver Wyvern", 43, Rarity.RARE, mage.cards.s.SilverWyvern.class)); + cards.add(new SetCardInfo("Skeleton Scavengers", 20, Rarity.RARE, mage.cards.s.SkeletonScavengers.class)); cards.add(new SetCardInfo("Skyshroud Archer", 114, Rarity.COMMON, mage.cards.s.SkyshroudArcher.class)); cards.add(new SetCardInfo("Skyshroud Falcon", 16, Rarity.COMMON, mage.cards.s.SkyshroudFalcon.class)); cards.add(new SetCardInfo("Skyshroud Troopers", 115, Rarity.COMMON, mage.cards.s.SkyshroudTroopers.class)); From 47dac3940cbac6200a7ad23324764a6d37a60040 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 29 Nov 2018 09:26:31 -0600 Subject: [PATCH 44/50] - Fixed #5401 --- Mage.Sets/src/mage/cards/c/CommitMemory.java | 2 +- Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CommitMemory.java b/Mage.Sets/src/mage/cards/c/CommitMemory.java index eaebaa461e1..4d6c2e77e37 100644 --- a/Mage.Sets/src/mage/cards/c/CommitMemory.java +++ b/Mage.Sets/src/mage/cards/c/CommitMemory.java @@ -82,7 +82,7 @@ class CommitEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent permanent = game.getPermanent(source.getFirstTarget()); if (permanent != null) { return controller.putCardOnTopXOfLibrary(permanent, game, source, 2); } diff --git a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java index d4d7341f1ae..de769af2dae 100644 --- a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java +++ b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java @@ -1,4 +1,3 @@ - package mage.cards.j; import java.util.HashMap; @@ -130,7 +129,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect { if (controller.choose(Outcome.PlayForFree, exileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)); + controller.playCard(card, game, true, false, new MageObjectReference(source.getSourceId(), game)); } } } From a948a1101acf95749e078ea0fd95c7852ce5cc03 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 29 Nov 2018 09:30:05 -0600 Subject: [PATCH 45/50] - small edit to Jeleva. --- Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java index de769af2dae..2af20fd0760 100644 --- a/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java +++ b/Mage.Sets/src/mage/cards/j/JelevaNephaliasScourge.java @@ -91,7 +91,6 @@ class JelevaNephaliasScourgeEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - // player.moveCardsToExile(player.getLibrary().getTopCards(game, xValue), source, game, true, CardUtil.getCardExileZoneId(game, source), sourceObject.getIdName()); } } @@ -129,7 +128,7 @@ class JelevaNephaliasCastEffect extends OneShotEffect { if (controller.choose(Outcome.PlayForFree, exileZone, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.playCard(card, game, true, false, new MageObjectReference(source.getSourceId(), game)); + return controller.playCard(card, game, true, false, new MageObjectReference(source.getSourceId(), game)); } } } From 6e48b4f954df81b34bd235f65b085c50c67383a2 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 1 Dec 2018 21:57:06 +0400 Subject: [PATCH 46/50] Added link to xmage servers status page (by DiMiaN from discord) --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index 4c25a0bdad9..043c124dbd3 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,9 @@ XMage community: * [Reddit XMage group](https://www.reddit.com/r/XMage/); * [Reddit XMage discord channel](https://discord.gg/Pqf42yn). +Servers status: +* http://xmageservers.online/ + ## Features * Deck editor (load and save decks) From dcec3ad66eff24e11f813f536a64246de2283a53 Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 4 Dec 2018 16:32:23 -0600 Subject: [PATCH 47/50] - Stronghold Set 100%. Added Hidden Retreat, Ransack, Rebound, and Samite Blessing. --- Mage.Sets/src/mage/cards/h/HiddenRetreat.java | 76 ++++++++++++++++ Mage.Sets/src/mage/cards/r/Ransack.java | 87 +++++++++++++++++++ Mage.Sets/src/mage/cards/r/Rebound.java | 75 ++++++++++++++++ .../src/mage/cards/s/SamiteBlessing.java | 58 +++++++++++++ Mage.Sets/src/mage/sets/Stronghold.java | 4 + .../other/TargetsPlayerPredicate.java | 48 ++++++++++ 6 files changed, 348 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HiddenRetreat.java create mode 100644 Mage.Sets/src/mage/cards/r/Ransack.java create mode 100644 Mage.Sets/src/mage/cards/r/Rebound.java create mode 100644 Mage.Sets/src/mage/cards/s/SamiteBlessing.java create mode 100644 Mage/src/main/java/mage/filter/predicate/other/TargetsPlayerPredicate.java diff --git a/Mage.Sets/src/mage/cards/h/HiddenRetreat.java b/Mage.Sets/src/mage/cards/h/HiddenRetreat.java new file mode 100644 index 00000000000..b90d3d088a3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HiddenRetreat.java @@ -0,0 +1,76 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.PutCardFromHandOnTopOfLibraryCost; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import java.util.UUID; +import mage.filter.StaticFilters; +import mage.game.events.DamageEvent; +import mage.target.TargetSpell; + +/** + * + * @author bunchOfDevs + */ +public class HiddenRetreat extends CardImpl { + + public HiddenRetreat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + + //Put a card from your hand on top of your library: Prevent all damage that would be dealt by target instant or sorcery spell this turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HiddenRetreatEffect(), new PutCardFromHandOnTopOfLibraryCost()); + ability.addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY)); + this.addAbility(ability); + + } + + public HiddenRetreat(final HiddenRetreat hiddenRetreat) { + super(hiddenRetreat); + } + + @Override + public HiddenRetreat copy() { + return new HiddenRetreat(this); + } +} + +class HiddenRetreatEffect extends PreventionEffectImpl { + + public HiddenRetreatEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); + this.staticText = "Prevent all damage that would be dealt by target instant or sorcery spell this turn."; + } + + public HiddenRetreatEffect(final HiddenRetreatEffect effect) { + super(effect); + } + + @Override + public HiddenRetreatEffect copy() { + return new HiddenRetreatEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return (super.applies(event, source, game) + && event instanceof DamageEvent + && event.getAmount() > 0 + && game.getObject(source.getFirstTarget()) != null + && game.getObject(event.getSourceId()) != null + && game.getObject(source.getFirstTarget()).equals(game.getObject(event.getSourceId())) + && game.getObject(source.getFirstTarget()).isInstantOrSorcery()); + } +} diff --git a/Mage.Sets/src/mage/cards/r/Ransack.java b/Mage.Sets/src/mage/cards/r/Ransack.java new file mode 100644 index 00000000000..32e69f711fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Ransack.java @@ -0,0 +1,87 @@ +package mage.cards.r; + +import static java.lang.Integer.min; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class Ransack extends CardImpl { + + public Ransack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}"); + + // Look at the top five cards of target player's library. + //Put any number of them on the bottom of that library in any order + //and the rest on top of the library in any order. + this.getSpellAbility().addEffect(new RansackEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + + } + + public Ransack(final Ransack card) { + super(card); + } + + @Override + public Ransack copy() { + return new Ransack(this); + } +} + +class RansackEffect extends OneShotEffect { + + public RansackEffect() { + super(Outcome.Detriment); + this.staticText = "Look at the top five cards of target player's library. " + + "Put any number of them on the bottom of that library in any order " + + "and the rest on top of the library in any order"; + } + + public RansackEffect(final RansackEffect effect) { + super(effect); + } + + @Override + public RansackEffect copy() { + return new RansackEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + FilterCard filter = new FilterCard("cards to put on the bottom of your library"); + if (player != null) { + int number = min(player.getLibrary().size(), 5); + Set cards = player.getLibrary().getTopCards(game, number); + Cards cardsRemaining = new CardsImpl(); + cardsRemaining.addAll(cards); + TargetCard target = new TargetCard((true ? 0 : number), number, Zone.LIBRARY, filter); + if (player.choose(Outcome.DrawCard, cardsRemaining, target, game)) { + Cards pickedCards = new CardsImpl(target.getTargets()); + cardsRemaining.removeAll(pickedCards); + player.putCardsOnBottomOfLibrary(pickedCards, game, source, true); + player.putCardsOnTopOfLibrary(cardsRemaining, game, source, true); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/r/Rebound.java b/Mage.Sets/src/mage/cards/r/Rebound.java new file mode 100644 index 00000000000..deb926e0ebc --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Rebound.java @@ -0,0 +1,75 @@ +package mage.cards.r; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterSpell; +import mage.filter.predicate.other.TargetsPlayerPredicate; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.TargetSpell; + +/** + * + * @author jeffwadsworth + */ +public final class Rebound extends CardImpl { + + public Rebound(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); + + // Change the target of target spell that targets only a player. The new target must be a player. + this.getSpellAbility().addEffect(new ReboundEffect()); + FilterSpell filter = new FilterSpell("spell that targets only a player"); + filter.add(new TargetsPlayerPredicate()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + + } + + public Rebound(final Rebound card) { + super(card); + } + + @Override + public Rebound copy() { + return new Rebound(this); + } +} + +class ReboundEffect extends OneShotEffect { + + public ReboundEffect() { + super(Outcome.Neutral); + this.staticText = "Change the target of target spell that targets only a player. The new target must be a player"; + } + + public ReboundEffect(final ReboundEffect effect) { + super(effect); + } + + @Override + public ReboundEffect copy() { + return new ReboundEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Spell spell = game.getStack().getSpell(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (spell != null + && controller != null) { + spell.getSpellAbility().getTargets().clear(); + TargetPlayer targetPlayer = new TargetPlayer(); + if (controller.choose(Outcome.Neutral, targetPlayer, source.getSourceId(), game)) { + spell.getSpellAbility().addTarget(targetPlayer); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SamiteBlessing.java b/Mage.Sets/src/mage/cards/s/SamiteBlessing.java new file mode 100644 index 00000000000..1168cf6606a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SamiteBlessing.java @@ -0,0 +1,58 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.PreventNextDamageFromChosenSourceToTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; + +/** + * + * @author jeffwadsworth + */ +public final class SamiteBlessing extends CardImpl { + + private static final String rule = "Enchanted creature has \"{T}: The next time a source of your choice would deal damage to target creature this turn, prevent that damage.\""; + + public SamiteBlessing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature has "{tap}: The next time a source of your choice would deal damage to target creature this turn, prevent that damage." + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventNextDamageFromChosenSourceToTargetEffect(Duration.EndOfTurn), new TapSourceCost()); + ability2.addTarget(new TargetCreaturePermanent()); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability2, AttachmentType.AURA, Duration.WhileOnBattlefield, rule))); + + } + + public SamiteBlessing(final SamiteBlessing card) { + super(card); + } + + @Override + public SamiteBlessing copy() { + return new SamiteBlessing(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Stronghold.java b/Mage.Sets/src/mage/sets/Stronghold.java index d07dc5677bf..b575ec9416c 100644 --- a/Mage.Sets/src/mage/sets/Stronghold.java +++ b/Mage.Sets/src/mage/sets/Stronghold.java @@ -77,6 +77,7 @@ public final class Stronghold extends ExpansionSet { cards.add(new SetCardInfo("Hermit Druid", 108, Rarity.RARE, mage.cards.h.HermitDruid.class)); cards.add(new SetCardInfo("Hesitation", 33, Rarity.UNCOMMON, mage.cards.h.Hesitation.class)); cards.add(new SetCardInfo("Hibernation Sliver", 128, Rarity.UNCOMMON, mage.cards.h.HibernationSliver.class)); + cards.add(new SetCardInfo("Hidden Retreat", 106, Rarity.RARE, mage.cards.h.HiddenRetreat.class)); cards.add(new SetCardInfo("Honor Guard", 7, Rarity.COMMON, mage.cards.h.HonorGuard.class)); cards.add(new SetCardInfo("Horn of Greed", 135, Rarity.RARE, mage.cards.h.HornOfGreed.class)); cards.add(new SetCardInfo("Hornet Cannon", 136, Rarity.UNCOMMON, mage.cards.h.HornetCannon.class)); @@ -109,11 +110,14 @@ public final class Stronghold extends ExpansionSet { cards.add(new SetCardInfo("Provoke", 113, Rarity.COMMON, mage.cards.p.Provoke.class)); cards.add(new SetCardInfo("Pursuit of Knowledge", 10, Rarity.RARE, mage.cards.p.PursuitOfKnowledge.class)); cards.add(new SetCardInfo("Rabid Rats", 67, Rarity.COMMON, mage.cards.r.RabidRats.class)); + cards.add(new SetCardInfo("Ransack", 39, Rarity.UNCOMMON, mage.cards.r.Ransack.class)); + cards.add(new SetCardInfo("Rebound", 40, Rarity.UNCOMMON, mage.cards.r.Rebound.class)); cards.add(new SetCardInfo("Reins of Power", 41, Rarity.RARE, mage.cards.r.ReinsOfPower.class)); cards.add(new SetCardInfo("Revenant", 68, Rarity.RARE, mage.cards.r.Revenant.class)); cards.add(new SetCardInfo("Rolling Stones", 11, Rarity.RARE, mage.cards.r.RollingStones.class)); cards.add(new SetCardInfo("Ruination", 95, Rarity.RARE, mage.cards.r.Ruination.class)); cards.add(new SetCardInfo("Sacred Ground", 12, Rarity.RARE, mage.cards.s.SacredGround.class)); + cards.add(new SetCardInfo("Samite Blessing", 113, Rarity.COMMON, mage.cards.s.SamiteBlessing.class)); cards.add(new SetCardInfo("Scapegoat", 14, Rarity.UNCOMMON, mage.cards.s.Scapegoat.class)); cards.add(new SetCardInfo("Seething Anger", 96, Rarity.COMMON, mage.cards.s.SeethingAnger.class)); cards.add(new SetCardInfo("Serpent Warrior", 69, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); diff --git a/Mage/src/main/java/mage/filter/predicate/other/TargetsPlayerPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/TargetsPlayerPredicate.java new file mode 100644 index 00000000000..af8f556bc4d --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/other/TargetsPlayerPredicate.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.filter.predicate.other; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Mode; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.stack.StackObject; +import mage.players.Player; +import mage.target.Target; + +/** + * + * @author jeffwadsworth + */ +public class TargetsPlayerPredicate implements ObjectSourcePlayerPredicate> { + + public TargetsPlayerPredicate() { + } + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + StackObject object = game.getStack().getStackObject(input.getObject().getId()); + if (object != null) { + for (UUID modeId : object.getStackAbility().getModes().getSelectedModes()) { + Mode mode = object.getStackAbility().getModes().get(modeId); + for (Target target : mode.getTargets()) { + for (UUID targetId : target.getTargets()) { + Player player = game.getPlayer(targetId); + return player != null; + } + } + } + } + return false; + } + + @Override + public String toString() { + return "that targets a player"; + } +} From d397c8126aa6d536c493920dd2c9c4e183b0fcfa Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 4 Dec 2018 17:17:46 -0600 Subject: [PATCH 48/50] - added card info to Starter1999 set. --- Mage.Sets/src/mage/sets/Starter1999.java | 401 ++++++++++++----------- 1 file changed, 201 insertions(+), 200 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Starter1999.java b/Mage.Sets/src/mage/sets/Starter1999.java index e7e5d8050ca..d41c6b095fd 100644 --- a/Mage.Sets/src/mage/sets/Starter1999.java +++ b/Mage.Sets/src/mage/sets/Starter1999.java @@ -1,200 +1,201 @@ -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author LevelX2 - */ -public final class Starter1999 extends ExpansionSet { - - private static final Starter1999 instance = new Starter1999(); - - public static Starter1999 getInstance() { - return instance; - } - - private Starter1999() { - super("Starter 1999", "S99", ExpansionSet.buildDate(1999, 7, 1), SetType.SUPPLEMENTAL); - this.blockName = "Beginner"; - this.hasBasicLands = true; - this.hasBoosters = true; - this.numBoosterLands = 2; - this.numBoosterCommon = 9; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Abyssal Horror", 63, Rarity.RARE, mage.cards.a.AbyssalHorror.class)); - cards.add(new SetCardInfo("Air Elemental", 32, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); - cards.add(new SetCardInfo("Alluring Scent", 124, Rarity.RARE, mage.cards.a.AlluringScent.class)); - cards.add(new SetCardInfo("Ancient Craving", 64, Rarity.RARE, mage.cards.a.AncientCraving.class)); - cards.add(new SetCardInfo("Angelic Blessing", 3, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); - cards.add(new SetCardInfo("Angel of Light", 1, Rarity.UNCOMMON, mage.cards.a.AngelOfLight.class)); - cards.add(new SetCardInfo("Angel of Mercy", 2, Rarity.UNCOMMON, mage.cards.a.AngelOfMercy.class)); - cards.add(new SetCardInfo("Archangel", 4, Rarity.RARE, mage.cards.a.Archangel.class)); - cards.add(new SetCardInfo("Ardent Militia", 5, Rarity.UNCOMMON, mage.cards.a.ArdentMilitia.class)); - cards.add(new SetCardInfo("Armageddon", 6, Rarity.RARE, mage.cards.a.Armageddon.class)); - cards.add(new SetCardInfo("Barbtooth Wurm", 125, Rarity.COMMON, mage.cards.b.BarbtoothWurm.class)); - cards.add(new SetCardInfo("Bargain", 7, Rarity.UNCOMMON, mage.cards.b.Bargain.class)); - cards.add(new SetCardInfo("Blinding Light", 8, Rarity.RARE, mage.cards.b.BlindingLight.class)); - cards.add(new SetCardInfo("Bog Imp", 65, Rarity.COMMON, mage.cards.b.BogImp.class)); - cards.add(new SetCardInfo("Bog Raiders", 66, Rarity.COMMON, mage.cards.b.BogRaiders.class)); - cards.add(new SetCardInfo("Bog Wraith", 67, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); - cards.add(new SetCardInfo("Border Guard", 9, Rarity.COMMON, mage.cards.b.BorderGuard.class)); - cards.add(new SetCardInfo("Breath of Life", 10, Rarity.UNCOMMON, mage.cards.b.BreathOfLife.class)); - cards.add(new SetCardInfo("Bull Hippo", 126, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); - cards.add(new SetCardInfo("Champion Lancer", 11, Rarity.RARE, mage.cards.c.ChampionLancer.class)); - cards.add(new SetCardInfo("Charging Paladin", 12, Rarity.UNCOMMON, mage.cards.c.ChargingPaladin.class)); - cards.add(new SetCardInfo("Chorus of Woe", 68, Rarity.COMMON, mage.cards.c.ChorusOfWoe.class)); - cards.add(new SetCardInfo("Cinder Storm", 93, Rarity.UNCOMMON, mage.cards.c.CinderStorm.class)); - cards.add(new SetCardInfo("Coercion", 69, Rarity.UNCOMMON, mage.cards.c.Coercion.class)); - cards.add(new SetCardInfo("Coral Eel", 33, Rarity.COMMON, mage.cards.c.CoralEel.class)); - cards.add(new SetCardInfo("Counterspell", 34, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); - cards.add(new SetCardInfo("Dakmor Ghoul", 70, Rarity.UNCOMMON, mage.cards.d.DakmorGhoul.class)); - cards.add(new SetCardInfo("Dakmor Lancer", 71, Rarity.RARE, mage.cards.d.DakmorLancer.class)); - cards.add(new SetCardInfo("Dakmor Plague", 72, Rarity.UNCOMMON, mage.cards.d.DakmorPlague.class)); - cards.add(new SetCardInfo("Dakmor Scorpion", 73, Rarity.COMMON, mage.cards.d.DakmorScorpion.class)); - cards.add(new SetCardInfo("Dakmor Sorceress", 74, Rarity.RARE, mage.cards.d.DakmorSorceress.class)); - cards.add(new SetCardInfo("Dark Offering", 75, Rarity.UNCOMMON, mage.cards.d.DarkOffering.class)); - cards.add(new SetCardInfo("Denizen of the Deep", 35, Rarity.RARE, mage.cards.d.DenizenOfTheDeep.class)); - cards.add(new SetCardInfo("Devastation", 94, Rarity.RARE, mage.cards.d.Devastation.class)); - cards.add(new SetCardInfo("Devoted Hero", 13, Rarity.COMMON, mage.cards.d.DevotedHero.class)); - cards.add(new SetCardInfo("Devout Monk", 14, Rarity.COMMON, mage.cards.d.DevoutMonk.class)); - cards.add(new SetCardInfo("Dread Reaper", 76, Rarity.RARE, mage.cards.d.DreadReaper.class)); - cards.add(new SetCardInfo("Durkwood Boars", 127, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); - cards.add(new SetCardInfo("Eager Cadet", 15, Rarity.COMMON, mage.cards.e.EagerCadet.class)); - cards.add(new SetCardInfo("Earth Elemental", 95, Rarity.UNCOMMON, mage.cards.e.EarthElemental.class)); - cards.add(new SetCardInfo("Exhaustion", 36, Rarity.UNCOMMON, mage.cards.e.Exhaustion.class)); - cards.add(new SetCardInfo("Extinguish", 37, Rarity.COMMON, mage.cards.e.Extinguish.class)); - cards.add(new SetCardInfo("Eye Spy", 38, Rarity.UNCOMMON, mage.cards.e.EyeSpy.class)); - cards.add(new SetCardInfo("False Peace", 16, Rarity.UNCOMMON, mage.cards.f.FalsePeace.class)); - cards.add(new SetCardInfo("Feral Shadow", 77, Rarity.COMMON, mage.cards.f.FeralShadow.class)); - cards.add(new SetCardInfo("Fire Elemental", 96, Rarity.UNCOMMON, mage.cards.f.FireElemental.class)); - cards.add(new SetCardInfo("Fire Tempest", 97, Rarity.RARE, mage.cards.f.FireTempest.class)); - cards.add(new SetCardInfo("Foot Soldiers", 17, Rarity.COMMON, mage.cards.f.FootSoldiers.class)); - cards.add(new SetCardInfo("Forest", 170, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 171, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 172, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 173, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Gerrard's Wisdom", 18, Rarity.RARE, mage.cards.g.GerrardsWisdom.class)); - cards.add(new SetCardInfo("Giant Octopus", 39, Rarity.COMMON, mage.cards.g.GiantOctopus.class)); - cards.add(new SetCardInfo("Goblin Cavaliers", 98, Rarity.COMMON, mage.cards.g.GoblinCavaliers.class)); - cards.add(new SetCardInfo("Goblin Chariot", 99, Rarity.COMMON, mage.cards.g.GoblinChariot.class)); - cards.add(new SetCardInfo("Goblin Commando", 100, Rarity.UNCOMMON, mage.cards.g.GoblinCommando.class)); - cards.add(new SetCardInfo("Goblin General", 101, Rarity.UNCOMMON, mage.cards.g.GoblinGeneral.class)); - cards.add(new SetCardInfo("Goblin Glider", 102, Rarity.UNCOMMON, mage.cards.g.GoblinGlider.class)); - cards.add(new SetCardInfo("Goblin Hero", 103, Rarity.COMMON, mage.cards.g.GoblinHero.class)); - cards.add(new SetCardInfo("Goblin Lore", 104, Rarity.UNCOMMON, mage.cards.g.GoblinLore.class)); - cards.add(new SetCardInfo("Goblin Mountaineer", 105, Rarity.COMMON, mage.cards.g.GoblinMountaineer.class)); - cards.add(new SetCardInfo("Goblin Settler", 106, Rarity.UNCOMMON, mage.cards.g.GoblinSettler.class)); - cards.add(new SetCardInfo("Gorilla Warrior", 128, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); - cards.add(new SetCardInfo("Gravedigger", 78, Rarity.UNCOMMON, mage.cards.g.Gravedigger.class)); - cards.add(new SetCardInfo("Grim Tutor", 79, Rarity.RARE, mage.cards.g.GrimTutor.class)); - cards.add(new SetCardInfo("Grizzly Bears", 129, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); - cards.add(new SetCardInfo("Hand of Death", 80, Rarity.COMMON, mage.cards.h.HandOfDeath.class)); - cards.add(new SetCardInfo("Hollow Dogs", 81, Rarity.COMMON, mage.cards.h.HollowDogs.class)); - cards.add(new SetCardInfo("Howling Fury", 82, Rarity.UNCOMMON, mage.cards.h.HowlingFury.class)); - cards.add(new SetCardInfo("Hulking Goblin", 107, Rarity.COMMON, mage.cards.h.HulkingGoblin.class)); - cards.add(new SetCardInfo("Hulking Ogre", 108, Rarity.UNCOMMON, mage.cards.h.HulkingOgre.class)); - cards.add(new SetCardInfo("Ingenious Thief", 40, Rarity.COMMON, mage.cards.i.IngeniousThief.class)); - cards.add(new SetCardInfo("Island", 158, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 159, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 160, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 161, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Jagged Lightning", 109, Rarity.UNCOMMON, mage.cards.j.JaggedLightning.class)); - cards.add(new SetCardInfo("Knight Errant", 19, Rarity.COMMON, mage.cards.k.KnightErrant.class)); - cards.add(new SetCardInfo("Last Chance", 110, Rarity.RARE, mage.cards.l.LastChance.class)); - cards.add(new SetCardInfo("Lava Axe", 111, Rarity.COMMON, mage.cards.l.LavaAxe.class)); - cards.add(new SetCardInfo("Lone Wolf", 130, Rarity.COMMON, mage.cards.l.LoneWolf.class)); - cards.add(new SetCardInfo("Loyal Sentry", 20, Rarity.RARE, mage.cards.l.LoyalSentry.class)); - cards.add(new SetCardInfo("Lynx", 131, Rarity.UNCOMMON, mage.cards.l.Lynx.class)); - cards.add(new SetCardInfo("Man-o'-War", 41, Rarity.UNCOMMON, mage.cards.m.ManOWar.class)); - cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 42, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); - cards.add(new SetCardInfo("Mind Rot", 83, Rarity.COMMON, mage.cards.m.MindRot.class)); - cards.add(new SetCardInfo("Mons's Goblin Raiders", 112, Rarity.COMMON, mage.cards.m.MonssGoblinRaiders.class)); - cards.add(new SetCardInfo("Monstrous Growth", 132, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class)); - cards.add(new SetCardInfo("Moon Sprite", 133, Rarity.UNCOMMON, mage.cards.m.MoonSprite.class)); - cards.add(new SetCardInfo("Mountain", 166, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 167, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 168, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 169, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Muck Rats", 84, Rarity.COMMON, mage.cards.m.MuckRats.class)); - cards.add(new SetCardInfo("Natural Spring", 134, Rarity.UNCOMMON, mage.cards.n.NaturalSpring.class)); - cards.add(new SetCardInfo("Nature's Cloak", 135, Rarity.RARE, mage.cards.n.NaturesCloak.class)); - cards.add(new SetCardInfo("Nature's Lore", 136, Rarity.COMMON, mage.cards.n.NaturesLore.class)); - cards.add(new SetCardInfo("Norwood Archers", 137, Rarity.COMMON, mage.cards.n.NorwoodArchers.class)); - cards.add(new SetCardInfo("Norwood Ranger", 138, Rarity.COMMON, mage.cards.n.NorwoodRanger.class)); - cards.add(new SetCardInfo("Ogre Warrior", 113, Rarity.COMMON, mage.cards.o.OgreWarrior.class)); - cards.add(new SetCardInfo("Path of Peace", 21, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); - cards.add(new SetCardInfo("Phantom Warrior", 44, Rarity.RARE, mage.cards.p.PhantomWarrior.class)); - cards.add(new SetCardInfo("Plains", 154, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 155, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 156, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 157, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Pride of Lions", 139, Rarity.UNCOMMON, mage.cards.p.PrideOfLions.class)); - cards.add(new SetCardInfo("Psychic Transfer", 46, Rarity.RARE, mage.cards.p.PsychicTransfer.class)); - cards.add(new SetCardInfo("Raging Goblin", 114, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); - cards.add(new SetCardInfo("Raise Dead", 85, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Ravenous Rats", 86, Rarity.UNCOMMON, mage.cards.r.RavenousRats.class)); - cards.add(new SetCardInfo("Relearn", 48, Rarity.UNCOMMON, mage.cards.r.Relearn.class)); - cards.add(new SetCardInfo("Relentless Assault", 115, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); - cards.add(new SetCardInfo("Remove Soul", 49, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); - cards.add(new SetCardInfo("Renewing Touch", 140, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); - cards.add(new SetCardInfo("Righteous Charge", 22, Rarity.UNCOMMON, mage.cards.r.RighteousCharge.class)); - cards.add(new SetCardInfo("Righteous Fury", 23, Rarity.RARE, mage.cards.r.RighteousFury.class)); - cards.add(new SetCardInfo("Royal Falcon", 24, Rarity.COMMON, mage.cards.r.RoyalFalcon.class)); - cards.add(new SetCardInfo("Royal Trooper", 25, Rarity.UNCOMMON, mage.cards.r.RoyalTrooper.class)); - cards.add(new SetCardInfo("Sacred Nectar", 26, Rarity.COMMON, mage.cards.s.SacredNectar.class)); - cards.add(new SetCardInfo("Scathe Zombies", 87, Rarity.COMMON, mage.cards.s.ScatheZombies.class)); - cards.add(new SetCardInfo("Scorching Spear", 116, Rarity.COMMON, mage.cards.s.ScorchingSpear.class)); - cards.add(new SetCardInfo("Sea Eagle", 50, Rarity.COMMON, mage.cards.s.SeaEagle.class)); - cards.add(new SetCardInfo("Serpent Warrior", 88, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); - cards.add(new SetCardInfo("Shrieking Specter", 89, Rarity.UNCOMMON, mage.cards.s.ShriekingSpecter.class)); - cards.add(new SetCardInfo("Silverback Ape", 141, Rarity.UNCOMMON, mage.cards.s.SilverbackApe.class)); - cards.add(new SetCardInfo("Sleight of Hand", 51, Rarity.COMMON, mage.cards.s.SleightOfHand.class)); - cards.add(new SetCardInfo("Snapping Drake", 52, Rarity.COMMON, mage.cards.s.SnappingDrake.class)); - cards.add(new SetCardInfo("Soul Feast", 90, Rarity.UNCOMMON, mage.cards.s.SoulFeast.class)); - cards.add(new SetCardInfo("Southern Elephant", 142, Rarity.COMMON, mage.cards.s.SouthernElephant.class)); - cards.add(new SetCardInfo("Spitting Earth", 117, Rarity.UNCOMMON, mage.cards.s.SpittingEarth.class)); - cards.add(new SetCardInfo("Squall", 143, Rarity.COMMON, mage.cards.s.Squall.class)); - cards.add(new SetCardInfo("Steadfastness", 27, Rarity.COMMON, mage.cards.s.Steadfastness.class)); - cards.add(new SetCardInfo("Stone Rain", 118, Rarity.COMMON, mage.cards.s.StoneRain.class)); - cards.add(new SetCardInfo("Storm Crow", 53, Rarity.COMMON, mage.cards.s.StormCrow.class)); - cards.add(new SetCardInfo("Stream of Acid", 91, Rarity.UNCOMMON, mage.cards.s.StreamOfAcid.class)); - cards.add(new SetCardInfo("Summer Bloom", 144, Rarity.RARE, mage.cards.s.SummerBloom.class)); - cards.add(new SetCardInfo("Swamp", 162, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 163, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 164, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 165, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sylvan Basilisk", 145, Rarity.RARE, mage.cards.s.SylvanBasilisk.class)); - cards.add(new SetCardInfo("Sylvan Yeti", 146, Rarity.RARE, mage.cards.s.SylvanYeti.class)); - cards.add(new SetCardInfo("Thorn Elemental", 147, Rarity.RARE, mage.cards.t.ThornElemental.class)); - cards.add(new SetCardInfo("Thunder Dragon", 119, Rarity.RARE, mage.cards.t.ThunderDragon.class)); - cards.add(new SetCardInfo("Tidings", 54, Rarity.UNCOMMON, mage.cards.t.Tidings.class)); - cards.add(new SetCardInfo("Time Ebb", 55, Rarity.COMMON, mage.cards.t.TimeEbb.class)); - cards.add(new SetCardInfo("Time Warp", 56, Rarity.RARE, mage.cards.t.TimeWarp.class)); - cards.add(new SetCardInfo("Touch of Brilliance", 57, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); - cards.add(new SetCardInfo("Trained Orgg", 120, Rarity.RARE, mage.cards.t.TrainedOrgg.class)); - cards.add(new SetCardInfo("Tremor", 121, Rarity.COMMON, mage.cards.t.Tremor.class)); - cards.add(new SetCardInfo("Undo", 58, Rarity.UNCOMMON, mage.cards.u.Undo.class)); - cards.add(new SetCardInfo("Untamed Wilds", 148, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); - cards.add(new SetCardInfo("Venerable Monk", 28, Rarity.COMMON, mage.cards.v.VenerableMonk.class)); - cards.add(new SetCardInfo("Vengeance", 29, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); - cards.add(new SetCardInfo("Veteran Cavalier", 30, Rarity.UNCOMMON, mage.cards.v.VeteranCavalier.class)); - cards.add(new SetCardInfo("Vizzerdrix", 59, Rarity.RARE, mage.cards.v.Vizzerdrix.class)); - cards.add(new SetCardInfo("Volcanic Dragon", 122, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); - cards.add(new SetCardInfo("Volcanic Hammer", 123, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); - cards.add(new SetCardInfo("Water Elemental", 60, Rarity.UNCOMMON, mage.cards.w.WaterElemental.class)); - cards.add(new SetCardInfo("Whiptail Wurm", 149, Rarity.UNCOMMON, mage.cards.w.WhiptailWurm.class)); - cards.add(new SetCardInfo("Whirlwind", 150, Rarity.RARE, mage.cards.w.Whirlwind.class)); - cards.add(new SetCardInfo("Wicked Pact", 92, Rarity.RARE, mage.cards.w.WickedPact.class)); - cards.add(new SetCardInfo("Wild Griffin", 31, Rarity.COMMON, mage.cards.w.WildGriffin.class)); - cards.add(new SetCardInfo("Wild Ox", 151, Rarity.UNCOMMON, mage.cards.w.WildOx.class)); - cards.add(new SetCardInfo("Willow Elf", 152, Rarity.COMMON, mage.cards.w.WillowElf.class)); - cards.add(new SetCardInfo("Wind Drake", 61, Rarity.COMMON, mage.cards.w.WindDrake.class)); - cards.add(new SetCardInfo("Wind Sail", 62, Rarity.UNCOMMON, mage.cards.w.WindSail.class)); - cards.add(new SetCardInfo("Wood Elves", 153, Rarity.UNCOMMON, mage.cards.w.WoodElves.class)); - } -} +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author LevelX2 + */ +public final class Starter1999 extends ExpansionSet { + + private static final Starter1999 instance = new Starter1999(); + + public static Starter1999 getInstance() { + return instance; + } + + private Starter1999() { + super("Starter 1999", "S99", ExpansionSet.buildDate(1999, 7, 1), SetType.SUPPLEMENTAL); + this.blockName = "Beginner"; + this.hasBasicLands = true; + this.hasBoosters = true; + this.numBoosterLands = 2; + this.numBoosterCommon = 9; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Abyssal Horror", 63, Rarity.RARE, mage.cards.a.AbyssalHorror.class)); + cards.add(new SetCardInfo("Air Elemental", 32, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); + cards.add(new SetCardInfo("Alluring Scent", 124, Rarity.RARE, mage.cards.a.AlluringScent.class)); + cards.add(new SetCardInfo("Ancient Craving", 64, Rarity.RARE, mage.cards.a.AncientCraving.class)); + cards.add(new SetCardInfo("Angelic Blessing", 3, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); + cards.add(new SetCardInfo("Angel of Light", 1, Rarity.UNCOMMON, mage.cards.a.AngelOfLight.class)); + cards.add(new SetCardInfo("Angel of Mercy", 2, Rarity.UNCOMMON, mage.cards.a.AngelOfMercy.class)); + cards.add(new SetCardInfo("Archangel", 4, Rarity.RARE, mage.cards.a.Archangel.class)); + cards.add(new SetCardInfo("Ardent Militia", 5, Rarity.UNCOMMON, mage.cards.a.ArdentMilitia.class)); + cards.add(new SetCardInfo("Armageddon", 6, Rarity.RARE, mage.cards.a.Armageddon.class)); + cards.add(new SetCardInfo("Barbtooth Wurm", 125, Rarity.COMMON, mage.cards.b.BarbtoothWurm.class)); + cards.add(new SetCardInfo("Bargain", 7, Rarity.UNCOMMON, mage.cards.b.Bargain.class)); + cards.add(new SetCardInfo("Blinding Light", 8, Rarity.RARE, mage.cards.b.BlindingLight.class)); + cards.add(new SetCardInfo("Bog Imp", 65, Rarity.COMMON, mage.cards.b.BogImp.class)); + cards.add(new SetCardInfo("Bog Raiders", 66, Rarity.COMMON, mage.cards.b.BogRaiders.class)); + cards.add(new SetCardInfo("Bog Wraith", 67, Rarity.UNCOMMON, mage.cards.b.BogWraith.class)); + cards.add(new SetCardInfo("Border Guard", 9, Rarity.COMMON, mage.cards.b.BorderGuard.class)); + cards.add(new SetCardInfo("Breath of Life", 10, Rarity.UNCOMMON, mage.cards.b.BreathOfLife.class)); + cards.add(new SetCardInfo("Bull Hippo", 126, Rarity.UNCOMMON, mage.cards.b.BullHippo.class)); + cards.add(new SetCardInfo("Champion Lancer", 11, Rarity.RARE, mage.cards.c.ChampionLancer.class)); + cards.add(new SetCardInfo("Charging Paladin", 12, Rarity.UNCOMMON, mage.cards.c.ChargingPaladin.class)); + cards.add(new SetCardInfo("Chorus of Woe", 68, Rarity.COMMON, mage.cards.c.ChorusOfWoe.class)); + cards.add(new SetCardInfo("Cinder Storm", 93, Rarity.UNCOMMON, mage.cards.c.CinderStorm.class)); + cards.add(new SetCardInfo("Coercion", 69, Rarity.UNCOMMON, mage.cards.c.Coercion.class)); + cards.add(new SetCardInfo("Coral Eel", 33, Rarity.COMMON, mage.cards.c.CoralEel.class)); + cards.add(new SetCardInfo("Counterspell", 34, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); + cards.add(new SetCardInfo("Dakmor Ghoul", 70, Rarity.UNCOMMON, mage.cards.d.DakmorGhoul.class)); + cards.add(new SetCardInfo("Dakmor Lancer", 71, Rarity.RARE, mage.cards.d.DakmorLancer.class)); + cards.add(new SetCardInfo("Dakmor Plague", 72, Rarity.UNCOMMON, mage.cards.d.DakmorPlague.class)); + cards.add(new SetCardInfo("Dakmor Scorpion", 73, Rarity.COMMON, mage.cards.d.DakmorScorpion.class)); + cards.add(new SetCardInfo("Dakmor Sorceress", 74, Rarity.RARE, mage.cards.d.DakmorSorceress.class)); + cards.add(new SetCardInfo("Dark Offering", 75, Rarity.UNCOMMON, mage.cards.d.DarkOffering.class)); + cards.add(new SetCardInfo("Denizen of the Deep", 35, Rarity.RARE, mage.cards.d.DenizenOfTheDeep.class)); + cards.add(new SetCardInfo("Devastation", 94, Rarity.RARE, mage.cards.d.Devastation.class)); + cards.add(new SetCardInfo("Devoted Hero", 13, Rarity.COMMON, mage.cards.d.DevotedHero.class)); + cards.add(new SetCardInfo("Devout Monk", 14, Rarity.COMMON, mage.cards.d.DevoutMonk.class)); + cards.add(new SetCardInfo("Dread Reaper", 76, Rarity.RARE, mage.cards.d.DreadReaper.class)); + cards.add(new SetCardInfo("Durkwood Boars", 127, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class)); + cards.add(new SetCardInfo("Eager Cadet", 15, Rarity.COMMON, mage.cards.e.EagerCadet.class)); + cards.add(new SetCardInfo("Earth Elemental", 95, Rarity.UNCOMMON, mage.cards.e.EarthElemental.class)); + cards.add(new SetCardInfo("Exhaustion", 36, Rarity.UNCOMMON, mage.cards.e.Exhaustion.class)); + cards.add(new SetCardInfo("Extinguish", 37, Rarity.COMMON, mage.cards.e.Extinguish.class)); + cards.add(new SetCardInfo("Eye Spy", 38, Rarity.UNCOMMON, mage.cards.e.EyeSpy.class)); + cards.add(new SetCardInfo("False Peace", 16, Rarity.UNCOMMON, mage.cards.f.FalsePeace.class)); + cards.add(new SetCardInfo("Feral Shadow", 77, Rarity.COMMON, mage.cards.f.FeralShadow.class)); + cards.add(new SetCardInfo("Fire Elemental", 96, Rarity.UNCOMMON, mage.cards.f.FireElemental.class)); + cards.add(new SetCardInfo("Fire Tempest", 97, Rarity.RARE, mage.cards.f.FireTempest.class)); + cards.add(new SetCardInfo("Foot Soldiers", 17, Rarity.COMMON, mage.cards.f.FootSoldiers.class)); + cards.add(new SetCardInfo("Forest", 170, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 171, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 172, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 173, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gerrard's Wisdom", 18, Rarity.RARE, mage.cards.g.GerrardsWisdom.class)); + cards.add(new SetCardInfo("Giant Octopus", 39, Rarity.COMMON, mage.cards.g.GiantOctopus.class)); + cards.add(new SetCardInfo("Goblin Cavaliers", 98, Rarity.COMMON, mage.cards.g.GoblinCavaliers.class)); + cards.add(new SetCardInfo("Goblin Chariot", 99, Rarity.COMMON, mage.cards.g.GoblinChariot.class)); + cards.add(new SetCardInfo("Goblin Commando", 100, Rarity.UNCOMMON, mage.cards.g.GoblinCommando.class)); + cards.add(new SetCardInfo("Goblin General", 101, Rarity.UNCOMMON, mage.cards.g.GoblinGeneral.class)); + cards.add(new SetCardInfo("Goblin Glider", 102, Rarity.UNCOMMON, mage.cards.g.GoblinGlider.class)); + cards.add(new SetCardInfo("Goblin Hero", 103, Rarity.COMMON, mage.cards.g.GoblinHero.class)); + cards.add(new SetCardInfo("Goblin Lore", 104, Rarity.UNCOMMON, mage.cards.g.GoblinLore.class)); + cards.add(new SetCardInfo("Goblin Mountaineer", 105, Rarity.COMMON, mage.cards.g.GoblinMountaineer.class)); + cards.add(new SetCardInfo("Goblin Settler", 106, Rarity.UNCOMMON, mage.cards.g.GoblinSettler.class)); + cards.add(new SetCardInfo("Gorilla Warrior", 128, Rarity.COMMON, mage.cards.g.GorillaWarrior.class)); + cards.add(new SetCardInfo("Gravedigger", 78, Rarity.UNCOMMON, mage.cards.g.Gravedigger.class)); + cards.add(new SetCardInfo("Grim Tutor", 79, Rarity.RARE, mage.cards.g.GrimTutor.class)); + cards.add(new SetCardInfo("Grizzly Bears", 129, Rarity.COMMON, mage.cards.g.GrizzlyBears.class)); + cards.add(new SetCardInfo("Hand of Death", 80, Rarity.COMMON, mage.cards.h.HandOfDeath.class)); + cards.add(new SetCardInfo("Hollow Dogs", 81, Rarity.COMMON, mage.cards.h.HollowDogs.class)); + cards.add(new SetCardInfo("Howling Fury", 82, Rarity.UNCOMMON, mage.cards.h.HowlingFury.class)); + cards.add(new SetCardInfo("Hulking Goblin", 107, Rarity.COMMON, mage.cards.h.HulkingGoblin.class)); + cards.add(new SetCardInfo("Hulking Ogre", 108, Rarity.UNCOMMON, mage.cards.h.HulkingOgre.class)); + cards.add(new SetCardInfo("Ingenious Thief", 40, Rarity.COMMON, mage.cards.i.IngeniousThief.class)); + cards.add(new SetCardInfo("Island", 158, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 159, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 160, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 161, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jagged Lightning", 109, Rarity.UNCOMMON, mage.cards.j.JaggedLightning.class)); + cards.add(new SetCardInfo("Knight Errant", 19, Rarity.COMMON, mage.cards.k.KnightErrant.class)); + cards.add(new SetCardInfo("Last Chance", 110, Rarity.RARE, mage.cards.l.LastChance.class)); + cards.add(new SetCardInfo("Lava Axe", 111, Rarity.COMMON, mage.cards.l.LavaAxe.class)); + cards.add(new SetCardInfo("Lone Wolf", 130, Rarity.COMMON, mage.cards.l.LoneWolf.class)); + cards.add(new SetCardInfo("Loyal Sentry", 20, Rarity.RARE, mage.cards.l.LoyalSentry.class)); + cards.add(new SetCardInfo("Lynx", 131, Rarity.UNCOMMON, mage.cards.l.Lynx.class)); + cards.add(new SetCardInfo("Man-o'-War", 41, Rarity.UNCOMMON, mage.cards.m.ManOWar.class)); + cards.add(new SetCardInfo("Merfolk of the Pearl Trident", 42, Rarity.COMMON, mage.cards.m.MerfolkOfThePearlTrident.class)); + cards.add(new SetCardInfo("Mind Rot", 83, Rarity.COMMON, mage.cards.m.MindRot.class)); + cards.add(new SetCardInfo("Mons's Goblin Raiders", 112, Rarity.COMMON, mage.cards.m.MonssGoblinRaiders.class)); + cards.add(new SetCardInfo("Monstrous Growth", 132, Rarity.COMMON, mage.cards.m.MonstrousGrowth.class)); + cards.add(new SetCardInfo("Moon Sprite", 133, Rarity.UNCOMMON, mage.cards.m.MoonSprite.class)); + cards.add(new SetCardInfo("Mountain", 166, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 167, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 168, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 169, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Muck Rats", 84, Rarity.COMMON, mage.cards.m.MuckRats.class)); + cards.add(new SetCardInfo("Natural Spring", 134, Rarity.UNCOMMON, mage.cards.n.NaturalSpring.class)); + cards.add(new SetCardInfo("Nature's Cloak", 135, Rarity.RARE, mage.cards.n.NaturesCloak.class)); + cards.add(new SetCardInfo("Nature's Lore", 136, Rarity.COMMON, mage.cards.n.NaturesLore.class)); + cards.add(new SetCardInfo("Norwood Archers", 137, Rarity.COMMON, mage.cards.n.NorwoodArchers.class)); + cards.add(new SetCardInfo("Norwood Ranger", 138, Rarity.COMMON, mage.cards.n.NorwoodRanger.class)); + cards.add(new SetCardInfo("Ogre Warrior", 113, Rarity.COMMON, mage.cards.o.OgreWarrior.class)); + cards.add(new SetCardInfo("Path of Peace", 21, Rarity.COMMON, mage.cards.p.PathOfPeace.class)); + cards.add(new SetCardInfo("Phantom Warrior", 44, Rarity.RARE, mage.cards.p.PhantomWarrior.class)); + cards.add(new SetCardInfo("Plains", 154, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 155, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 156, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 157, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Pride of Lions", 139, Rarity.UNCOMMON, mage.cards.p.PrideOfLions.class)); + cards.add(new SetCardInfo("Psychic Transfer", 46, Rarity.RARE, mage.cards.p.PsychicTransfer.class)); + cards.add(new SetCardInfo("Raging Goblin", 114, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); + cards.add(new SetCardInfo("Raise Dead", 85, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Ransack", 47, Rarity.RARE, mage.cards.r.Ransack.class)); + cards.add(new SetCardInfo("Ravenous Rats", 86, Rarity.UNCOMMON, mage.cards.r.RavenousRats.class)); + cards.add(new SetCardInfo("Relearn", 48, Rarity.UNCOMMON, mage.cards.r.Relearn.class)); + cards.add(new SetCardInfo("Relentless Assault", 115, Rarity.RARE, mage.cards.r.RelentlessAssault.class)); + cards.add(new SetCardInfo("Remove Soul", 49, Rarity.COMMON, mage.cards.r.RemoveSoul.class)); + cards.add(new SetCardInfo("Renewing Touch", 140, Rarity.UNCOMMON, mage.cards.r.RenewingTouch.class)); + cards.add(new SetCardInfo("Righteous Charge", 22, Rarity.UNCOMMON, mage.cards.r.RighteousCharge.class)); + cards.add(new SetCardInfo("Righteous Fury", 23, Rarity.RARE, mage.cards.r.RighteousFury.class)); + cards.add(new SetCardInfo("Royal Falcon", 24, Rarity.COMMON, mage.cards.r.RoyalFalcon.class)); + cards.add(new SetCardInfo("Royal Trooper", 25, Rarity.UNCOMMON, mage.cards.r.RoyalTrooper.class)); + cards.add(new SetCardInfo("Sacred Nectar", 26, Rarity.COMMON, mage.cards.s.SacredNectar.class)); + cards.add(new SetCardInfo("Scathe Zombies", 87, Rarity.COMMON, mage.cards.s.ScatheZombies.class)); + cards.add(new SetCardInfo("Scorching Spear", 116, Rarity.COMMON, mage.cards.s.ScorchingSpear.class)); + cards.add(new SetCardInfo("Sea Eagle", 50, Rarity.COMMON, mage.cards.s.SeaEagle.class)); + cards.add(new SetCardInfo("Serpent Warrior", 88, Rarity.COMMON, mage.cards.s.SerpentWarrior.class)); + cards.add(new SetCardInfo("Shrieking Specter", 89, Rarity.UNCOMMON, mage.cards.s.ShriekingSpecter.class)); + cards.add(new SetCardInfo("Silverback Ape", 141, Rarity.UNCOMMON, mage.cards.s.SilverbackApe.class)); + cards.add(new SetCardInfo("Sleight of Hand", 51, Rarity.COMMON, mage.cards.s.SleightOfHand.class)); + cards.add(new SetCardInfo("Snapping Drake", 52, Rarity.COMMON, mage.cards.s.SnappingDrake.class)); + cards.add(new SetCardInfo("Soul Feast", 90, Rarity.UNCOMMON, mage.cards.s.SoulFeast.class)); + cards.add(new SetCardInfo("Southern Elephant", 142, Rarity.COMMON, mage.cards.s.SouthernElephant.class)); + cards.add(new SetCardInfo("Spitting Earth", 117, Rarity.UNCOMMON, mage.cards.s.SpittingEarth.class)); + cards.add(new SetCardInfo("Squall", 143, Rarity.COMMON, mage.cards.s.Squall.class)); + cards.add(new SetCardInfo("Steadfastness", 27, Rarity.COMMON, mage.cards.s.Steadfastness.class)); + cards.add(new SetCardInfo("Stone Rain", 118, Rarity.COMMON, mage.cards.s.StoneRain.class)); + cards.add(new SetCardInfo("Storm Crow", 53, Rarity.COMMON, mage.cards.s.StormCrow.class)); + cards.add(new SetCardInfo("Stream of Acid", 91, Rarity.UNCOMMON, mage.cards.s.StreamOfAcid.class)); + cards.add(new SetCardInfo("Summer Bloom", 144, Rarity.RARE, mage.cards.s.SummerBloom.class)); + cards.add(new SetCardInfo("Swamp", 162, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 163, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 164, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 165, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sylvan Basilisk", 145, Rarity.RARE, mage.cards.s.SylvanBasilisk.class)); + cards.add(new SetCardInfo("Sylvan Yeti", 146, Rarity.RARE, mage.cards.s.SylvanYeti.class)); + cards.add(new SetCardInfo("Thorn Elemental", 147, Rarity.RARE, mage.cards.t.ThornElemental.class)); + cards.add(new SetCardInfo("Thunder Dragon", 119, Rarity.RARE, mage.cards.t.ThunderDragon.class)); + cards.add(new SetCardInfo("Tidings", 54, Rarity.UNCOMMON, mage.cards.t.Tidings.class)); + cards.add(new SetCardInfo("Time Ebb", 55, Rarity.COMMON, mage.cards.t.TimeEbb.class)); + cards.add(new SetCardInfo("Time Warp", 56, Rarity.RARE, mage.cards.t.TimeWarp.class)); + cards.add(new SetCardInfo("Touch of Brilliance", 57, Rarity.COMMON, mage.cards.t.TouchOfBrilliance.class)); + cards.add(new SetCardInfo("Trained Orgg", 120, Rarity.RARE, mage.cards.t.TrainedOrgg.class)); + cards.add(new SetCardInfo("Tremor", 121, Rarity.COMMON, mage.cards.t.Tremor.class)); + cards.add(new SetCardInfo("Undo", 58, Rarity.UNCOMMON, mage.cards.u.Undo.class)); + cards.add(new SetCardInfo("Untamed Wilds", 148, Rarity.UNCOMMON, mage.cards.u.UntamedWilds.class)); + cards.add(new SetCardInfo("Venerable Monk", 28, Rarity.COMMON, mage.cards.v.VenerableMonk.class)); + cards.add(new SetCardInfo("Vengeance", 29, Rarity.UNCOMMON, mage.cards.v.Vengeance.class)); + cards.add(new SetCardInfo("Veteran Cavalier", 30, Rarity.UNCOMMON, mage.cards.v.VeteranCavalier.class)); + cards.add(new SetCardInfo("Vizzerdrix", 59, Rarity.RARE, mage.cards.v.Vizzerdrix.class)); + cards.add(new SetCardInfo("Volcanic Dragon", 122, Rarity.RARE, mage.cards.v.VolcanicDragon.class)); + cards.add(new SetCardInfo("Volcanic Hammer", 123, Rarity.COMMON, mage.cards.v.VolcanicHammer.class)); + cards.add(new SetCardInfo("Water Elemental", 60, Rarity.UNCOMMON, mage.cards.w.WaterElemental.class)); + cards.add(new SetCardInfo("Whiptail Wurm", 149, Rarity.UNCOMMON, mage.cards.w.WhiptailWurm.class)); + cards.add(new SetCardInfo("Whirlwind", 150, Rarity.RARE, mage.cards.w.Whirlwind.class)); + cards.add(new SetCardInfo("Wicked Pact", 92, Rarity.RARE, mage.cards.w.WickedPact.class)); + cards.add(new SetCardInfo("Wild Griffin", 31, Rarity.COMMON, mage.cards.w.WildGriffin.class)); + cards.add(new SetCardInfo("Wild Ox", 151, Rarity.UNCOMMON, mage.cards.w.WildOx.class)); + cards.add(new SetCardInfo("Willow Elf", 152, Rarity.COMMON, mage.cards.w.WillowElf.class)); + cards.add(new SetCardInfo("Wind Drake", 61, Rarity.COMMON, mage.cards.w.WindDrake.class)); + cards.add(new SetCardInfo("Wind Sail", 62, Rarity.UNCOMMON, mage.cards.w.WindSail.class)); + cards.add(new SetCardInfo("Wood Elves", 153, Rarity.UNCOMMON, mage.cards.w.WoodElves.class)); + } +} From 21c6afa1c70d790474f79051bc69ede7e07dbdf7 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 5 Dec 2018 16:05:46 -0600 Subject: [PATCH 49/50] - Added Volrath's Dungeon. --- .../src/mage/cards/v/VolrathsDungeon.java | 132 +++++++ Mage.Sets/src/mage/sets/Exodus.java | 331 +++++++++--------- .../mage/abilities/ActivatedAbilityImpl.java | 37 +- 3 files changed, 325 insertions(+), 175 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/v/VolrathsDungeon.java diff --git a/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java b/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java new file mode 100644 index 00000000000..3c0680016d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java @@ -0,0 +1,132 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroySourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; + +/** + * + * @author jeffwadsworth + */ +public final class VolrathsDungeon extends CardImpl { + + public VolrathsDungeon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); + + // Pay 5 life: Destroy Volrath's Dungeon. Any player may activate this ability but only during his or her turn. + ActivatedAbility ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new DestroySourceEffect().setText("Destroy {this}. Any player may activate this ability but only during his or her turn."), + new PayLifeActivePlayerCost(5)); + ability.setMayActivate(TargetController.ACTIVE); + this.addAbility(ability); + + // Discard a card: Target player puts a card from his or her hand on top of his or her library. Activate this ability only any time you could cast a sorcery. + FilterCard filter = new FilterCard("a card for payment"); + Ability ability2 = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new VolrathsDungeonEffect(), new DiscardCardCost(filter)); + ability2.addTarget(new TargetPlayer()); + this.addAbility(ability2); + } + + public VolrathsDungeon(final VolrathsDungeon card) { + super(card); + } + + @Override + public VolrathsDungeon copy() { + return new VolrathsDungeon(this); + } +} + +class PayLifeActivePlayerCost extends CostImpl { + + private final DynamicValue amount; + + public PayLifeActivePlayerCost(int amount) { + this.amount = new StaticValue(amount); + this.text = "Pay " + Integer.toString(amount) + " life"; + } + + public PayLifeActivePlayerCost(DynamicValue amount, String text) { + this.amount = amount.copy(); + this.text = "Pay " + text; + } + + public PayLifeActivePlayerCost(PayLifeActivePlayerCost cost) { + super(cost); + this.amount = cost.amount.copy(); + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + int lifeToPayAmount = amount.calculate(game, ability, null); + return game.getPlayer(game.getActivePlayerId()).getLife() >= lifeToPayAmount; + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + int lifeToPayAmount = amount.calculate(game, ability, null); + Player activatingPlayer = game.getPlayer(game.getActivePlayerId()); + if (activatingPlayer != null + && activatingPlayer.chooseUse(Outcome.LoseLife, "Do you wish to pay + lifeToPayAmount + life?", ability, game)) { + this.paid = game.getPlayer(game.getActivePlayerId()).loseLife(lifeToPayAmount, game, false) == lifeToPayAmount; + } + return paid; + } + + @Override + public PayLifeActivePlayerCost copy() { + return new PayLifeActivePlayerCost(this); + } +} + +class VolrathsDungeonEffect extends OneShotEffect { + + public VolrathsDungeonEffect() { + super(Outcome.Detriment); + this.staticText = "Target player puts a card from his or her hand on top of his or her library"; + } + + public VolrathsDungeonEffect(final VolrathsDungeonEffect effect) { + super(effect); + } + + @Override + public VolrathsDungeonEffect copy() { + return new VolrathsDungeonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetedPlayer = game.getPlayer(source.getFirstTarget()); + if (targetedPlayer != null) { + TargetCardInHand target = new TargetCardInHand(); + if (targetedPlayer.choose(Outcome.Detriment, targetedPlayer.getHand(), target, game)) { + Card card = game.getCard(target.getFirstTarget()); + return targetedPlayer.putCardOnTopXOfLibrary(card, game, source, 0); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index d1091318d43..04e9a204467 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -1,165 +1,166 @@ - -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author North - */ -public final class Exodus extends ExpansionSet { - - private static final Exodus instance = new Exodus(); - - public static Exodus getInstance() { - return instance; - } - - private Exodus() { - super("Exodus", "EXO", ExpansionSet.buildDate(1998, 6, 15), SetType.EXPANSION); - this.blockName = "Tempest"; - this.parentSet = Tempest.getInstance(); - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 0; - cards.add(new SetCardInfo("Allay", 1, Rarity.COMMON, mage.cards.a.Allay.class)); - cards.add(new SetCardInfo("Anarchist", 79, Rarity.COMMON, mage.cards.a.Anarchist.class)); - cards.add(new SetCardInfo("Angelic Blessing", 2, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); - cards.add(new SetCardInfo("Avenging Druid", 105, Rarity.COMMON, mage.cards.a.AvengingDruid.class)); - cards.add(new SetCardInfo("Bequeathal", 106, Rarity.COMMON, mage.cards.b.Bequeathal.class)); - cards.add(new SetCardInfo("Carnophage", 53, Rarity.COMMON, mage.cards.c.Carnophage.class)); - cards.add(new SetCardInfo("Cartographer", 107, Rarity.UNCOMMON, mage.cards.c.Cartographer.class)); - cards.add(new SetCardInfo("Cataclysm", 3, Rarity.RARE, mage.cards.c.Cataclysm.class)); - cards.add(new SetCardInfo("Cat Burglar", 54, Rarity.COMMON, mage.cards.c.CatBurglar.class)); - cards.add(new SetCardInfo("Charging Paladin", 4, Rarity.COMMON, mage.cards.c.ChargingPaladin.class)); - cards.add(new SetCardInfo("Cinder Crawler", 80, Rarity.COMMON, mage.cards.c.CinderCrawler.class)); - cards.add(new SetCardInfo("City of Traitors", 143, Rarity.RARE, mage.cards.c.CityOfTraitors.class)); - cards.add(new SetCardInfo("Coat of Arms", 131, Rarity.RARE, mage.cards.c.CoatOfArms.class)); - cards.add(new SetCardInfo("Convalescence", 5, Rarity.RARE, mage.cards.c.Convalescence.class)); - cards.add(new SetCardInfo("Crashing Boars", 108, Rarity.UNCOMMON, mage.cards.c.CrashingBoars.class)); - cards.add(new SetCardInfo("Culling the Weak", 55, Rarity.COMMON, mage.cards.c.CullingTheWeak.class)); - cards.add(new SetCardInfo("Curiosity", 29, Rarity.UNCOMMON, mage.cards.c.Curiosity.class)); - cards.add(new SetCardInfo("Cursed Flesh", 56, Rarity.COMMON, mage.cards.c.CursedFlesh.class)); - cards.add(new SetCardInfo("Dauthi Cutthroat", 57, Rarity.UNCOMMON, mage.cards.d.DauthiCutthroat.class)); - cards.add(new SetCardInfo("Dauthi Jackal", 58, Rarity.COMMON, mage.cards.d.DauthiJackal.class)); - cards.add(new SetCardInfo("Dauthi Warlord", 59, Rarity.UNCOMMON, mage.cards.d.DauthiWarlord.class)); - cards.add(new SetCardInfo("Death's Duet", 60, Rarity.COMMON, mage.cards.d.DeathsDuet.class)); - cards.add(new SetCardInfo("Dominating Licid", 30, Rarity.RARE, mage.cards.d.DominatingLicid.class)); - cards.add(new SetCardInfo("Elven Palisade", 109, Rarity.UNCOMMON, mage.cards.e.ElvenPalisade.class)); - cards.add(new SetCardInfo("Elvish Berserker", 110, Rarity.COMMON, mage.cards.e.ElvishBerserker.class)); - cards.add(new SetCardInfo("Entropic Specter", 61, Rarity.RARE, mage.cards.e.EntropicSpecter.class)); - cards.add(new SetCardInfo("Ephemeron", 31, Rarity.RARE, mage.cards.e.Ephemeron.class)); - cards.add(new SetCardInfo("Equilibrium", 32, Rarity.RARE, mage.cards.e.Equilibrium.class)); - cards.add(new SetCardInfo("Erratic Portal", 132, Rarity.RARE, mage.cards.e.ErraticPortal.class)); - cards.add(new SetCardInfo("Ertai, Wizard Adept", 33, Rarity.RARE, mage.cards.e.ErtaiWizardAdept.class)); - cards.add(new SetCardInfo("Exalted Dragon", 6, Rarity.RARE, mage.cards.e.ExaltedDragon.class)); - cards.add(new SetCardInfo("Fade Away", 34, Rarity.COMMON, mage.cards.f.FadeAway.class)); - cards.add(new SetCardInfo("Fighting Chance", 82, Rarity.RARE, mage.cards.f.FightingChance.class)); - cards.add(new SetCardInfo("Flowstone Flood", 83, Rarity.UNCOMMON, mage.cards.f.FlowstoneFlood.class)); - cards.add(new SetCardInfo("Forbid", 35, Rarity.UNCOMMON, mage.cards.f.Forbid.class)); - cards.add(new SetCardInfo("Fugue", 62, Rarity.UNCOMMON, mage.cards.f.Fugue.class)); - cards.add(new SetCardInfo("Furnace Brood", 84, Rarity.COMMON, mage.cards.f.FurnaceBrood.class)); - cards.add(new SetCardInfo("Hatred", 64, Rarity.RARE, mage.cards.h.Hatred.class)); - cards.add(new SetCardInfo("High Ground", 7, Rarity.UNCOMMON, mage.cards.h.HighGround.class)); - cards.add(new SetCardInfo("Jackalope Herd", 111, Rarity.COMMON, mage.cards.j.JackalopeHerd.class)); - cards.add(new SetCardInfo("Keeper of the Beasts", 112, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheBeasts.class)); - cards.add(new SetCardInfo("Keeper of the Dead", 65, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheDead.class)); - cards.add(new SetCardInfo("Keeper of the Light", 8, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheLight.class)); - cards.add(new SetCardInfo("Keeper of the Mind", 36, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheMind.class)); - cards.add(new SetCardInfo("Killer Whale", 37, Rarity.UNCOMMON, mage.cards.k.KillerWhale.class)); - cards.add(new SetCardInfo("Kor Chant", 9, Rarity.COMMON, mage.cards.k.KorChant.class)); - cards.add(new SetCardInfo("Mage il-Vec", 86, Rarity.COMMON, mage.cards.m.MageIlVec.class)); - cards.add(new SetCardInfo("Manabond", 113, Rarity.RARE, mage.cards.m.Manabond.class)); - cards.add(new SetCardInfo("Mana Breach", 38, Rarity.UNCOMMON, mage.cards.m.ManaBreach.class)); - cards.add(new SetCardInfo("Maniacal Rage", 87, Rarity.COMMON, mage.cards.m.ManiacalRage.class)); - cards.add(new SetCardInfo("Medicine Bag", 133, Rarity.UNCOMMON, mage.cards.m.MedicineBag.class)); - cards.add(new SetCardInfo("Memory Crystal", 134, Rarity.RARE, mage.cards.m.MemoryCrystal.class)); - cards.add(new SetCardInfo("Merfolk Looter", 39, Rarity.COMMON, mage.cards.m.MerfolkLooter.class)); - cards.add(new SetCardInfo("Mindless Automaton", 135, Rarity.RARE, mage.cards.m.MindlessAutomaton.class)); - cards.add(new SetCardInfo("Mind Over Matter", 40, Rarity.RARE, mage.cards.m.MindOverMatter.class)); - cards.add(new SetCardInfo("Mirozel", 41, Rarity.UNCOMMON, mage.cards.m.Mirozel.class)); - cards.add(new SetCardInfo("Mirri, Cat Warrior", 114, Rarity.RARE, mage.cards.m.MirriCatWarrior.class)); - cards.add(new SetCardInfo("Mogg Assassin", 88, Rarity.UNCOMMON, mage.cards.m.MoggAssassin.class)); - cards.add(new SetCardInfo("Nausea", 67, Rarity.COMMON, mage.cards.n.Nausea.class)); - cards.add(new SetCardInfo("Necrologia", 68, Rarity.UNCOMMON, mage.cards.n.Necrologia.class)); - cards.add(new SetCardInfo("Null Brooch", 136, Rarity.RARE, mage.cards.n.NullBrooch.class)); - cards.add(new SetCardInfo("Oath of Druids", 115, Rarity.RARE, mage.cards.o.OathOfDruids.class)); - cards.add(new SetCardInfo("Oath of Ghouls", 69, Rarity.RARE, mage.cards.o.OathOfGhouls.class)); - cards.add(new SetCardInfo("Oath of Lieges", 11, Rarity.RARE, mage.cards.o.OathOfLieges.class)); - cards.add(new SetCardInfo("Oath of Mages", 90, Rarity.RARE, mage.cards.o.OathOfMages.class)); - cards.add(new SetCardInfo("Oath of Scholars", 42, Rarity.RARE, mage.cards.o.OathOfScholars.class)); - cards.add(new SetCardInfo("Ogre Shaman", 91, Rarity.RARE, mage.cards.o.OgreShaman.class)); - cards.add(new SetCardInfo("Onslaught", 92, Rarity.COMMON, mage.cards.o.Onslaught.class)); - cards.add(new SetCardInfo("Paladin en-Vec", 12, Rarity.RARE, mage.cards.p.PaladinEnVec.class)); - cards.add(new SetCardInfo("Pandemonium", 93, Rarity.RARE, mage.cards.p.Pandemonium.class)); - cards.add(new SetCardInfo("Peace of Mind", 13, Rarity.UNCOMMON, mage.cards.p.PeaceOfMind.class)); - cards.add(new SetCardInfo("Pegasus Stampede", 14, Rarity.UNCOMMON, mage.cards.p.PegasusStampede.class)); - cards.add(new SetCardInfo("Penance", 15, Rarity.UNCOMMON, mage.cards.p.Penance.class)); - cards.add(new SetCardInfo("Pit Spawn", 70, Rarity.RARE, mage.cards.p.PitSpawn.class)); - cards.add(new SetCardInfo("Plaguebearer", 71, Rarity.RARE, mage.cards.p.Plaguebearer.class)); - cards.add(new SetCardInfo("Plated Rootwalla", 116, Rarity.COMMON, mage.cards.p.PlatedRootwalla.class)); - cards.add(new SetCardInfo("Predatory Hunger", 117, Rarity.COMMON, mage.cards.p.PredatoryHunger.class)); - cards.add(new SetCardInfo("Price of Progress", 95, Rarity.UNCOMMON, mage.cards.p.PriceOfProgress.class)); - cards.add(new SetCardInfo("Pygmy Troll", 118, Rarity.COMMON, mage.cards.p.PygmyTroll.class)); - cards.add(new SetCardInfo("Rabid Wolverines", 119, Rarity.COMMON, mage.cards.r.RabidWolverines.class)); - cards.add(new SetCardInfo("Raging Goblin", 96, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); - cards.add(new SetCardInfo("Ravenous Baboons", 97, Rarity.RARE, mage.cards.r.RavenousBaboons.class)); - cards.add(new SetCardInfo("Reaping the Rewards", 16, Rarity.COMMON, mage.cards.r.ReapingTheRewards.class)); - cards.add(new SetCardInfo("Reckless Ogre", 98, Rarity.COMMON, mage.cards.r.RecklessOgre.class)); - cards.add(new SetCardInfo("Reclaim", 120, Rarity.COMMON, mage.cards.r.Reclaim.class)); - cards.add(new SetCardInfo("Reconnaissance", 17, Rarity.UNCOMMON, mage.cards.r.Reconnaissance.class)); - cards.add(new SetCardInfo("Recurring Nightmare", 72, Rarity.RARE, mage.cards.r.RecurringNightmare.class)); - cards.add(new SetCardInfo("Resuscitate", 121, Rarity.UNCOMMON, mage.cards.r.Resuscitate.class)); - cards.add(new SetCardInfo("Robe of Mirrors", 43, Rarity.COMMON, mage.cards.r.RobeOfMirrors.class)); - cards.add(new SetCardInfo("Rootwater Alligator", 122, Rarity.COMMON, mage.cards.r.RootwaterAlligator.class)); - cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); - cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); - cards.add(new SetCardInfo("Scalding Salamander", 100, Rarity.UNCOMMON, mage.cards.s.ScaldingSalamander.class)); - cards.add(new SetCardInfo("Scare Tactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); - cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); - cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); - cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); - cards.add(new SetCardInfo("Shackles", 18, Rarity.COMMON, mage.cards.s.Shackles.class)); - cards.add(new SetCardInfo("Shattering Pulse", 102, Rarity.COMMON, mage.cards.s.ShatteringPulse.class)); - cards.add(new SetCardInfo("Shield Mate", 19, Rarity.COMMON, mage.cards.s.ShieldMate.class)); - cards.add(new SetCardInfo("Skyshaper", 137, Rarity.UNCOMMON, mage.cards.s.Skyshaper.class)); - cards.add(new SetCardInfo("Skyshroud Elite", 123, Rarity.UNCOMMON, mage.cards.s.SkyshroudElite.class)); - cards.add(new SetCardInfo("Skyshroud War Beast", 124, Rarity.RARE, mage.cards.s.SkyshroudWarBeast.class)); - cards.add(new SetCardInfo("Slaughter", 74, Rarity.UNCOMMON, mage.cards.s.Slaughter.class)); - cards.add(new SetCardInfo("Soltari Visionary", 20, Rarity.COMMON, mage.cards.s.SoltariVisionary.class)); - cards.add(new SetCardInfo("Song of Serenity", 125, Rarity.UNCOMMON, mage.cards.s.SongOfSerenity.class)); - cards.add(new SetCardInfo("Sonic Burst", 103, Rarity.COMMON, mage.cards.s.SonicBurst.class)); - cards.add(new SetCardInfo("Soul Warden", 21, Rarity.COMMON, mage.cards.s.SoulWarden.class)); - cards.add(new SetCardInfo("Spellbook", 138, Rarity.UNCOMMON, mage.cards.s.Spellbook.class)); - cards.add(new SetCardInfo("Spellshock", 104, Rarity.UNCOMMON, mage.cards.s.Spellshock.class)); - cards.add(new SetCardInfo("Sphere of Resistance", 139, Rarity.RARE, mage.cards.s.SphereOfResistance.class)); - cards.add(new SetCardInfo("Spike Cannibal", 75, Rarity.UNCOMMON, mage.cards.s.SpikeCannibal.class)); - cards.add(new SetCardInfo("Spike Hatcher", 126, Rarity.RARE, mage.cards.s.SpikeHatcher.class)); - cards.add(new SetCardInfo("Spike Rogue", 127, Rarity.UNCOMMON, mage.cards.s.SpikeRogue.class)); - cards.add(new SetCardInfo("Spike Weaver", 128, Rarity.RARE, mage.cards.s.SpikeWeaver.class)); - cards.add(new SetCardInfo("Standing Troops", 22, Rarity.COMMON, mage.cards.s.StandingTroops.class)); - cards.add(new SetCardInfo("Survival of the Fittest", 129, Rarity.RARE, mage.cards.s.SurvivalOfTheFittest.class)); - cards.add(new SetCardInfo("Thalakos Drifters", 47, Rarity.RARE, mage.cards.t.ThalakosDrifters.class)); - cards.add(new SetCardInfo("Thalakos Scout", 48, Rarity.COMMON, mage.cards.t.ThalakosScout.class)); - cards.add(new SetCardInfo("Theft of Dreams", 49, Rarity.COMMON, mage.cards.t.TheftOfDreams.class)); - cards.add(new SetCardInfo("Thopter Squadron", 140, Rarity.RARE, mage.cards.t.ThopterSquadron.class)); - cards.add(new SetCardInfo("Thrull Surgeon", 76, Rarity.COMMON, mage.cards.t.ThrullSurgeon.class)); - cards.add(new SetCardInfo("Transmogrifying Licid", 141, Rarity.UNCOMMON, mage.cards.t.TransmogrifyingLicid.class)); - cards.add(new SetCardInfo("Treasure Hunter", 23, Rarity.UNCOMMON, mage.cards.t.TreasureHunter.class)); - cards.add(new SetCardInfo("Treasure Trove", 50, Rarity.UNCOMMON, mage.cards.t.TreasureTrove.class)); - cards.add(new SetCardInfo("Vampire Hounds", 77, Rarity.COMMON, mage.cards.v.VampireHounds.class)); - cards.add(new SetCardInfo("Wall of Nets", 24, Rarity.RARE, mage.cards.w.WallOfNets.class)); - cards.add(new SetCardInfo("Wayward Soul", 51, Rarity.COMMON, mage.cards.w.WaywardSoul.class)); - cards.add(new SetCardInfo("Welkin Hawk", 25, Rarity.COMMON, mage.cards.w.WelkinHawk.class)); - cards.add(new SetCardInfo("Whiptongue Frog", 52, Rarity.COMMON, mage.cards.w.WhiptongueFrog.class)); - cards.add(new SetCardInfo("Wood Elves", 130, Rarity.COMMON, mage.cards.w.WoodElves.class)); - cards.add(new SetCardInfo("Workhorse", 142, Rarity.RARE, mage.cards.w.Workhorse.class)); - cards.add(new SetCardInfo("Zealots en-Dal", 26, Rarity.UNCOMMON, mage.cards.z.ZealotsEnDal.class)); - } -} + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author North + */ +public final class Exodus extends ExpansionSet { + + private static final Exodus instance = new Exodus(); + + public static Exodus getInstance() { + return instance; + } + + private Exodus() { + super("Exodus", "EXO", ExpansionSet.buildDate(1998, 6, 15), SetType.EXPANSION); + this.blockName = "Tempest"; + this.parentSet = Tempest.getInstance(); + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 0; + cards.add(new SetCardInfo("Allay", 1, Rarity.COMMON, mage.cards.a.Allay.class)); + cards.add(new SetCardInfo("Anarchist", 79, Rarity.COMMON, mage.cards.a.Anarchist.class)); + cards.add(new SetCardInfo("Angelic Blessing", 2, Rarity.COMMON, mage.cards.a.AngelicBlessing.class)); + cards.add(new SetCardInfo("Avenging Druid", 105, Rarity.COMMON, mage.cards.a.AvengingDruid.class)); + cards.add(new SetCardInfo("Bequeathal", 106, Rarity.COMMON, mage.cards.b.Bequeathal.class)); + cards.add(new SetCardInfo("Carnophage", 53, Rarity.COMMON, mage.cards.c.Carnophage.class)); + cards.add(new SetCardInfo("Cartographer", 107, Rarity.UNCOMMON, mage.cards.c.Cartographer.class)); + cards.add(new SetCardInfo("Cataclysm", 3, Rarity.RARE, mage.cards.c.Cataclysm.class)); + cards.add(new SetCardInfo("Cat Burglar", 54, Rarity.COMMON, mage.cards.c.CatBurglar.class)); + cards.add(new SetCardInfo("Charging Paladin", 4, Rarity.COMMON, mage.cards.c.ChargingPaladin.class)); + cards.add(new SetCardInfo("Cinder Crawler", 80, Rarity.COMMON, mage.cards.c.CinderCrawler.class)); + cards.add(new SetCardInfo("City of Traitors", 143, Rarity.RARE, mage.cards.c.CityOfTraitors.class)); + cards.add(new SetCardInfo("Coat of Arms", 131, Rarity.RARE, mage.cards.c.CoatOfArms.class)); + cards.add(new SetCardInfo("Convalescence", 5, Rarity.RARE, mage.cards.c.Convalescence.class)); + cards.add(new SetCardInfo("Crashing Boars", 108, Rarity.UNCOMMON, mage.cards.c.CrashingBoars.class)); + cards.add(new SetCardInfo("Culling the Weak", 55, Rarity.COMMON, mage.cards.c.CullingTheWeak.class)); + cards.add(new SetCardInfo("Curiosity", 29, Rarity.UNCOMMON, mage.cards.c.Curiosity.class)); + cards.add(new SetCardInfo("Cursed Flesh", 56, Rarity.COMMON, mage.cards.c.CursedFlesh.class)); + cards.add(new SetCardInfo("Dauthi Cutthroat", 57, Rarity.UNCOMMON, mage.cards.d.DauthiCutthroat.class)); + cards.add(new SetCardInfo("Dauthi Jackal", 58, Rarity.COMMON, mage.cards.d.DauthiJackal.class)); + cards.add(new SetCardInfo("Dauthi Warlord", 59, Rarity.UNCOMMON, mage.cards.d.DauthiWarlord.class)); + cards.add(new SetCardInfo("Death's Duet", 60, Rarity.COMMON, mage.cards.d.DeathsDuet.class)); + cards.add(new SetCardInfo("Dominating Licid", 30, Rarity.RARE, mage.cards.d.DominatingLicid.class)); + cards.add(new SetCardInfo("Elven Palisade", 109, Rarity.UNCOMMON, mage.cards.e.ElvenPalisade.class)); + cards.add(new SetCardInfo("Elvish Berserker", 110, Rarity.COMMON, mage.cards.e.ElvishBerserker.class)); + cards.add(new SetCardInfo("Entropic Specter", 61, Rarity.RARE, mage.cards.e.EntropicSpecter.class)); + cards.add(new SetCardInfo("Ephemeron", 31, Rarity.RARE, mage.cards.e.Ephemeron.class)); + cards.add(new SetCardInfo("Equilibrium", 32, Rarity.RARE, mage.cards.e.Equilibrium.class)); + cards.add(new SetCardInfo("Erratic Portal", 132, Rarity.RARE, mage.cards.e.ErraticPortal.class)); + cards.add(new SetCardInfo("Ertai, Wizard Adept", 33, Rarity.RARE, mage.cards.e.ErtaiWizardAdept.class)); + cards.add(new SetCardInfo("Exalted Dragon", 6, Rarity.RARE, mage.cards.e.ExaltedDragon.class)); + cards.add(new SetCardInfo("Fade Away", 34, Rarity.COMMON, mage.cards.f.FadeAway.class)); + cards.add(new SetCardInfo("Fighting Chance", 82, Rarity.RARE, mage.cards.f.FightingChance.class)); + cards.add(new SetCardInfo("Flowstone Flood", 83, Rarity.UNCOMMON, mage.cards.f.FlowstoneFlood.class)); + cards.add(new SetCardInfo("Forbid", 35, Rarity.UNCOMMON, mage.cards.f.Forbid.class)); + cards.add(new SetCardInfo("Fugue", 62, Rarity.UNCOMMON, mage.cards.f.Fugue.class)); + cards.add(new SetCardInfo("Furnace Brood", 84, Rarity.COMMON, mage.cards.f.FurnaceBrood.class)); + cards.add(new SetCardInfo("Hatred", 64, Rarity.RARE, mage.cards.h.Hatred.class)); + cards.add(new SetCardInfo("High Ground", 7, Rarity.UNCOMMON, mage.cards.h.HighGround.class)); + cards.add(new SetCardInfo("Jackalope Herd", 111, Rarity.COMMON, mage.cards.j.JackalopeHerd.class)); + cards.add(new SetCardInfo("Keeper of the Beasts", 112, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheBeasts.class)); + cards.add(new SetCardInfo("Keeper of the Dead", 65, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheDead.class)); + cards.add(new SetCardInfo("Keeper of the Light", 8, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheLight.class)); + cards.add(new SetCardInfo("Keeper of the Mind", 36, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheMind.class)); + cards.add(new SetCardInfo("Killer Whale", 37, Rarity.UNCOMMON, mage.cards.k.KillerWhale.class)); + cards.add(new SetCardInfo("Kor Chant", 9, Rarity.COMMON, mage.cards.k.KorChant.class)); + cards.add(new SetCardInfo("Mage il-Vec", 86, Rarity.COMMON, mage.cards.m.MageIlVec.class)); + cards.add(new SetCardInfo("Manabond", 113, Rarity.RARE, mage.cards.m.Manabond.class)); + cards.add(new SetCardInfo("Mana Breach", 38, Rarity.UNCOMMON, mage.cards.m.ManaBreach.class)); + cards.add(new SetCardInfo("Maniacal Rage", 87, Rarity.COMMON, mage.cards.m.ManiacalRage.class)); + cards.add(new SetCardInfo("Medicine Bag", 133, Rarity.UNCOMMON, mage.cards.m.MedicineBag.class)); + cards.add(new SetCardInfo("Memory Crystal", 134, Rarity.RARE, mage.cards.m.MemoryCrystal.class)); + cards.add(new SetCardInfo("Merfolk Looter", 39, Rarity.COMMON, mage.cards.m.MerfolkLooter.class)); + cards.add(new SetCardInfo("Mindless Automaton", 135, Rarity.RARE, mage.cards.m.MindlessAutomaton.class)); + cards.add(new SetCardInfo("Mind Over Matter", 40, Rarity.RARE, mage.cards.m.MindOverMatter.class)); + cards.add(new SetCardInfo("Mirozel", 41, Rarity.UNCOMMON, mage.cards.m.Mirozel.class)); + cards.add(new SetCardInfo("Mirri, Cat Warrior", 114, Rarity.RARE, mage.cards.m.MirriCatWarrior.class)); + cards.add(new SetCardInfo("Mogg Assassin", 88, Rarity.UNCOMMON, mage.cards.m.MoggAssassin.class)); + cards.add(new SetCardInfo("Nausea", 67, Rarity.COMMON, mage.cards.n.Nausea.class)); + cards.add(new SetCardInfo("Necrologia", 68, Rarity.UNCOMMON, mage.cards.n.Necrologia.class)); + cards.add(new SetCardInfo("Null Brooch", 136, Rarity.RARE, mage.cards.n.NullBrooch.class)); + cards.add(new SetCardInfo("Oath of Druids", 115, Rarity.RARE, mage.cards.o.OathOfDruids.class)); + cards.add(new SetCardInfo("Oath of Ghouls", 69, Rarity.RARE, mage.cards.o.OathOfGhouls.class)); + cards.add(new SetCardInfo("Oath of Lieges", 11, Rarity.RARE, mage.cards.o.OathOfLieges.class)); + cards.add(new SetCardInfo("Oath of Mages", 90, Rarity.RARE, mage.cards.o.OathOfMages.class)); + cards.add(new SetCardInfo("Oath of Scholars", 42, Rarity.RARE, mage.cards.o.OathOfScholars.class)); + cards.add(new SetCardInfo("Ogre Shaman", 91, Rarity.RARE, mage.cards.o.OgreShaman.class)); + cards.add(new SetCardInfo("Onslaught", 92, Rarity.COMMON, mage.cards.o.Onslaught.class)); + cards.add(new SetCardInfo("Paladin en-Vec", 12, Rarity.RARE, mage.cards.p.PaladinEnVec.class)); + cards.add(new SetCardInfo("Pandemonium", 93, Rarity.RARE, mage.cards.p.Pandemonium.class)); + cards.add(new SetCardInfo("Peace of Mind", 13, Rarity.UNCOMMON, mage.cards.p.PeaceOfMind.class)); + cards.add(new SetCardInfo("Pegasus Stampede", 14, Rarity.UNCOMMON, mage.cards.p.PegasusStampede.class)); + cards.add(new SetCardInfo("Penance", 15, Rarity.UNCOMMON, mage.cards.p.Penance.class)); + cards.add(new SetCardInfo("Pit Spawn", 70, Rarity.RARE, mage.cards.p.PitSpawn.class)); + cards.add(new SetCardInfo("Plaguebearer", 71, Rarity.RARE, mage.cards.p.Plaguebearer.class)); + cards.add(new SetCardInfo("Plated Rootwalla", 116, Rarity.COMMON, mage.cards.p.PlatedRootwalla.class)); + cards.add(new SetCardInfo("Predatory Hunger", 117, Rarity.COMMON, mage.cards.p.PredatoryHunger.class)); + cards.add(new SetCardInfo("Price of Progress", 95, Rarity.UNCOMMON, mage.cards.p.PriceOfProgress.class)); + cards.add(new SetCardInfo("Pygmy Troll", 118, Rarity.COMMON, mage.cards.p.PygmyTroll.class)); + cards.add(new SetCardInfo("Rabid Wolverines", 119, Rarity.COMMON, mage.cards.r.RabidWolverines.class)); + cards.add(new SetCardInfo("Raging Goblin", 96, Rarity.COMMON, mage.cards.r.RagingGoblin.class)); + cards.add(new SetCardInfo("Ravenous Baboons", 97, Rarity.RARE, mage.cards.r.RavenousBaboons.class)); + cards.add(new SetCardInfo("Reaping the Rewards", 16, Rarity.COMMON, mage.cards.r.ReapingTheRewards.class)); + cards.add(new SetCardInfo("Reckless Ogre", 98, Rarity.COMMON, mage.cards.r.RecklessOgre.class)); + cards.add(new SetCardInfo("Reclaim", 120, Rarity.COMMON, mage.cards.r.Reclaim.class)); + cards.add(new SetCardInfo("Reconnaissance", 17, Rarity.UNCOMMON, mage.cards.r.Reconnaissance.class)); + cards.add(new SetCardInfo("Recurring Nightmare", 72, Rarity.RARE, mage.cards.r.RecurringNightmare.class)); + cards.add(new SetCardInfo("Resuscitate", 121, Rarity.UNCOMMON, mage.cards.r.Resuscitate.class)); + cards.add(new SetCardInfo("Robe of Mirrors", 43, Rarity.COMMON, mage.cards.r.RobeOfMirrors.class)); + cards.add(new SetCardInfo("Rootwater Alligator", 122, Rarity.COMMON, mage.cards.r.RootwaterAlligator.class)); + cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); + cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); + cards.add(new SetCardInfo("Scalding Salamander", 100, Rarity.UNCOMMON, mage.cards.s.ScaldingSalamander.class)); + cards.add(new SetCardInfo("Scare Tactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); + cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); + cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); + cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); + cards.add(new SetCardInfo("Shackles", 18, Rarity.COMMON, mage.cards.s.Shackles.class)); + cards.add(new SetCardInfo("Shattering Pulse", 102, Rarity.COMMON, mage.cards.s.ShatteringPulse.class)); + cards.add(new SetCardInfo("Shield Mate", 19, Rarity.COMMON, mage.cards.s.ShieldMate.class)); + cards.add(new SetCardInfo("Skyshaper", 137, Rarity.UNCOMMON, mage.cards.s.Skyshaper.class)); + cards.add(new SetCardInfo("Skyshroud Elite", 123, Rarity.UNCOMMON, mage.cards.s.SkyshroudElite.class)); + cards.add(new SetCardInfo("Skyshroud War Beast", 124, Rarity.RARE, mage.cards.s.SkyshroudWarBeast.class)); + cards.add(new SetCardInfo("Slaughter", 74, Rarity.UNCOMMON, mage.cards.s.Slaughter.class)); + cards.add(new SetCardInfo("Soltari Visionary", 20, Rarity.COMMON, mage.cards.s.SoltariVisionary.class)); + cards.add(new SetCardInfo("Song of Serenity", 125, Rarity.UNCOMMON, mage.cards.s.SongOfSerenity.class)); + cards.add(new SetCardInfo("Sonic Burst", 103, Rarity.COMMON, mage.cards.s.SonicBurst.class)); + cards.add(new SetCardInfo("Soul Warden", 21, Rarity.COMMON, mage.cards.s.SoulWarden.class)); + cards.add(new SetCardInfo("Spellbook", 138, Rarity.UNCOMMON, mage.cards.s.Spellbook.class)); + cards.add(new SetCardInfo("Spellshock", 104, Rarity.UNCOMMON, mage.cards.s.Spellshock.class)); + cards.add(new SetCardInfo("Sphere of Resistance", 139, Rarity.RARE, mage.cards.s.SphereOfResistance.class)); + cards.add(new SetCardInfo("Spike Cannibal", 75, Rarity.UNCOMMON, mage.cards.s.SpikeCannibal.class)); + cards.add(new SetCardInfo("Spike Hatcher", 126, Rarity.RARE, mage.cards.s.SpikeHatcher.class)); + cards.add(new SetCardInfo("Spike Rogue", 127, Rarity.UNCOMMON, mage.cards.s.SpikeRogue.class)); + cards.add(new SetCardInfo("Spike Weaver", 128, Rarity.RARE, mage.cards.s.SpikeWeaver.class)); + cards.add(new SetCardInfo("Standing Troops", 22, Rarity.COMMON, mage.cards.s.StandingTroops.class)); + cards.add(new SetCardInfo("Survival of the Fittest", 129, Rarity.RARE, mage.cards.s.SurvivalOfTheFittest.class)); + cards.add(new SetCardInfo("Thalakos Drifters", 47, Rarity.RARE, mage.cards.t.ThalakosDrifters.class)); + cards.add(new SetCardInfo("Thalakos Scout", 48, Rarity.COMMON, mage.cards.t.ThalakosScout.class)); + cards.add(new SetCardInfo("Theft of Dreams", 49, Rarity.COMMON, mage.cards.t.TheftOfDreams.class)); + cards.add(new SetCardInfo("Thopter Squadron", 140, Rarity.RARE, mage.cards.t.ThopterSquadron.class)); + cards.add(new SetCardInfo("Thrull Surgeon", 76, Rarity.COMMON, mage.cards.t.ThrullSurgeon.class)); + cards.add(new SetCardInfo("Transmogrifying Licid", 141, Rarity.UNCOMMON, mage.cards.t.TransmogrifyingLicid.class)); + cards.add(new SetCardInfo("Treasure Hunter", 23, Rarity.UNCOMMON, mage.cards.t.TreasureHunter.class)); + cards.add(new SetCardInfo("Treasure Trove", 50, Rarity.UNCOMMON, mage.cards.t.TreasureTrove.class)); + cards.add(new SetCardInfo("Vampire Hounds", 77, Rarity.COMMON, mage.cards.v.VampireHounds.class)); + cards.add(new SetCardInfo("Volrath's Dungeon", 78, Rarity.RARE, mage.cards.v.VolrathsDungeon.class)); + cards.add(new SetCardInfo("Wall of Nets", 24, Rarity.RARE, mage.cards.w.WallOfNets.class)); + cards.add(new SetCardInfo("Wayward Soul", 51, Rarity.COMMON, mage.cards.w.WaywardSoul.class)); + cards.add(new SetCardInfo("Welkin Hawk", 25, Rarity.COMMON, mage.cards.w.WelkinHawk.class)); + cards.add(new SetCardInfo("Whiptongue Frog", 52, Rarity.COMMON, mage.cards.w.WhiptongueFrog.class)); + cards.add(new SetCardInfo("Wood Elves", 130, Rarity.COMMON, mage.cards.w.WoodElves.class)); + cards.add(new SetCardInfo("Workhorse", 142, Rarity.RARE, mage.cards.w.Workhorse.class)); + cards.add(new SetCardInfo("Zealots en-Dal", 26, Rarity.UNCOMMON, mage.cards.z.ZealotsEnDal.class)); + } +} diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 21fac77d7aa..8ebc0a44a66 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -1,4 +1,3 @@ - package mage.abilities; import java.util.UUID; @@ -154,13 +153,19 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa @Override public ActivationStatus canActivate(UUID playerId, Game game) { //20091005 - 602.2 - if (!(hasMoreActivationsThisTurn(game) && (condition == null || condition.apply(game, this)))) { + if (!(hasMoreActivationsThisTurn(game) + && (condition == null + || condition.apply(game, this)))) { return ActivationStatus.getFalse(); } switch (mayActivate) { case ANY: break; - + case ACTIVE: + if (game.getActivePlayerId() != playerId) { + return ActivationStatus.getFalse(); + } + break; case NOT_YOU: if (controlsAbility(playerId, game)) { return ActivationStatus.getFalse(); @@ -198,9 +203,17 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return ActivationStatus.getFalse(); } //20091005 - 602.5d/602.5e - MageObjectReference permittingObject = game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.ACTIVATE_AS_INSTANT, this, controllerId, game); - if (timing == TimingRule.INSTANT || game.canPlaySorcery(playerId) || null != permittingObject) { - if (costs.canPay(this, sourceId, playerId, game) && canChooseTarget(game)) { + MageObjectReference permittingObject = game.getContinuousEffects() + .asThough(sourceId, + AsThoughEffectType.ACTIVATE_AS_INSTANT, + this, + controllerId, + game); + if (timing == TimingRule.INSTANT + || game.canPlaySorcery(playerId) + || null != permittingObject) { + if (costs.canPay(this, sourceId, playerId, game) + && canChooseTarget(game)) { this.activatorId = playerId; return new ActivationStatus(true, permittingObject); } @@ -297,8 +310,10 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } protected ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); + Integer turnNum = (Integer) game.getState() + .getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); + Integer activationCount = (Integer) game.getState() + .getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); if (turnNum == null || activationCount == null) { return null; } @@ -306,7 +321,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } protected void setActivationInfo(ActivationInfo activationInfo, Game game) { - game.getState().setValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); - game.getState().setValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game), activationInfo.activationCounter); + game.getState().setValue(CardUtil + .getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); + game.getState().setValue(CardUtil + .getCardZoneString("activationsCount" + originalId, sourceId, game), activationInfo.activationCounter); } } From 88578502ad90b080dbd667c0e752276772dc5aa1 Mon Sep 17 00:00:00 2001 From: Jeff Date: Thu, 6 Dec 2018 09:57:24 -0600 Subject: [PATCH 50/50] - Added Monstrous Hound and Keeper of the Flame. --- .../src/mage/cards/k/KeeperOfTheFlame.java | 79 +++++++++++++++++++ .../src/mage/cards/m/MonstrousHound.java | 63 +++++++++++++++ Mage.Sets/src/mage/sets/Exodus.java | 2 + 3 files changed, 144 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java create mode 100644 Mage.Sets/src/mage/cards/m/MonstrousHound.java diff --git a/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java b/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java new file mode 100644 index 00000000000..9c1bcdd170f --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KeeperOfTheFlame.java @@ -0,0 +1,79 @@ +package mage.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterOpponent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author jeffwadsworth + */ +public final class KeeperOfTheFlame extends CardImpl { + + private static final FilterOpponent filter = new FilterOpponent(); + + static { + filter.add(new KeeperOfTheFlamePredicate()); + } + + public KeeperOfTheFlame(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {R}, {tap}: Choose target opponent who had more life than you did as you activated this ability. Keeper of the Flame deals 2 damage to him or her. + Ability ability = new SimpleActivatedAbility( + new DamageTargetEffect(2).setText("Choose target opponent who had more life than you did as you activated this ability. {this} deals 2 damage to him or her"), + new ManaCostsImpl("{R}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetPlayer(1, 1, false, filter)); + this.addAbility(ability); + + } + + public KeeperOfTheFlame(final KeeperOfTheFlame card) { + super(card); + } + + @Override + public KeeperOfTheFlame copy() { + return new KeeperOfTheFlame(this); + } +} + +class KeeperOfTheFlamePredicate implements ObjectSourcePlayerPredicate> { + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Player targetOpponent = input.getObject(); + Player controller = game.getPlayer(input.getPlayerId()); + if (targetOpponent == null + || controller == null + || !controller.hasOpponent(targetOpponent.getId(), game)) { + return false; + } + return targetOpponent.getLife() > controller.getLife(); + } + + @Override + public String toString() { + return "opponent who had more life than you did as you activated this ability"; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MonstrousHound.java b/Mage.Sets/src/mage/cards/m/MonstrousHound.java new file mode 100644 index 00000000000..5bf9aa0f1f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MonstrousHound.java @@ -0,0 +1,63 @@ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.ControlsPermanentsComparedToOpponentsCondition; +import mage.abilities.decorator.ConditionalRestrictionEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerSourceEffect; +import mage.abilities.effects.common.combat.CantBlockSourceEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; + +/** + * + * @author jeffwadsworth + */ +public final class MonstrousHound extends CardImpl { + + public MonstrousHound(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.HOUND); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Monstrous Hound can't attack unless you control more lands than defending player. + Effect effect = new ConditionalRestrictionEffect( + new CantAttackAnyPlayerSourceEffect(Duration.WhileOnBattlefield), + new ControlsPermanentsComparedToOpponentsCondition( + ComparisonType.FEWER_THAN, + new FilterLandPermanent())); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + effect.setText("{this} can't attack unless you control more lands than defending player"))); + + // Monstrous Hound can't block unless you control more lands than attacking player. + Effect effect2 = new ConditionalRestrictionEffect( + new CantBlockSourceEffect(Duration.WhileOnBattlefield), + new ControlsPermanentsComparedToOpponentsCondition( + ComparisonType.FEWER_THAN, + new FilterLandPermanent())); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, + effect2.setText("{this} can't block unless you control more lands than attacking player"))); + + } + + public MonstrousHound(final MonstrousHound card) { + super(card); + } + + @Override + public MonstrousHound copy() { + return new MonstrousHound(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 04e9a204467..8cdb6742d84 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -70,6 +70,7 @@ public final class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Jackalope Herd", 111, Rarity.COMMON, mage.cards.j.JackalopeHerd.class)); cards.add(new SetCardInfo("Keeper of the Beasts", 112, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheBeasts.class)); cards.add(new SetCardInfo("Keeper of the Dead", 65, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheDead.class)); + cards.add(new SetCardInfo("Keeper of the Flame", 85, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheFlame.class)); cards.add(new SetCardInfo("Keeper of the Light", 8, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheLight.class)); cards.add(new SetCardInfo("Keeper of the Mind", 36, Rarity.UNCOMMON, mage.cards.k.KeeperOfTheMind.class)); cards.add(new SetCardInfo("Killer Whale", 37, Rarity.UNCOMMON, mage.cards.k.KillerWhale.class)); @@ -86,6 +87,7 @@ public final class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Mirozel", 41, Rarity.UNCOMMON, mage.cards.m.Mirozel.class)); cards.add(new SetCardInfo("Mirri, Cat Warrior", 114, Rarity.RARE, mage.cards.m.MirriCatWarrior.class)); cards.add(new SetCardInfo("Mogg Assassin", 88, Rarity.UNCOMMON, mage.cards.m.MoggAssassin.class)); + cards.add(new SetCardInfo("Monstrous Hound", 89, Rarity.RARE, mage.cards.m.MonstrousHound.class)); cards.add(new SetCardInfo("Nausea", 67, Rarity.COMMON, mage.cards.n.Nausea.class)); cards.add(new SetCardInfo("Necrologia", 68, Rarity.UNCOMMON, mage.cards.n.Necrologia.class)); cards.add(new SetCardInfo("Null Brooch", 136, Rarity.RARE, mage.cards.n.NullBrooch.class));