mirror of
https://github.com/correl/mage.git
synced 2024-12-26 03:00:11 +00:00
Merge pull request #81 from magefree/master
Merge https://github.com/magefree/mage
This commit is contained in:
commit
c4545e9ad2
485 changed files with 16638 additions and 7187 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -91,6 +91,7 @@ Mage.Verify/AllCards.json.zip
|
|||
Mage.Verify/AllSets.json.zip
|
||||
Mage.Verify/AllCards.json
|
||||
Mage.Verify/AllSets.json
|
||||
/db
|
||||
|
||||
releases
|
||||
Utils/author.txt
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
XMage.de 1 (Europe/Germany) fast :xmage.de:17171
|
||||
old xmage.de (Europe/Germany) :185.3.232.200:17171
|
||||
XMage Players MTG:xmageplayersmtg.ddns.net:17171
|
||||
XMage.tahiti :xmage.tahiti.one:443
|
||||
Seedds Server (Asia) :115.29.203.80:17171
|
||||
localhost -> connect to your local server (must be started):localhost:17171
|
|
@ -1,5 +1,15 @@
|
|||
package mage.client.cards;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.*;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.MageCard;
|
||||
import mage.cards.decks.DeckCardInfo;
|
||||
|
@ -20,17 +30,6 @@ import mage.view.CardsView;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.mage.card.arcane.CardRenderer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by StravantUser on 2016-09-20.
|
||||
*/
|
||||
|
@ -2032,6 +2031,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
|
||||
private int getCardWidth() {
|
||||
if (GUISizeHelper.editorCardDimension == null) {
|
||||
return 200;
|
||||
}
|
||||
return (int) (GUISizeHelper.editorCardDimension.width * cardSizeMod);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.client.deck.generator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -7,6 +6,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
|
@ -368,7 +368,6 @@ public final class DeckGenerator {
|
|||
private static Card getBasicLand(ColoredManaSymbol color, Map<String, List<CardInfo>> basicLands) {
|
||||
String landName = DeckGeneratorPool.getBasicLandName(color.toString());
|
||||
List<CardInfo> basicLandsInfo = basicLands.get(landName);
|
||||
return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size() - 1)).getMockCard().copy();
|
||||
return basicLandsInfo.get(RandomUtil.nextInt(basicLandsInfo.size())).getMockCard().copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
/*
|
||||
/*
|
||||
* CardSelector.java
|
||||
*
|
||||
* Created on Feb 18, 2010, 2:49:03 PM
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
|
||||
/*
|
||||
/*
|
||||
* DeckEditorPane.java
|
||||
*
|
||||
* Created on Dec 17, 2009, 9:21:42 AM
|
||||
|
@ -105,7 +103,6 @@ public class DeckEditorPane extends MagePane {
|
|||
.addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, 626, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public DeckEditorPanel getPanel() {
|
||||
|
|
|
@ -192,6 +192,15 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAddLandActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnGenDeck">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Generate"/>
|
||||
<Property name="name" type="java.lang.String" value="btnGenDeck" noResource="true"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGenDeckActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnSubmit">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Submit"/>
|
||||
|
@ -210,7 +219,7 @@
|
|||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnSubmitTimerActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="JComponent" name="cardInfoPane">
|
||||
<Component class="org.mage.plugins.card.info.CardInfoPaneImpl" name="cardInfoPane">
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtTimeRemaining">
|
||||
</Component>
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
|
||||
package mage.client.deckeditor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Deck;
|
||||
|
@ -29,18 +37,6 @@ import mage.view.CardView;
|
|||
import mage.view.SimpleCardView;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -55,7 +51,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
private UUID tableId;
|
||||
private DeckEditorMode mode;
|
||||
private int timeout;
|
||||
private Timer countdown;
|
||||
private javax.swing.Timer countdown;
|
||||
private UpdateDeckTask updateDeckTask;
|
||||
private int timeToSubmit = -1;
|
||||
|
||||
|
@ -75,7 +71,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
jPanel1.setOpaque(false);
|
||||
jSplitPane1.setOpaque(false);
|
||||
restoreDividerLocationsAndDeckAreaSettings();
|
||||
countdown = new Timer(1000,
|
||||
countdown = new javax.swing.Timer(1000,
|
||||
e -> {
|
||||
if (--timeout > 0) {
|
||||
setTimeout(timeout);
|
||||
|
@ -456,7 +452,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
CardView cardView = (CardView) event.getSource();
|
||||
int numberToSet = event.getNumber();
|
||||
int cardsFound = 0;
|
||||
List<Card> toDelete = new ArrayList<>();
|
||||
java.util.List<Card> toDelete = new ArrayList<>();
|
||||
for (Card card : cards) {
|
||||
if (card.getName().equals(cardView.getName())
|
||||
&& Objects.equals(card.getCardNumber(), cardView.getCardNumber())
|
||||
|
@ -689,7 +685,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
btnGenDeck.setText("Generate");
|
||||
btnGenDeck.setName("btnGenDeck");
|
||||
btnGenDeck.addActionListener(evt -> btnGenDeckActionPerformed(evt));
|
||||
|
||||
txtTimeRemaining.setEditable(false);
|
||||
txtTimeRemaining.setForeground(java.awt.Color.red);
|
||||
txtTimeRemaining.setHorizontalAlignment(javax.swing.JTextField.CENTER);
|
||||
|
@ -779,9 +774,9 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
.addComponent(jSplitPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE));
|
||||
}
|
||||
|
||||
private void processAndShowImportErrors(StringBuilder errorMessages){
|
||||
private void processAndShowImportErrors(StringBuilder errorMessages) {
|
||||
// show up errors list
|
||||
if (errorMessages.length() > 0){
|
||||
if (errorMessages.length() > 0) {
|
||||
String mes = "Founded problems with deck: \n\n" + errorMessages.toString();
|
||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), mes.substring(0, Math.min(1000, mes.length())), "Errors while loading deck", JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
|
@ -813,7 +808,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
|
||||
} catch (GameException e1) {
|
||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE);
|
||||
}finally {
|
||||
} finally {
|
||||
MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
@ -845,7 +840,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
} catch (GameException e1) {
|
||||
JOptionPane.showMessageDialog(MageFrame.getDesktop(), e1.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE);
|
||||
}finally {
|
||||
} finally {
|
||||
MageFrame.getDesktop().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
|
@ -1063,7 +1058,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
|||
}
|
||||
refreshDeck();
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private mage.client.cards.BigCard bigCard;
|
||||
private javax.swing.JButton btnExit;
|
||||
|
|
|
@ -3,15 +3,28 @@ package mage.client.deckeditor;
|
|||
import mage.util.StreamUtils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.awt.event.*;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class DeckImportFromClipboardDialog extends JDialog {
|
||||
|
||||
private static final String FORMAT_TEXT =
|
||||
"// Example:\n" +
|
||||
"//1 Library of Congress\n" +
|
||||
"//1 Cryptic Gateway\n" +
|
||||
"//1 Azami, Lady of Scrolls\n" +
|
||||
"// NB: This is slow as, and will lock your screen :)\n" +
|
||||
"\n" +
|
||||
"// Your current clipboard:\n";
|
||||
|
||||
private JPanel contentPane;
|
||||
private JButton buttonOK;
|
||||
private JButton buttonCancel;
|
||||
|
@ -21,6 +34,9 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
|||
|
||||
public DeckImportFromClipboardDialog() {
|
||||
initComponents();
|
||||
|
||||
onRefreshClipboard();
|
||||
|
||||
setContentPane(contentPane);
|
||||
setModal(true);
|
||||
getRootPane().setDefaultButton(buttonOK);
|
||||
|
@ -40,6 +56,15 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
|||
contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
}
|
||||
|
||||
private Optional<String> getClipboardStringData() {
|
||||
try {
|
||||
return Optional.of((String)Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor));
|
||||
} catch (HeadlessException | UnsupportedFlavorException | IOException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void onOK() {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
|
@ -60,6 +85,10 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
|||
dispose();
|
||||
}
|
||||
|
||||
private void onRefreshClipboard() {
|
||||
txtDeckList.setText(FORMAT_TEXT + getClipboardStringData().orElse(""));
|
||||
}
|
||||
|
||||
public String getTmpPath() {
|
||||
return tmpPath;
|
||||
}
|
||||
|
@ -143,7 +172,7 @@ public class DeckImportFromClipboardDialog extends JDialog {
|
|||
|
||||
txtDeckList.setMinimumSize(new Dimension(250, 400));
|
||||
txtDeckList.setPreferredSize(new Dimension(550, 400));
|
||||
txtDeckList.setText("// Example:\n//1 Library of Congress\n//1 Cryptic Gateway\n//1 Azami, Lady of Scrolls\n// NB: This is slow as, and will lock your screen :)");
|
||||
txtDeckList.setText(FORMAT_TEXT);
|
||||
JScrollPane txtScrollableDeckList = new JScrollPane(txtDeckList);
|
||||
panel3.add(txtScrollableDeckList, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0,
|
||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
package mage.client.deckeditor.table;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import mage.cards.MageCard;
|
||||
import mage.view.CardView;
|
||||
|
||||
|
@ -94,8 +95,8 @@ public class MageCardComparator implements Comparator<CardView> {
|
|||
break;
|
||||
// Rarity
|
||||
case 6:
|
||||
aCom = a.getRarity().toString();
|
||||
bCom = b.getRarity().toString();
|
||||
aCom = a.getRarity().getSorting();
|
||||
bCom = b.getRarity().getSorting();
|
||||
break;
|
||||
// Set name
|
||||
case 7:
|
||||
|
|
|
@ -340,8 +340,8 @@
|
|||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/flags/us.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="W"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Connect to vaporservermtg.com (USA)"/>
|
||||
<Property name="text" type="java.lang.String" value="P"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Connect to mtg.powersofwar.com (USA)"/>
|
||||
<Property name="actionCommand" type="java.lang.String" value="connectXmageus"/>
|
||||
<Property name="alignmentY" type="float" value="0.0"/>
|
||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||
|
|
|
@ -270,8 +270,8 @@ public class ConnectDialog extends MageDialog {
|
|||
});
|
||||
|
||||
btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
|
||||
btnFind3.setText("W");
|
||||
btnFind3.setToolTipText("Connect to vaporservermtg.com (USA)");
|
||||
btnFind3.setText("P");
|
||||
btnFind3.setToolTipText("Connect to mtg.powersofwar.com (USA)");
|
||||
btnFind3.setActionCommand("connectXmageus");
|
||||
btnFind3.setAlignmentY(0.0F);
|
||||
btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
|
||||
|
@ -688,7 +688,7 @@ public class ConnectDialog extends MageDialog {
|
|||
}//GEN-LAST:event_btnFind2findPublicServerActionPerformed
|
||||
|
||||
private void connectXmageus(java.awt.event.ActionEvent evt) {
|
||||
String serverAddress = "vapormtgserver.com";
|
||||
String serverAddress = "mtg.powersofwar.com";
|
||||
this.txtServer.setText(serverAddress);
|
||||
this.txtPort.setText("17171");
|
||||
// Update userName and password according to the chosen server.
|
||||
|
|
|
@ -24,6 +24,7 @@ import mage.cards.repository.ExpansionRepository;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.table.TournamentPlayerPanel;
|
||||
import mage.client.util.IgnoreList;
|
||||
import mage.client.util.gui.FastSearchUtil;
|
||||
import mage.constants.MatchTimeLimit;
|
||||
import mage.constants.MultiplayerAttackOption;
|
||||
|
@ -595,6 +596,9 @@ public class NewTournamentDialog extends MageDialog {
|
|||
tOptions.getMatchOptions().setLimited(false);
|
||||
}
|
||||
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
|
||||
tOptions.getMatchOptions().setBannedUsers(IgnoreList.ignoreList(serverAddress));
|
||||
|
||||
tOptions.getMatchOptions().setMatchTimeLimit((MatchTimeLimit) this.cbTimeLimit.getSelectedItem());
|
||||
tOptions.getMatchOptions().setSkillLevel((SkillLevel) this.cbSkillLevel.getSelectedItem());
|
||||
tOptions.getMatchOptions().setWinsNeeded((Integer) this.spnNumWins.getValue());
|
||||
|
|
|
@ -26,6 +26,8 @@ import mage.view.CardView;
|
|||
import mage.view.PermanentView;
|
||||
import net.xeoh.plugins.base.PluginManager;
|
||||
import net.xeoh.plugins.base.impl.PluginManagerFactory;
|
||||
import net.xeoh.plugins.base.util.uri.ClassURI;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.plugins.card.CardPluginImpl;
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
@ -46,13 +48,15 @@ public enum Plugins implements MagePlugins {
|
|||
|
||||
@Override
|
||||
public void loadPlugins() {
|
||||
|
||||
LOGGER.info("Loading plugins...");
|
||||
pm = PluginManagerFactory.createPluginManager();
|
||||
pm.addPluginsFrom(new File(PLUGINS_DIRECTORY + File.separator).toURI());
|
||||
this.cardPlugin = new CardPluginImpl();
|
||||
pm.addPluginsFrom(new ClassURI(CardPluginImpl.class).toURI());
|
||||
pm.addPluginsFrom(new ClassURI(ThemePluginImpl.class).toURI());
|
||||
|
||||
this.cardPlugin = pm.getPlugin(CardPlugin.class);
|
||||
this.counterPlugin = pm.getPlugin(CounterPlugin.class);
|
||||
this.themePlugin = new ThemePluginImpl();
|
||||
this.themePlugin = pm.getPlugin(ThemePlugin.class);
|
||||
LOGGER.info("Done.");
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
case GAME_CHOOSE_ABILITY: {
|
||||
GamePanel panel = MageFrame.getGame(callback.getObjectId());
|
||||
if (panel != null) {
|
||||
appendJsonEvent("GAME_CHOOSE_PILE", callback.getObjectId(), callback.getData());
|
||||
appendJsonEvent("GAME_CHOOSE_ABILITY", callback.getObjectId(), callback.getData());
|
||||
panel.pickAbility((AbilityPickerView) callback.getData());
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,66 +1,58 @@
|
|||
|
||||
|
||||
/*
|
||||
* TablesPanel.java
|
||||
*
|
||||
* Created on 15-Dec-2009, 10:54:01 PM
|
||||
*/
|
||||
package mage.client.table;
|
||||
package mage.client.table;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import mage.cards.decks.importer.DeckImporterUtil;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.chat.ChatPanelBasic;
|
||||
import mage.client.components.MageComponents;
|
||||
import mage.client.dialog.*;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_ORDER;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_COLUMNS_WIDTH;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_FILTER_SETTINGS;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_1;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_2;
|
||||
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_3;
|
||||
import mage.client.util.ButtonColumn;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import mage.client.util.IgnoreList;
|
||||
import mage.client.util.MageTableRowSorter;
|
||||
import mage.client.util.URLHandler;
|
||||
import mage.client.util.gui.GuiDisplayUtil;
|
||||
import mage.client.util.gui.TableUtil;
|
||||
import mage.constants.*;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.players.PlayerType;
|
||||
import mage.remote.MageRemoteException;
|
||||
import mage.view.MatchView;
|
||||
import mage.view.RoomUsersView;
|
||||
import mage.view.TableView;
|
||||
import mage.view.UserRequestMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.ocpsoft.prettytime.Duration;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import org.ocpsoft.prettytime.units.JustNow;
|
||||
import mage.cards.decks.importer.DeckImporterUtil;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.SessionHandler;
|
||||
import mage.client.chat.ChatPanelBasic;
|
||||
import mage.client.components.MageComponents;
|
||||
import mage.client.dialog.*;
|
||||
import mage.client.util.*;
|
||||
import mage.client.util.gui.GuiDisplayUtil;
|
||||
import mage.client.util.gui.TableUtil;
|
||||
import mage.constants.*;
|
||||
import mage.game.match.MatchOptions;
|
||||
import mage.players.PlayerType;
|
||||
import mage.remote.MageRemoteException;
|
||||
import mage.view.MatchView;
|
||||
import mage.view.RoomUsersView;
|
||||
import mage.view.TableView;
|
||||
import mage.view.UserRequestMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.mage.card.arcane.CardRendererUtils;
|
||||
import org.ocpsoft.prettytime.Duration;
|
||||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import org.ocpsoft.prettytime.units.JustNow;
|
||||
|
||||
/**
|
||||
*
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.io.File;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static mage.client.dialog.PreferencesDialog.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TablesPanel extends javax.swing.JPanel {
|
||||
public class TablesPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TablesPanel.class);
|
||||
private static final int[] DEFAULT_COLUMNS_WIDTH = {35, 150, 120, 180, 80, 120, 80, 60, 40, 40, 60};
|
||||
|
@ -134,6 +126,41 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
}
|
||||
};
|
||||
|
||||
// skill renderer
|
||||
TableCellRenderer skillCellRenderer = new DefaultTableCellRenderer() {
|
||||
|
||||
// base panel to render
|
||||
private JPanel renderPanel = new JPanel();
|
||||
private ImageIcon skillIcon = new ImageIcon(this.getClass().getResource("/info/yellow_star_16.png"));
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
|
||||
// get table text cell settings
|
||||
DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class);
|
||||
JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
String skillCode = baseComp.getText();
|
||||
|
||||
// apply settings to render panel from parent
|
||||
renderPanel.setOpaque(baseComp.isOpaque());
|
||||
renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground()));
|
||||
renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground()));
|
||||
renderPanel.setBorder(baseComp.getBorder());
|
||||
|
||||
// create each skill symbol as child label
|
||||
renderPanel.removeAll();
|
||||
renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS));
|
||||
for (char skillSymbol : skillCode.toCharArray()) {
|
||||
JLabel symbolLabel = new JLabel();
|
||||
symbolLabel.setBorder(new EmptyBorder(0, 3, 0, 0));
|
||||
symbolLabel.setIcon(skillIcon);
|
||||
renderPanel.add(symbolLabel);
|
||||
}
|
||||
|
||||
return renderPanel;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates new form TablesPanel
|
||||
*/
|
||||
|
@ -158,6 +185,9 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
|
||||
// time ago
|
||||
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_CREATED).setCellRenderer(timeAgoCellRenderer);
|
||||
// skill level
|
||||
tableTables.getColumnModel().getColumn(TableTableModel.COLUMN_SKILL).setCellRenderer(skillCellRenderer);
|
||||
|
||||
/* date sorter (not need, default is good - see getColumnClass)
|
||||
activeTablesSorter.setComparator(TableTableModel.COLUMN_CREATED, new Comparator<Date>() {
|
||||
@Override
|
||||
|
@ -326,9 +356,14 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
table.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
int row = table.rowAtPoint(e.getPoint());
|
||||
if (e.getClickCount() == 2 && row != -1) {
|
||||
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row));
|
||||
if (e.getClickCount() == 2) {
|
||||
int selRow = table.getSelectedRow();
|
||||
if (selRow != -1) {
|
||||
int dataRow = table.convertRowIndexToModel(selRow);
|
||||
if (dataRow != -1) {
|
||||
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + dataRow));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -620,15 +655,16 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
formatFilterList.add(RowFilter.regexFilter("^Momir Basic|^Constructed - Pauper|^Constructed - Frontier|^Constructed - Extended|^Constructed - Eternal|^Constructed - Historical|^Constructed - Super|^Constructed - Freeform|^Australian Highlander|^Canadian Highlander|^Constructed - Old", TableTableModel.COLUMN_DECK_TYPE));
|
||||
}
|
||||
|
||||
// skill
|
||||
java.util.List<RowFilter<Object, Object>> skillFilterList = new ArrayList<>();
|
||||
if (btnSkillBeginner.isSelected()) {
|
||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.BEGINNER.toString(), TableTableModel.COLUMN_SKILL));
|
||||
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.BEGINNER, true), TableTableModel.COLUMN_SKILL));
|
||||
}
|
||||
if (btnSkillCasual.isSelected()) {
|
||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.CASUAL.toString(), TableTableModel.COLUMN_SKILL));
|
||||
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.CASUAL, true), TableTableModel.COLUMN_SKILL));
|
||||
}
|
||||
if (btnSkillSerious.isSelected()) {
|
||||
skillFilterList.add(RowFilter.regexFilter(SkillLevel.SERIOUS.toString(), TableTableModel.COLUMN_SKILL));
|
||||
skillFilterList.add(RowFilter.regexFilter(this.tableModel.getSkillLevelAsCode(SkillLevel.SERIOUS, true), TableTableModel.COLUMN_SKILL));
|
||||
}
|
||||
|
||||
String ratedMark = TableTableModel.RATED_VALUE_YES;
|
||||
|
@ -1198,7 +1234,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
|
||||
private void btnNewTournamentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTournamentActionPerformed
|
||||
newTournamentDialog.showDialog(roomId);
|
||||
}//GEN-LAST:event_btnNewTournamentActionPerformed
|
||||
}//GEN-LAST:event_btnNewTournamentActionPerformed
|
||||
|
||||
private void btnQuickStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartActionPerformed
|
||||
TableView table;
|
||||
|
@ -1231,7 +1267,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
} catch (HeadlessException ex) {
|
||||
handleError(ex);
|
||||
}
|
||||
}//GEN-LAST:event_btnQuickStartActionPerformed
|
||||
}//GEN-LAST:event_btnQuickStartActionPerformed
|
||||
|
||||
private void btnNewTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewTableActionPerformed
|
||||
newTableDialog.showDialog(roomId);
|
||||
|
@ -1317,9 +1353,9 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
private javax.swing.JTable tableTables;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class TableTableModel extends AbstractTableModel {
|
||||
class TableTableModel extends AbstractTableModel {
|
||||
|
||||
final ImageIcon tourneyIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/tourney_icon.png"));
|
||||
final ImageIcon matchIcon = new javax.swing.ImageIcon(getClass().getResource("/tables/match_icon.png"));
|
||||
|
@ -1354,6 +1390,31 @@ class TableTableModel extends AbstractTableModel {
|
|||
this.fireTableDataChanged();
|
||||
}
|
||||
|
||||
public String getSkillLevelAsCode(SkillLevel skill, boolean asRegExp) {
|
||||
String res;
|
||||
switch (skill) {
|
||||
case BEGINNER:
|
||||
res = "*";
|
||||
break;
|
||||
case CASUAL:
|
||||
res = "**";
|
||||
break;
|
||||
case SERIOUS:
|
||||
res = "***";
|
||||
break;
|
||||
default:
|
||||
res = "";
|
||||
break;
|
||||
}
|
||||
|
||||
// regexp format for search table rows
|
||||
if (asRegExp) {
|
||||
res = String.format("^%s$", res.replace("*", "\\*"));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return tables.length;
|
||||
|
@ -1384,7 +1445,7 @@ class TableTableModel extends AbstractTableModel {
|
|||
case 7:
|
||||
return tables[arg0].getCreateTime(); // use cell render, not format here
|
||||
case 8:
|
||||
return tables[arg0].getSkillLevel();
|
||||
return this.getSkillLevelAsCode(tables[arg0].getSkillLevel(), false);
|
||||
case 9:
|
||||
return tables[arg0].isRated() ? RATED_VALUE_YES : RATED_VALUE_NO;
|
||||
case 10:
|
||||
|
@ -1462,9 +1523,9 @@ class TableTableModel extends AbstractTableModel {
|
|||
return columnIndex == ACTION_COLUMN;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
|
||||
class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
|
||||
|
||||
private final UUID roomId;
|
||||
private final TablesPanel panel;
|
||||
|
@ -1511,9 +1572,9 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
|
||||
class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
|
||||
|
||||
private final UUID roomId;
|
||||
private final PlayersChatPanel chat;
|
||||
|
@ -1550,9 +1611,9 @@ class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class MatchesTableModel extends AbstractTableModel {
|
||||
class MatchesTableModel extends AbstractTableModel {
|
||||
|
||||
private final String[] columnNames = new String[]{"Deck Type", "Players", "Game Type", "Rating", "Result", "Duration", "Start Time", "End Time", "Action"};
|
||||
public static final int COLUMN_DURATION = 5;
|
||||
|
@ -1663,9 +1724,9 @@ class MatchesTableModel extends AbstractTableModel {
|
|||
return columnIndex == COLUMN_ACTION;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
|
||||
class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
|
||||
|
||||
private final UUID roomId;
|
||||
private final TablesPanel panel;
|
||||
|
@ -1704,9 +1765,9 @@ class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class GameChooser extends JPopupMenu {
|
||||
class GameChooser extends JPopupMenu {
|
||||
|
||||
public void init() {
|
||||
|
||||
|
@ -1741,4 +1802,4 @@ class GameChooser extends JPopupMenu {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.client.util;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -33,11 +32,13 @@ public final class Config {
|
|||
|
||||
static {
|
||||
Properties p = new Properties();
|
||||
try(FileInputStream fis =new FileInputStream(new File("config/config.properties"))) {
|
||||
boolean fileFound = true;
|
||||
try (FileInputStream fis = new FileInputStream(new File("config/config.properties"))) {
|
||||
p.load(fis);
|
||||
} catch (IOException ex) {
|
||||
logger.fatal("Config error ", ex);
|
||||
fileFound = false;
|
||||
}
|
||||
if (fileFound) {
|
||||
serverName = p.getProperty("server-name");
|
||||
port = Integer.parseInt(p.getProperty("port"));
|
||||
remoteServer = p.getProperty("remote-server");
|
||||
|
@ -51,20 +52,21 @@ public final class Config {
|
|||
|
||||
dimensions = new CardDimensions(cardScalingFactor);
|
||||
dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged);
|
||||
// activate instead this part, to run the UI editor for some panels without error
|
||||
// serverName = "localhost";
|
||||
// port = 17171;
|
||||
// remoteServer = "mage-server";
|
||||
// cardScalingFactor = 0.4;
|
||||
// cardScalingFactorEnlarged = 0.5;
|
||||
// handScalingFactor = 1.3;
|
||||
// defaultGameType = p.getProperty("default-game-type", "Human");
|
||||
// defaultDeckPath = "";
|
||||
// defaultOtherPlayerIndex = "1";
|
||||
// defaultComputerName = "Computer";
|
||||
//
|
||||
// dimensions = new CardDimensions(cardScalingFactor);
|
||||
// dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged);
|
||||
} else { // Take some default valies for netbeans design view
|
||||
serverName = "localhost";
|
||||
port = 17171;
|
||||
remoteServer = "mage-server";
|
||||
cardScalingFactor = 0.4;
|
||||
cardScalingFactorEnlarged = 0.5;
|
||||
handScalingFactor = 1.3;
|
||||
defaultGameType = p.getProperty("default-game-type", "Human");
|
||||
defaultDeckPath = "";
|
||||
defaultOtherPlayerIndex = "1";
|
||||
defaultComputerName = "AI Computer";
|
||||
|
||||
dimensions = new CardDimensions(cardScalingFactor);
|
||||
dimensionsEnlarged = new CardDimensions(cardScalingFactorEnlarged);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import mage.view.ChatMessage;
|
|||
|
||||
public final class IgnoreList {
|
||||
|
||||
private static final String USAGE = "<br/><font color=yellow>\\ignore - shows current ignore list on this server."
|
||||
+ "<br/>\\ignore [username] - add a username to your ignore list on this server."
|
||||
private static final String USAGE = "<br/><font color=yellow>\\ignore - shows your ignore list on this server."
|
||||
+ "<br/>\\ignore [username] - add username to ignore list (they won't be able to chat or join to your game)."
|
||||
+ "<br/>\\unignore [username] - remove a username from your ignore list on this server.</font>";
|
||||
|
||||
public static final int MAX_IGNORE_LIST_SIZE = 50;
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Map;
|
|||
import mage.cards.repository.ExpansionInfo;
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
import mage.constants.SetType;
|
||||
import static mage.constants.SetType.EXPANSION;
|
||||
import static mage.constants.SetType.SUPPLEMENTAL;
|
||||
import mage.deck.Standard;
|
||||
|
||||
/**
|
||||
|
@ -64,6 +66,13 @@ public final class ConstructedFormats {
|
|||
underlyingSetCodesPerFormat.put(CUSTOM, new ArrayList<>());
|
||||
final Map<String, ExpansionInfo> expansionInfo = new HashMap<>();
|
||||
formats.clear(); // prevent NPE on sorting if this is not the first try
|
||||
|
||||
// Because this is also called in Netbeans Design view, but the object does not exist in that case,
|
||||
// we have to return here to prevent exception in design view. (Does not hurt at design time)
|
||||
if (!ExpansionRepository.instance.instanceInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ExpansionInfo set : ExpansionRepository.instance.getAll()) {
|
||||
expansionInfo.put(set.getName(), set);
|
||||
formats.add(set.getName());
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
/*
|
||||
* 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 org.mage.card.arcane;
|
||||
|
||||
import java.awt.*;
|
||||
|
@ -74,9 +69,9 @@ public final class CardRendererUtils {
|
|||
int b = c.getBlue();
|
||||
int alpha = c.getAlpha();
|
||||
|
||||
int plus_r = (int) (Math.min (255 - r, r) / 2);
|
||||
int plus_g = (int) (Math.min (255 - g, g) / 2);
|
||||
int plus_b = (int) (Math.min (255 - b, b) / 2);
|
||||
int plus_r = (int) (Math.min(255 - r, r) / 2);
|
||||
int plus_g = (int) (Math.min(255 - g, g) / 2);
|
||||
int plus_b = (int) (Math.min(255 - b, b) / 2);
|
||||
|
||||
return new Color(r - plus_r,
|
||||
g - plus_g,
|
||||
|
@ -192,4 +187,12 @@ public final class CardRendererUtils {
|
|||
.replaceAll("<i>", "")
|
||||
.replaceAll("</i>", "");
|
||||
}
|
||||
|
||||
public static Color copyColor(Color color) {
|
||||
if (color != null) {
|
||||
return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,13 @@ import java.awt.*;
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
// base panel to render
|
||||
private JPanel manaPanel = new JPanel();
|
||||
private JPanel renderPanel = new JPanel();
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
|
||||
|
@ -20,47 +23,47 @@ public final class ManaSymbolsCellRenderer extends DefaultTableCellRenderer {
|
|||
|
||||
// get table text cell settings
|
||||
DefaultTableCellRenderer baseRenderer = (DefaultTableCellRenderer) table.getDefaultRenderer(String.class);
|
||||
JLabel baseLabel = (JLabel)baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
JLabel baseComp = (JLabel) baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
// apply settings to mana panel from parent
|
||||
manaPanel.setOpaque(baseLabel.isOpaque());
|
||||
manaPanel.setForeground(baseLabel.getForeground());
|
||||
manaPanel.setBackground(baseLabel.getBackground());
|
||||
renderPanel.setOpaque(baseComp.isOpaque());
|
||||
renderPanel.setForeground(CardRendererUtils.copyColor(baseComp.getForeground()));
|
||||
renderPanel.setBackground(CardRendererUtils.copyColor(baseComp.getBackground()));
|
||||
renderPanel.setBorder(baseComp.getBorder());
|
||||
|
||||
// icons size with margin
|
||||
int symbolWidth = GUISizeHelper.symbolTableSize;
|
||||
int symbolHorizontalMargin = 2;
|
||||
|
||||
// create each mana symbol as child label
|
||||
String manaCost = (String)value;
|
||||
manaPanel.removeAll();
|
||||
manaPanel.setLayout(new BoxLayout(manaPanel, BoxLayout.X_AXIS));
|
||||
if(manaCost != null){
|
||||
String manaCost = (String) value;
|
||||
renderPanel.removeAll();
|
||||
renderPanel.setLayout(new BoxLayout(renderPanel, BoxLayout.X_AXIS));
|
||||
if (manaCost != null) {
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String symbol = tok.nextToken();
|
||||
|
||||
JLabel symbolLabel = new JLabel();
|
||||
//symbolLabel.setBorder(new LineBorder(new Color(150, 150, 150))); // debug
|
||||
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin,0, 0));
|
||||
symbolLabel.setBorder(new EmptyBorder(0, symbolHorizontalMargin, 0, 0));
|
||||
|
||||
BufferedImage image = ManaSymbols.getSizedManaSymbol(symbol, symbolWidth);
|
||||
if (image != null){
|
||||
if (image != null) {
|
||||
// icon
|
||||
symbolLabel.setIcon(new ImageIcon(image));
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
// text
|
||||
symbolLabel.setText("{" + symbol + "}");
|
||||
symbolLabel.setOpaque(baseLabel.isOpaque());
|
||||
symbolLabel.setForeground(baseLabel.getForeground());
|
||||
symbolLabel.setBackground(baseLabel.getBackground());
|
||||
symbolLabel.setOpaque(baseComp.isOpaque());
|
||||
symbolLabel.setForeground(baseComp.getForeground());
|
||||
symbolLabel.setBackground(baseComp.getBackground());
|
||||
}
|
||||
|
||||
manaPanel.add(symbolLabel);
|
||||
renderPanel.add(symbolLabel);
|
||||
}
|
||||
}
|
||||
|
||||
return manaPanel;
|
||||
return renderPanel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
package org.mage.plugins.card.dl.sources;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Quercitron, JayDi85
|
||||
*/
|
||||
|
@ -234,9 +230,16 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
supportedSets.add("M19");
|
||||
supportedSets.add("GS1");
|
||||
supportedSets.add("GRN");
|
||||
supportedSets.add("GK1");
|
||||
supportedSets.add("GNT");
|
||||
supportedSets.add("UMA");
|
||||
supportedSets.add("PUMA");
|
||||
//
|
||||
supportedSets.add("EURO");
|
||||
supportedSets.add("GPX");
|
||||
supportedSets.add("ATH");
|
||||
supportedSets.add("GRC");
|
||||
supportedSets.add("ANA");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,26 +250,44 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode);
|
||||
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
|
||||
|
||||
// TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2)
|
||||
// WARNING, some cards haven't direct images and uses random GUID:
|
||||
// As example: Raging Ravine - https://scryfall.com/card/uma/249/raging-ravine
|
||||
// https://img.scryfall.com/cards/large/front/5/4/54f41726-e0bb-4154-a2db-4b68b50f5032.jpg
|
||||
String baseUrl = null;
|
||||
String alternativeUrl = null;
|
||||
|
||||
// direct links to images (non localization)
|
||||
if (baseUrl == null) {
|
||||
String linkCode = card.getSet() + "/" + card.getName();
|
||||
if (directDownloadLinks.containsKey(linkCode)) {
|
||||
baseUrl = directDownloadLinks.get(linkCode);
|
||||
|
||||
// set/card/number
|
||||
String linkCode1 = card.getSet() + "/" + card.getName() + "/" + card.getCollectorId();
|
||||
if (directDownloadLinks.containsKey(linkCode1)) {
|
||||
baseUrl = directDownloadLinks.get(linkCode1);
|
||||
alternativeUrl = null;
|
||||
}
|
||||
|
||||
// set/card
|
||||
String linkCode2 = card.getSet() + "/" + card.getName();
|
||||
if (directDownloadLinks.containsKey(linkCode2)) {
|
||||
baseUrl = directDownloadLinks.get(linkCode2);
|
||||
alternativeUrl = null;
|
||||
}
|
||||
}
|
||||
|
||||
// special card number like "103a" already compatible
|
||||
// special card number like "103a" and "U123" already compatible
|
||||
if (baseUrl == null && card.isCollectorIdWithStr()) {
|
||||
// WARNING, after 2018 it's not compatible and some new sets have GUID files instead card numbers
|
||||
// TODO: replace card number links to API calls (need test with lands, alternative images and double faces), replace not working images by direct links
|
||||
if (card.getCollectorId().startsWith("U")) {
|
||||
// fix for Ultimate Box Topper (PUMA) -- need to use API
|
||||
// ignored and go to API call at the end
|
||||
} else {
|
||||
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + ".jpg";
|
||||
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
|
||||
+ card.getCollectorId() + ".jpg";
|
||||
}
|
||||
}
|
||||
|
||||
// double faced cards do not supports by API (need direct link for img)
|
||||
// example: https://img.scryfall.com/cards/large/en/xln/173b.jpg
|
||||
|
@ -376,6 +397,74 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
put("DPAP/Soul of Ravnica", "https://img.scryfall.com/cards/large/en/pdp14/1.jpg");
|
||||
put("DPAP/Soul of Zendikar", "https://img.scryfall.com/cards/large/en/pdp14/2.jpg");
|
||||
|
||||
// Gateway Promos -- xmage uses one set (GRC), but scryfall store it by years
|
||||
// 2006 - https://scryfall.com/sets/pgtw
|
||||
put("GRC/Fiery Temper", "https://img.scryfall.com/cards/large/en/pgtw/3.jpg");
|
||||
put("GRC/Icatian Javelineers", "https://img.scryfall.com/cards/large/en/pgtw/2.jpg");
|
||||
put("GRC/Wood Elves", "https://img.scryfall.com/cards/large/en/pgtw/1.jpg");
|
||||
// 2007 - https://scryfall.com/sets/pg07
|
||||
put("GRC/Boomerang", "https://img.scryfall.com/cards/large/en/pg07/4.jpg");
|
||||
put("GRC/Calciderm", "https://img.scryfall.com/cards/large/en/pg07/5.jpg");
|
||||
put("GRC/Dauntless Dourbark", "https://img.scryfall.com/cards/large/en/pg07/12.jpg");
|
||||
put("GRC/Llanowar Elves", "https://img.scryfall.com/cards/large/en/pg07/9.jpg");
|
||||
put("GRC/Mind Stone", "https://img.scryfall.com/cards/large/en/pg07/11.jpg");
|
||||
put("GRC/Mogg Fanatic", "https://img.scryfall.com/cards/large/en/pg07/10.jpg");
|
||||
put("GRC/Reckless Wurm", "https://img.scryfall.com/cards/large/en/pg07/6.jpg");
|
||||
put("GRC/Yixlid Jailer", "https://img.scryfall.com/cards/large/en/pg07/7.jpg");
|
||||
put("GRC/Zoetic Cavern", "https://img.scryfall.com/cards/large/en/pg07/8.jpg");
|
||||
// 2008a - https://scryfall.com/sets/pg08
|
||||
put("GRC/Boggart Ram-Gang", "https://img.scryfall.com/cards/large/en/pg08/17.jpg");
|
||||
put("GRC/Cenn's Tactician", "https://img.scryfall.com/cards/large/en/pg08/14.jpg");
|
||||
put("GRC/Duergar Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/19.jpg");
|
||||
put("GRC/Gravedigger", "https://img.scryfall.com/cards/large/en/pg08/16.jpg");
|
||||
put("GRC/Lava Axe", "https://img.scryfall.com/cards/large/en/pg08/13.jpg");
|
||||
put("GRC/Oona's Blackguard", "https://img.scryfall.com/cards/large/en/pg08/15.jpg");
|
||||
put("GRC/Selkie Hedge-Mage", "https://img.scryfall.com/cards/large/en/pg08/20.jpg");
|
||||
put("GRC/Wilt-Leaf Cavaliers", "https://img.scryfall.com/cards/large/en/pg08/18.jpg");
|
||||
|
||||
// Wizards Play Network Promos -- xmage uses one set (GRC), but scryfall store it by years
|
||||
// 2008b - https://scryfall.com/sets/pwpn
|
||||
put("GRC/Sprouting Thrinax", "https://img.scryfall.com/cards/large/en/pwpn/21.jpg");
|
||||
put("GRC/Woolly Thoctar", "https://img.scryfall.com/cards/large/en/pwpn/22.jpg");
|
||||
// 2009 - https://scryfall.com/sets/pwp09
|
||||
put("GRC/Hellspark Elemental", "https://img.scryfall.com/cards/large/en/pwp09/25.jpg");
|
||||
put("GRC/Kor Duelist", "https://img.scryfall.com/cards/large/en/pwp09/32.jpg");
|
||||
put("GRC/Marisi's Twinclaws", "https://img.scryfall.com/cards/large/en/pwp09/26.jpg");
|
||||
put("GRC/Mind Control", "https://img.scryfall.com/cards/large/en/pwp09/30.jpg");
|
||||
put("GRC/Path to Exile", "https://img.scryfall.com/cards/large/en/pwp09/24.jpg");
|
||||
put("GRC/Rise from the Grave", "https://img.scryfall.com/cards/large/en/pwp09/31.jpg");
|
||||
put("GRC/Slave of Bolas", "https://img.scryfall.com/cards/large/en/pwp09/27.jpg");
|
||||
put("GRC/Vampire Nighthawk", "https://img.scryfall.com/cards/large/en/pwp09/33.jpg");
|
||||
// 2010 - https://scryfall.com/sets/pwp10
|
||||
put("GRC/Kor Firewalker", "https://img.scryfall.com/cards/large/en/pwp10/36.jpg");
|
||||
put("GRC/Leatherback Baloth", "https://img.scryfall.com/cards/large/en/pwp10/37.jpg");
|
||||
put("GRC/Syphon Mind", "https://img.scryfall.com/cards/large/en/pwp10/40.jpg");
|
||||
put("GRC/Pathrazer of Ulamog", "https://img.scryfall.com/cards/large/en/pwp10/46.jpg");
|
||||
put("GRC/Curse of Wizardry", "https://img.scryfall.com/cards/large/en/pwp10/47.jpg");
|
||||
put("GRC/Fling/50", "https://img.scryfall.com/cards/large/en/pwp10/50.jpg"); // same card but different year
|
||||
put("GRC/Sylvan Ranger/51", "https://img.scryfall.com/cards/large/en/pwp10/51.jpg"); // same card but different year
|
||||
put("GRC/Plague Stinger", "https://img.scryfall.com/cards/large/en/pwp10/59.jpg");
|
||||
put("GRC/Golem's Heart", "https://img.scryfall.com/cards/large/en/pwp10/60.jpg");
|
||||
put("GRC/Skinrender", "https://img.scryfall.com/cards/large/en/pwp10/63.jpg");
|
||||
// 2011 - https://scryfall.com/sets/pwp11
|
||||
put("GRC/Auramancer", "https://img.scryfall.com/cards/large/en/pwp11/77.jpg");
|
||||
put("GRC/Bloodcrazed Neonate", "https://img.scryfall.com/cards/large/en/pwp11/83.jpg");
|
||||
put("GRC/Boneyard Wurm", "https://img.scryfall.com/cards/large/en/pwp11/84.jpg");
|
||||
put("GRC/Circle of Flame", "https://img.scryfall.com/cards/large/en/pwp11/78.jpg");
|
||||
put("GRC/Curse of the Bloody Tome", "https://img.scryfall.com/cards/large/en/pwp11/80.jpg");
|
||||
put("GRC/Fling/69", "https://img.scryfall.com/cards/large/en/pwp11/69.jpg"); // same card but different year
|
||||
put("GRC/Master's Call", "https://img.scryfall.com/cards/large/en/pwp11/64.jpg");
|
||||
put("GRC/Maul Splicer", "https://img.scryfall.com/cards/large/en/pwp11/72.jpg");
|
||||
put("GRC/Plague Myr", "https://img.scryfall.com/cards/large/en/pwp11/65.jpg");
|
||||
put("GRC/Shrine of Burning Rage", "https://img.scryfall.com/cards/large/en/pwp11/73.jpg");
|
||||
put("GRC/Signal Pest", "https://img.scryfall.com/cards/large/en/pwp11/66.jpg");
|
||||
put("GRC/Sylvan Ranger/70", "https://img.scryfall.com/cards/large/en/pwp11/70.jpg"); // same card but different year
|
||||
put("GRC/Tormented Soul", "https://img.scryfall.com/cards/large/en/pwp11/76.jpg");
|
||||
put("GRC/Vault Skirge", "https://img.scryfall.com/cards/large/en/pwp11/71.jpg");
|
||||
// 2012 - https://scryfall.com/sets/pwp12
|
||||
put("GRC/Curse of Thirst", "https://img.scryfall.com/cards/large/en/pwp12/81.jpg");
|
||||
put("GRC/Gather the Townsfolk", "https://img.scryfall.com/cards/large/en/pwp12/79.jpg");
|
||||
put("GRC/Nearheath Stalker", "https://img.scryfall.com/cards/large/en/pwp12/82.jpg");
|
||||
|
||||
// TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg )
|
||||
put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg");
|
||||
|
|
|
@ -409,6 +409,7 @@ public final class ImageCache {
|
|||
// legitimate, happens when a card has no image
|
||||
return null;
|
||||
} catch (ComputationException ex) {
|
||||
// too low memory
|
||||
if (ex.getCause() instanceof NullPointerException) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,8 @@
|
|||
|Generate|PLANE:PCA|Plane - Truga Jungle|||TrugaJunglePlane|
|
||||
|Generate|PLANE:PCA|Plane - Turri Island|||TurriIslandPlane|
|
||||
|Generate|PLANE:PCA|Plane - Undercity Reaches|||UndercityReachesPlane|
|
||||
|Generate|TOK:ANA|Goblin|||GoblinToken|
|
||||
|Generate|TOK:ANA|Spirit|||SpiritWhiteToken|
|
||||
|Generate|TOK:PCA|Eldrazi|||EldraziAnnihilatorToken|
|
||||
|Generate|TOK:10E|Ape|||PongifyApeToken|
|
||||
|Generate|TOK:10E|Dragon|||DragonToken2|
|
||||
|
|
BIN
Mage.Client/src/main/resources/info/yellow_star_16.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 478 B |
BIN
Mage.Client/src/main/resources/info/yellow_star_24.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_24.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 658 B |
BIN
Mage.Client/src/main/resources/info/yellow_star_32.png
Normal file
BIN
Mage.Client/src/main/resources/info/yellow_star_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 931 B |
|
@ -14,7 +14,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
|
|||
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 = "V3";
|
||||
public final static String MAGE_VERSION_MINOR_PATCH = "V4";
|
||||
public final static String MAGE_VERSION_INFO = "";
|
||||
|
||||
private final int major;
|
||||
|
|
|
@ -21,7 +21,11 @@ public final class PropertiesUtil {
|
|||
|
||||
static {
|
||||
try (InputStream in = PropertiesUtil.class.getResourceAsStream("/xmage.properties")) {
|
||||
if(in != null) {
|
||||
properties.load(in);
|
||||
} else {
|
||||
logger.warn("No xmage.properties were found");
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
logger.warn("No xmage.properties were found on classpath");
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package mage.deck;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public class AusHighlander extends Constructed {
|
||||
|
@ -36,9 +36,9 @@ public class AusHighlander extends Constructed {
|
|||
pointMap.put("Dig Through Time", 2);
|
||||
pointMap.put("Library of Alexandria", 2);
|
||||
pointMap.put("Mana Crypt", 2);
|
||||
pointMap.put("Mind Twist", 2);
|
||||
pointMap.put("Mystical Tutor", 2);
|
||||
pointMap.put("Protean Hulk", 2);
|
||||
pointMap.put("Skullclamp", 2);
|
||||
pointMap.put("Strip Mine", 2);
|
||||
pointMap.put("Tolarian Academy", 2);
|
||||
pointMap.put("Treasure Cruise", 2);
|
||||
|
@ -61,12 +61,12 @@ public class AusHighlander extends Constructed {
|
|||
pointMap.put("Mana Vault", 1);
|
||||
pointMap.put("Memory Jar", 1);
|
||||
pointMap.put("Merchant Scroll", 1);
|
||||
pointMap.put("Mind Twist", 1);
|
||||
pointMap.put("Mishra’s Workshop", 1);
|
||||
pointMap.put("Natural Order", 1);
|
||||
pointMap.put("Oath of Druids", 1);
|
||||
pointMap.put("Personal Tutor", 1);
|
||||
pointMap.put("Sensei’s Divining Top", 1);
|
||||
pointMap.put("Skullclamp", 1);
|
||||
pointMap.put("Snapcaster Mage", 1);
|
||||
pointMap.put("Stoneforge Mystic", 1);
|
||||
pointMap.put("Survival of the Fittest", 1);
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package mage.deck;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public class CanadianHighlander extends Constructed {
|
||||
|
@ -19,7 +19,7 @@ public class CanadianHighlander extends Constructed {
|
|||
static {
|
||||
pointMap.put("Ancestral Recall", 7);
|
||||
pointMap.put("Balance", 1);
|
||||
pointMap.put("Birthing Pod", 3);
|
||||
pointMap.put("Birthing Pod", 2);
|
||||
pointMap.put("Black Lotus", 7);
|
||||
pointMap.put("Demonic Tutor", 3);
|
||||
pointMap.put("Dig Through Time", 1);
|
||||
|
@ -27,7 +27,6 @@ public class CanadianHighlander extends Constructed {
|
|||
pointMap.put("Fastbond", 1);
|
||||
pointMap.put("Flash", 7);
|
||||
pointMap.put("Gifts Ungiven", 2);
|
||||
pointMap.put("Hermit Druid", 1);
|
||||
pointMap.put("Imperial Seal", 1);
|
||||
pointMap.put("Intuition", 1);
|
||||
pointMap.put("Library of Alexandria", 1);
|
||||
|
@ -46,6 +45,7 @@ public class CanadianHighlander extends Constructed {
|
|||
pointMap.put("Personal Tutor", 1);
|
||||
pointMap.put("Protean Hulk", 3);
|
||||
pointMap.put("Sol Ring", 3);
|
||||
pointMap.put("Spellseeker", 1);
|
||||
pointMap.put("Stoneforge Mystic", 1);
|
||||
pointMap.put("Strip Mine", 2);
|
||||
pointMap.put("Summoner's Pact", 2);
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
package mage.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class Standard extends Constructed {
|
||||
|
@ -23,13 +17,7 @@ public class Standard extends Constructed {
|
|||
|
||||
setCodes.addAll(makeLegalSets());
|
||||
|
||||
banned.add("Attune with Aether"); // since 2018-01-15
|
||||
banned.add("Aetherworks Marvel");
|
||||
banned.add("Felidar Guardian");
|
||||
banned.add("Rampaging Ferocidon"); // since 2018-01-15
|
||||
banned.add("Ramunap Ruins"); // since 2018-01-15
|
||||
banned.add("Rogue Refiner"); // since 2018-01-15
|
||||
banned.add("Smuggler's Copter");
|
||||
}
|
||||
|
||||
private static boolean isFallSet(ExpansionSet set) {
|
||||
|
|
|
@ -862,6 +862,19 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
return target.isChosen();
|
||||
}
|
||||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInGraveyardOrBattlefield) {
|
||||
List<Card> cards = new ArrayList<>();
|
||||
for (Player player : game.getPlayers().values()) {
|
||||
cards.addAll(player.getGraveyard().getCards(game));
|
||||
cards.addAll(game.getBattlefield().getAllActivePermanents(new FilterPermanent(), player.getId(), game));
|
||||
}
|
||||
Card card = pickTarget(cards, outcome, target, source, game);
|
||||
if (card != null) {
|
||||
target.addTarget(card.getId(), source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Target wasn't handled. class:" + target.getClass().toString());
|
||||
} //end of chooseTarget method
|
||||
|
||||
|
@ -2074,14 +2087,14 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
int maxScore = RateCard.rateCard(bestCard, chosenColors);
|
||||
int pickedCardRate = RateCard.getCardRating(bestCard);
|
||||
|
||||
if (pickedCardRate <= 3) {
|
||||
if (pickedCardRate <= 30) {
|
||||
// if card is bad
|
||||
// try to counter pick without any color restriction
|
||||
Card counterPick = pickBestCard(cards, null);
|
||||
int counterPickScore = RateCard.getCardRating(counterPick);
|
||||
// card is really good
|
||||
// take it!
|
||||
if (counterPickScore >= 8) {
|
||||
if (counterPickScore >= 80) {
|
||||
bestCard = counterPick;
|
||||
maxScore = RateCard.rateCard(bestCard, chosenColors);
|
||||
}
|
||||
|
|
|
@ -7,13 +7,25 @@ import mage.cards.Card;
|
|||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.Outcome;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.common.DamageWithPowerTargetEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
|
||||
import mage.abilities.effects.common.FightTargetsEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.SubType;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetAttackingCreature;
|
||||
import mage.target.common.TargetAttackingOrBlockingCreature;
|
||||
import mage.target.common.TargetPlayerOrPlaneswalker;
|
||||
|
||||
/**
|
||||
* Class responsible for reading ratings from resources and rating given cards.
|
||||
|
@ -24,14 +36,22 @@ import mage.constants.SubType;
|
|||
public final class RateCard {
|
||||
|
||||
private static Map<String, Integer> ratings;
|
||||
private static List<String> setsWithRatingsToBeLoaded;
|
||||
private static final Map<String, Integer> rated = new HashMap<>();
|
||||
private static Integer min = Integer.MAX_VALUE, max = 0;
|
||||
|
||||
/**
|
||||
* Rating that is given for new cards.
|
||||
* Ratings are in [1,10] range, so setting it high will make new cards appear more often.
|
||||
* nowadays, cards that are more rare are more powerful, lets trust that and play the shiny cards.
|
||||
*
|
||||
*/
|
||||
private static final int DEFAULT_NOT_RATED_CARD_RATING = 4;
|
||||
private static final int DEFAULT_NOT_RATED_CARD_RATING = 40;
|
||||
private static final int DEFAULT_NOT_RATED_UNCOMMON_RATING = 60;
|
||||
private static final int DEFAULT_NOT_RATED_RARE_RATING = 75;
|
||||
private static final int DEFAULT_NOT_RATED_MYTHIC_RATING = 90;
|
||||
|
||||
private static String RATINGS_DIR = "/ratings/";
|
||||
private static String RATINGS_SET_LIST = RATINGS_DIR + "setsWithRatings.csv";
|
||||
|
||||
private static final Logger log = Logger.getLogger(RateCard.class);
|
||||
|
||||
|
@ -53,7 +73,6 @@ public final class RateCard {
|
|||
public static int rateCard(Card card, List<ColoredManaSymbol> allowedColors) {
|
||||
if (allowedColors == null && rated.containsKey(card.getName())) {
|
||||
int rate = rated.get(card.getName());
|
||||
// log.info(card.getName() + " rate: " + rate);
|
||||
return rate;
|
||||
}
|
||||
int type;
|
||||
|
@ -70,7 +89,7 @@ public final class RateCard {
|
|||
} else {
|
||||
type = 6;
|
||||
}
|
||||
int score = 10 * getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors)
|
||||
int score = getCardRating(card) + 2 * type + getManaCostScore(card, allowedColors)
|
||||
+ 40 * isRemoval(card);
|
||||
if (allowedColors == null)
|
||||
rated.put(card.getName(), score);
|
||||
|
@ -78,38 +97,65 @@ public final class RateCard {
|
|||
}
|
||||
|
||||
private static int isRemoval(Card card) {
|
||||
if (card.getSubtype(null).contains(SubType.AURA) || card.isInstant() || card.isSorcery()) {
|
||||
if (card.isEnchantment() || card.isInstant() || card.isSorcery()) {
|
||||
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
if (isEffectRemoval(card, ability, effect) == 1){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (Mode mode: ability.getModes().values() ){
|
||||
for (Effect effect: mode.getEffects()){
|
||||
if (isEffectRemoval(card, ability, effect) == 1){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int isEffectRemoval(Card card, Ability ability, Effect effect){
|
||||
if (effect.getOutcome() == Outcome.Removal) {
|
||||
log.debug("Found removal: " + card.getName());
|
||||
return 1;
|
||||
}
|
||||
if (effect.getOutcome() == Outcome.Damage) {
|
||||
if (effect instanceof DamageTargetEffect) {
|
||||
DamageTargetEffect damageEffect = (DamageTargetEffect) effect;
|
||||
if (damageEffect.getAmount() > 1) {
|
||||
//static List<Effect> removalEffects =[BoostTargetEffect,BoostEnchantedEffect]
|
||||
if (effect instanceof BoostTargetEffect || effect instanceof BoostEnchantedEffect){
|
||||
String text = effect.getText(null);
|
||||
if (text.contains("/-")){
|
||||
// toughness reducer, aka removal
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (effect instanceof FightTargetsEffect || effect instanceof DamageWithPowerTargetEffect){
|
||||
return 1;
|
||||
}
|
||||
if (effect.getOutcome() == Outcome.Damage || effect instanceof DamageTargetEffect) {
|
||||
for (Target target : ability.getTargets()) {
|
||||
if (target instanceof TargetCreaturePermanent || target instanceof TargetAnyTarget) {
|
||||
if (!(target instanceof TargetPlayerOrPlaneswalker)){
|
||||
log.debug("Found damage dealer: " + card.getName());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (effect.getOutcome() == Outcome.DestroyPermanent) {
|
||||
if (effect.getOutcome() == Outcome.DestroyPermanent ||
|
||||
effect instanceof DestroyTargetEffect ||
|
||||
effect instanceof ExileTargetEffect ||
|
||||
effect instanceof ExileUntilSourceLeavesEffect) {
|
||||
for (Target target : ability.getTargets()) {
|
||||
if (target instanceof TargetCreaturePermanent) {
|
||||
log.debug("Found destroyer: " + card.getName());
|
||||
if (target instanceof TargetCreaturePermanent ||
|
||||
target instanceof TargetAttackingCreature ||
|
||||
target instanceof TargetAttackingOrBlockingCreature ||
|
||||
target instanceof TargetPermanent) {
|
||||
log.debug("Found destroyer/exiler: " + card.getName());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -117,32 +163,72 @@ public final class RateCard {
|
|||
* Return rating of the card.
|
||||
*
|
||||
* @param card Card to rate.
|
||||
* @return Rating number from [1;10].
|
||||
* @return Rating number from [1:100].
|
||||
*/
|
||||
public static int getCardRating(Card card) {
|
||||
if (ratings == null) {
|
||||
readRatings();
|
||||
readRatingSetList();
|
||||
String exp = card.getExpansionSetCode().toLowerCase();
|
||||
readRatings(exp);
|
||||
|
||||
if (ratings != null && ratings.containsKey(card.getName())) {
|
||||
return ratings.get(card.getName());
|
||||
}
|
||||
if (ratings.containsKey(card.getName())) {
|
||||
int r = ratings.get(card.getName());
|
||||
// normalize to [1..10]
|
||||
float f = 10.0f * (r - min) / (max - min);
|
||||
return (int) Math.round(f);
|
||||
|
||||
Rarity r = card.getRarity();
|
||||
if (Rarity.COMMON == r){
|
||||
return DEFAULT_NOT_RATED_CARD_RATING;
|
||||
}else if (Rarity.UNCOMMON == r){
|
||||
return DEFAULT_NOT_RATED_UNCOMMON_RATING;
|
||||
}else if (Rarity.RARE == r){
|
||||
return DEFAULT_NOT_RATED_RARE_RATING;
|
||||
}else if (Rarity.MYTHIC == r){
|
||||
return DEFAULT_NOT_RATED_MYTHIC_RATING;
|
||||
}
|
||||
return DEFAULT_NOT_RATED_CARD_RATING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads ratings from resources.
|
||||
* reads the list of sets that have ratings csv files
|
||||
* populates the setsWithRatingsToBeLoaded
|
||||
*/
|
||||
private synchronized static void readRatings() {
|
||||
if (ratings == null) {
|
||||
ratings = new HashMap<>();
|
||||
readFromFile("/m13.csv");
|
||||
private synchronized static void readRatingSetList(){
|
||||
try {
|
||||
if (setsWithRatingsToBeLoaded == null){
|
||||
setsWithRatingsToBeLoaded = new LinkedList<>();
|
||||
InputStream is = RateCard.class.getResourceAsStream(RATINGS_SET_LIST);
|
||||
Scanner scanner = new Scanner(is);
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (!line.substring(0,1).equals("#")){
|
||||
setsWithRatingsToBeLoaded.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Exception e) {
|
||||
log.info("failed to read ratings set list file: " + RATINGS_SET_LIST );
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void readFromFile(String path) {
|
||||
/**
|
||||
* Reads ratings from resources and loads them into ratings map
|
||||
*/
|
||||
private synchronized static void readRatings(String expCode) {
|
||||
if (ratings == null) {
|
||||
ratings = new HashMap<>();
|
||||
}
|
||||
if (setsWithRatingsToBeLoaded.contains(expCode)){
|
||||
log.info("reading draftbot ratings for the set" + expCode);
|
||||
readFromFile(RATINGS_DIR + expCode + ".csv");
|
||||
setsWithRatingsToBeLoaded.remove(expCode);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* reads ratings from the file
|
||||
*/
|
||||
private synchronized static void readFromFile(String path) {
|
||||
Integer min = Integer.MAX_VALUE, max = 0;
|
||||
Map<String, Integer> thisFileRatings = new HashMap<>();
|
||||
try {
|
||||
InputStream is = RateCard.class.getResourceAsStream(path);
|
||||
Scanner scanner = new Scanner(is);
|
||||
|
@ -158,21 +244,32 @@ public final class RateCard {
|
|||
if (rating < min) {
|
||||
min = rating;
|
||||
}
|
||||
ratings.put(name, rating);
|
||||
thisFileRatings.put(name, rating);
|
||||
}
|
||||
}
|
||||
// normalize for the file to [1..100]
|
||||
for (String name: thisFileRatings.keySet()){
|
||||
int r = thisFileRatings.get(name);
|
||||
int newrating = (int)(100.0f * (r - min) / (max - min));
|
||||
if (!ratings.containsKey(name) ||
|
||||
(ratings.containsKey(name) && newrating > ratings.get(name)) ){
|
||||
ratings.put(name, newrating);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info("failed to read ratings file: " + path );
|
||||
e.printStackTrace();
|
||||
ratings.clear(); // no rating available on exception
|
||||
}
|
||||
}
|
||||
|
||||
private static final int SINGLE_PENALTY[] = {0, 1, 1, 3, 6, 9};
|
||||
private static final int MULTICOLOR_BONUS = 15;
|
||||
|
||||
/**
|
||||
* Get manacost score.
|
||||
* Depends on chosen colors. Returns negative score for those cards that doesn't fit allowed colors.
|
||||
* If allowed colors are not chosen, then score based on converted cost is returned with penalty for heavy colored cards.
|
||||
* gives bonus to multicolor cards that fit within allowed colors and if allowed colors is <5
|
||||
*
|
||||
*
|
||||
* @param card
|
||||
|
@ -215,7 +312,12 @@ public final class RateCard {
|
|||
}
|
||||
if (maxSingleCount > 5)
|
||||
maxSingleCount = 5;
|
||||
return 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]/*-DOUBLE_PENALTY[doubleCount]*/);
|
||||
|
||||
int rate = 2 * converted + 3 * (10 - SINGLE_PENALTY[maxSingleCount]);
|
||||
if( singleCount.size() > 1 && singleCount.size() < 5){
|
||||
rate += MULTICOLOR_BONUS;
|
||||
}
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,184 @@
|
|||
Ajani Unyielding:40114
|
||||
Herald of Anguish:39905
|
||||
Rishkar, Peema Renegade:39137
|
||||
Aethersphere Harvester:38827
|
||||
Heart of Kiran:37403
|
||||
Yahenni’s Expertise:37199
|
||||
Tezzeret the Schemer:34694
|
||||
Solemn Recruit:34338
|
||||
Untethered Express:33419
|
||||
Battle at the Bridge:33072
|
||||
Yahenni, Undying Partisan:32377
|
||||
Fatal Push:32126
|
||||
Sram’s Expertise:32076
|
||||
Walking Ballista:31052
|
||||
Baral’s Expertise:30879
|
||||
Freejam Regent:30870
|
||||
Glint-Sleeve Siphoner:30022
|
||||
Ridgescale Tusker:30018
|
||||
Quicksmith Spy:29214
|
||||
Scrapper Champion:29176
|
||||
Aethertide Whale:28976
|
||||
Daring Demolition:28538
|
||||
Gifted Aetherborn:28163
|
||||
Quicksmith Rebel:27792
|
||||
Hungry Flames:27737
|
||||
Thopter Arrest:27574
|
||||
Exquisite Archangel:27415
|
||||
Kari Zev, Skyship Raider:27188
|
||||
Aetherwind Basker:26371
|
||||
Treasure Keeper:26283
|
||||
Greenbelt Rampager:26185
|
||||
Vengeful Rebel:25902
|
||||
Aethergeode Miner:25711
|
||||
Rishkar’s Expertise:25327
|
||||
Lightning Runner:25297
|
||||
Shock:25129
|
||||
Caught in the Brights:24815
|
||||
Lifecrafter’s Bestiary:24466
|
||||
Midnight Entourage:23732
|
||||
Sram, Senior Edificer:23386
|
||||
Metallic Mimic:23383
|
||||
Maulfist Revolutionary:23093
|
||||
Greenwheel Liberator:21817
|
||||
Chandra’s Revolution:21713
|
||||
Maverick Thopterist:21685
|
||||
Airdrop Aeronauts:21061
|
||||
Narnam Renegade:20406
|
||||
Winding Constrictor:20174
|
||||
Scrap Trawler:20001
|
||||
Monstrous Onslaught:19528
|
||||
Wind-Kin Raiders:19507
|
||||
Deadeye Harpooner:19305
|
||||
Skyship Plunderer:18967
|
||||
Aether Poisoner:18617
|
||||
Cruel Finality:18352
|
||||
Release the Gremlins:18286
|
||||
Aether Chaser:17813
|
||||
Rogue Refiner:17646
|
||||
Reckless Racer:17299
|
||||
Dawnfeather Eagle:17238
|
||||
Felidar Guardian:17122
|
||||
Prey Upon:16986
|
||||
Spire Patrol:16942
|
||||
Druid of the Cowl:16941
|
||||
Aetherstream Leopard:16826
|
||||
Reverse Engineer:15858
|
||||
Daredevil Dragster:15795
|
||||
Shielded Aether Thief:15596
|
||||
Scrounging Bandar:14827
|
||||
Lifecraft Cavalry:14821
|
||||
Pacification Array:14672
|
||||
Renegade Rallier:14442
|
||||
Trophy Mage:14084
|
||||
Enraged Giant:13989
|
||||
Foundry Hornet:13907
|
||||
Call for Unity:13832
|
||||
Renegade Wheelsmith:13717
|
||||
Peacewalker Colossus:13604
|
||||
Sweatworks Brawler:13229
|
||||
Aether Swooper:13171
|
||||
Outland Boar:13074
|
||||
Restoration Specialist:12713
|
||||
Perilous Predicament:12702
|
||||
Aeronaut Admiral:12409
|
||||
Tezzeret’s Touch:12281
|
||||
Oath of Ajani:11663
|
||||
Bastion Inventor:11485
|
||||
Weldfast Engineer:11309
|
||||
Countless Gears Renegade:11144
|
||||
Mechanized Production:10887
|
||||
Hinterland Drake:10667
|
||||
Consulate Crackdown:10549
|
||||
Renegade Map:10115
|
||||
Peema Aether-Seer:9906
|
||||
Unbridled Growth:9661
|
||||
Lifecraft Awakening:9620
|
||||
Baral, Chief of Compliance:9382
|
||||
Merchant’s Dockhand:9033
|
||||
Barricade Breaker:8635
|
||||
Lifecrafter’s Gift:8248
|
||||
Hidden Herbalists:8012
|
||||
Mobile Garrison:7976
|
||||
Aether Herder:7964
|
||||
Disallow:7550
|
||||
Kari Zev’s Expertise:7472
|
||||
Cogwork Assembler:7463
|
||||
Heroic Intervention:6922
|
||||
Hidden Stockpile:6732
|
||||
Illusionist’s Stratagem:6678
|
||||
Leave in the Dust:6675
|
||||
Ghirapur Osprey:6597
|
||||
Decommission:6354
|
||||
Ice Over:6297
|
||||
Night Market Aeronaut:6198
|
||||
Gremlin Infestation:6195
|
||||
Spire of Industry:6181
|
||||
Audacious Infiltrator:6084
|
||||
Sly Requisitioner:5718
|
||||
Alley Strangler:5595
|
||||
Silkweaver Elite:5574
|
||||
Aid from the Cowl:5463
|
||||
Highspire Infusion:5402
|
||||
Frontline Rebel:5350
|
||||
Invigorated Rampage:5268
|
||||
Defiant Salvager:5211
|
||||
Watchful Automaton:5147
|
||||
Siege Modification:5142
|
||||
Inspiring Statuary:4932
|
||||
Embraal Gear-Smasher:4847
|
||||
Deft Dismissal:4727
|
||||
Shipwreck Moray:4645
|
||||
Metallic Rebuke:4618
|
||||
Dispersal Technician:4389
|
||||
Resourceful Return:4325
|
||||
Efficient Construction:4108
|
||||
Welder Automaton:4076
|
||||
Aether Inspector:3989
|
||||
Ravenous Intruder:3963
|
||||
Ironclad Revolutionary:3930
|
||||
Implement of Ferocity:3720
|
||||
Alley Evasion:3712
|
||||
Hope of Ghirapur:3699
|
||||
Aerial Modification:3671
|
||||
Gonti’s Aether Heart:3295
|
||||
Foundry Assembler:3292
|
||||
Fen Hauler:3265
|
||||
Natural Obsolescence:3262
|
||||
Destructive Tampering:3239
|
||||
Implement of Examination:3217
|
||||
Irontread Crusher:3097
|
||||
Filigree Crawler:3020
|
||||
Servo Schematic:3006
|
||||
Verdant Automaton:2979
|
||||
Reservoir Walker:2918
|
||||
Whir of Invention:2916
|
||||
Paradox Engine:2714
|
||||
Salvage Scuttler:2677
|
||||
Augmenting Automaton:2636
|
||||
Fourth Bridge Prowler:2448
|
||||
Conviction:2411
|
||||
Lathnu Sailback:2352
|
||||
Planar Bridge:2348
|
||||
Night Market Guard:2244
|
||||
Bastion Enforcer:2236
|
||||
Precise Strike:2179
|
||||
Universal Solvent:2128
|
||||
Implement of Malice:2089
|
||||
Crackdown Construct:1926
|
||||
Dark Intimations:1876
|
||||
Pia’s Revolution:1850
|
||||
Renegade’s Getaway:1472
|
||||
Aegis Automaton:1355
|
||||
Consulate Dreadnought:1255
|
||||
Indomitable Creativity:1206
|
||||
Negate:1016
|
||||
Consulate Turret:1014
|
||||
Implement of Combustion:806
|
||||
Take into Custody:678
|
||||
Implement of Improvement:624
|
||||
Wrangle:543
|
||||
Ornithopter:177
|
||||
Gonti’s Machinations:167
|
||||
Prizefighter Construct:123
|
||||
Secret Salvage:77
|
|
|
@ -0,0 +1,249 @@
|
|||
Angel of Sanctions:1638
|
||||
Glorybringer:1590
|
||||
Oketra the True:1512
|
||||
Rhonas the Indomitable:1456
|
||||
Gideon of the Trials:1445
|
||||
Hazoret the Fervent:1404
|
||||
Liliana, Death’s Majesty:1370
|
||||
Archfiend of Ifnir:1346
|
||||
Cast Out:1331
|
||||
Curator of Mysteries:1329
|
||||
Regal Caracal:1324
|
||||
Glyph Keeper:1312
|
||||
Cut /// Ribbons:1310
|
||||
Dusk /// Dawn:1266
|
||||
Vizier of Many Faces:1252
|
||||
Never /// Return:1251
|
||||
Vizier of the Menagerie:1243
|
||||
Heart-Piercer Manticore:1220
|
||||
Liliana’s Mastery:1216
|
||||
Trial of Zeal:1195
|
||||
Samut, Voice of Dissent:1190
|
||||
Nissa, Steward of Elements:1174
|
||||
Magma Spray:1157
|
||||
Honored Hydra:1132
|
||||
Sweltering Suns:1126
|
||||
Glory-Bound Initiate:1125
|
||||
Lord of the Accursed:1119
|
||||
Ahn-Crop Crasher:1115
|
||||
Insult /// Injury:1113
|
||||
Champion of Rhonas:1096
|
||||
Plague Belcher:1095
|
||||
Angler Drake:1091
|
||||
Cartouche of Strength:1089
|
||||
Electrify:1083
|
||||
Combat Celebrant:1079
|
||||
Compulsory Rest:1073
|
||||
Crocodile of the Crossing:1061
|
||||
Gust Walker:1058
|
||||
Scaled Behemoth:1055
|
||||
Decimator Beetle:1050
|
||||
Bone Picker:1048
|
||||
Drake Haven:1042
|
||||
Mouth /// Feed:1039
|
||||
Channeler Initiate:1038
|
||||
Deem Worthy:1031
|
||||
Bontu the Glorified:1022
|
||||
Trial of Solidarity:1018
|
||||
Final Reward:1013
|
||||
Stir the Sands:1010
|
||||
Hapatra, Vizier of Poisons:1009
|
||||
Start /// Finish:1005
|
||||
Trial of Strength:1002
|
||||
Emberhorn Minotaur:999
|
||||
Prepare /// Fight:998
|
||||
Baleful Ammit:997
|
||||
Cartouche of Knowledge:989
|
||||
Cruel Reality:989
|
||||
Sandwurm Convergence:973
|
||||
Prowling Serpopard:965
|
||||
Trial of Ambition:962
|
||||
Devoted Crop-Mate:959
|
||||
Oketra’s Attendant:955
|
||||
Commit /// Memory:952
|
||||
Neheb, the Worthy:952
|
||||
Aven Wind Guide:944
|
||||
Bloodrage Brawler:944
|
||||
Fan Bearer:936
|
||||
Dread Wanderer:930
|
||||
Temmet, Vizier of Naktamun:924
|
||||
Oketra’s Monument:921
|
||||
Edifice of Authority:919
|
||||
Cartouche of Ambition:918
|
||||
Wayward Servant:905
|
||||
Lay Claim:903
|
||||
Splendid Agony:896
|
||||
Tah-Crop Elite:894
|
||||
Kefnet the Mindful:884
|
||||
Gravedigger:871
|
||||
Harsh Mentor:864
|
||||
Soulstinger:863
|
||||
Exemplar of Strength:862
|
||||
Cartouche of Zeal:861
|
||||
Defiant Greatmaw:846
|
||||
Enigma Drake:846
|
||||
Cartouche of Solidarity:840
|
||||
Labyrinth Guardian:836
|
||||
Vizier of Deferment:835
|
||||
Naga Vitalist:834
|
||||
Pull from Tomorrow:832
|
||||
Rags /// Riches:832
|
||||
Khenra Charioteer:829
|
||||
Hooded Brawler:828
|
||||
Horror of the Broken Lands:815
|
||||
Trueheart Duelist:815
|
||||
Honored Crop-Captain:813
|
||||
Bitterblade Warrior:812
|
||||
Shefet Monitor:808
|
||||
Heaven /// Earth:807
|
||||
Seraph of the Suns:805
|
||||
Nef-Crop Entangler:803
|
||||
Greater Sandwurm:802
|
||||
Ruthless Sniper:799
|
||||
Cursed Minotaur:798
|
||||
Rhet-Crop Spearmaster:796
|
||||
Soul-Scar Mage:796
|
||||
Trial of Knowledge:787
|
||||
Trueheart Twins:785
|
||||
Battlefield Scavenger:784
|
||||
Aven Initiate:782
|
||||
Wasteland Scorpion:778
|
||||
Impeccable Timing:774
|
||||
Essence Scatter:773
|
||||
Open into Wonder:769
|
||||
Unwavering Initiate:767
|
||||
Warfire Javelineer:765
|
||||
Manticore of the Gauntlet:762
|
||||
Binding Mummy:760
|
||||
Approach of the Second Sun:758
|
||||
Ahn-Crop Champion:757
|
||||
Synchronized Strike:756
|
||||
Winged Shepherd:747
|
||||
Ornery Kudu:742
|
||||
Cryptic Serpent:741
|
||||
Shimmerscale Drake:739
|
||||
Hieroglyphic Illumination:737
|
||||
Censor:733
|
||||
Illusory Wrappings:731
|
||||
Watchful Naga:731
|
||||
Vizier of Tumbling Sands:724
|
||||
Minotaur Sureshot:720
|
||||
Rhonas’s Monument:719
|
||||
Galestrike:718
|
||||
Merciless Javelineer:718
|
||||
Bounty of the Luxa:712
|
||||
Aven Mindcensor:708
|
||||
Naga Oracle:705
|
||||
Thresher Lizard:692
|
||||
Quarry Hauler:689
|
||||
Irrigated Farmland:688
|
||||
Pathmaker Initiate:681
|
||||
Shadowstorm Vizier:678
|
||||
Grim Strider:676
|
||||
Flameblade Adept:674
|
||||
Sheltered Thicket:672
|
||||
Destined /// Lead:668
|
||||
Wander in Death:668
|
||||
Weaver of Currents:663
|
||||
Blighted Bat:651
|
||||
Nest of Scarabs:648
|
||||
Oracle’s Vault:646
|
||||
Canyon Slough:643
|
||||
Evolving Wilds:640
|
||||
Colossapede:638
|
||||
Sacred Cat:637
|
||||
Doomed Dissenter:635
|
||||
Fetid Pools:628
|
||||
Festering Mummy:616
|
||||
Onward /// Victory:615
|
||||
Throne of the God-Pharaoh:613
|
||||
Anointed Procession:608
|
||||
Gift of Paradise:602
|
||||
Anointer Priest:599
|
||||
Consuming Fervor:595
|
||||
Limits of Solidarity:594
|
||||
Spring /// Mind:593
|
||||
Desert Cerodon:592
|
||||
Sparring Mummy:592
|
||||
River Serpent:584
|
||||
Seeker of Insight:582
|
||||
Shed Weakness:582
|
||||
Gideon’s Intervention:580
|
||||
Slither Blade:580
|
||||
Tah-Crop Skirmisher:580
|
||||
Initiate’s Companion:570
|
||||
Pitiless Vizier:567
|
||||
Scattered Groves:563
|
||||
Supernatural Stamina:563
|
||||
Vizier of Remedies:563
|
||||
Hekma Sentinels:562
|
||||
Bloodlust Inciter:559
|
||||
Pouncing Cheetah:559
|
||||
Winds of Rebuke:550
|
||||
Cancel:540
|
||||
Painful Lesson:536
|
||||
Mighty Leap:535
|
||||
Pyramid of the Pantheon:535
|
||||
Reduce /// Rubble:533
|
||||
Brute Strength:530
|
||||
Floodwaters:530
|
||||
Faith of the Devoted:529
|
||||
Manglehorn:529
|
||||
Miasmic Mummy:522
|
||||
Fling:519
|
||||
Oashra Cultivator:512
|
||||
In Oketra’s Name:510
|
||||
Forsake the Worldly:506
|
||||
Supply Caravan:505
|
||||
Time to Reflect:505
|
||||
Decision Paralysis:504
|
||||
Giant Spider:504
|
||||
Hapatra’s Mark:500
|
||||
Nimble-Blade Khenra:499
|
||||
Harvest Season:497
|
||||
Failure /// Comply:496
|
||||
Zenith Seeker:494
|
||||
Those Who Serve:491
|
||||
Bontu’s Monument:488
|
||||
As Foretold:487
|
||||
Tormenting Voice:487
|
||||
Hazoret’s Monument:485
|
||||
New Perspectives:484
|
||||
Pursue Glory:478
|
||||
Unburden:476
|
||||
Djeru’s Resolve:469
|
||||
Spidery Grasp:468
|
||||
Kefnet’s Monument:466
|
||||
Lay Bare the Heart:464
|
||||
Scribe of the Mindful:463
|
||||
Honed Khopesh:450
|
||||
Stinging Shot:443
|
||||
Trespasser’s Curse:431
|
||||
Blazing Volley:430
|
||||
Watchers of the Dead:415
|
||||
Sixth Sense:413
|
||||
Dune Beetle:386
|
||||
Cradle of the Accursed:382
|
||||
Glorious End:380
|
||||
Sacred Excavation:379
|
||||
Grasping Dunes:372
|
||||
Shadow of the Grave:370
|
||||
Cascading Cataracts:357
|
||||
Hyena Pack:356
|
||||
Benefaction of Rhonas:354
|
||||
Dissenter’s Deliverance:353
|
||||
Painted Bluffs:348
|
||||
Renewed Faith:337
|
||||
Hazoret’s Favor:305
|
||||
Violent Impact:284
|
||||
Haze of Pollen:277
|
||||
Scarab Feast:268
|
||||
Compelling Argument:265
|
||||
Embalmer’s Tools:260
|
||||
Luxa River Shrine:213
|
||||
By Force:201
|
||||
Ancient Crab:198
|
||||
Sunscorched Desert:186
|
||||
Dispossess:109
|
||||
Protection of the Hekma:108
|
||||
Gate to the Afterlife 95
|
Can't render this file because it has a wrong number of fields in line 249.
|
|
@ -0,0 +1,249 @@
|
|||
Lyra Dawnbringer:2375
|
||||
Karn, Scion of Urza:2372
|
||||
Shalai, Voice of Plenty:2234
|
||||
Teferi, Hero of Dominaria:2215
|
||||
Verix Bladewing:2207
|
||||
Aryel, Knight of Windgrace:2166
|
||||
Multani, Yavimaya’s Avatar:2150
|
||||
History of Benalia:2123
|
||||
Siege-Gang Commander:2091
|
||||
In Bolas’s Clutches:2047
|
||||
Josu Vess, Lich Knight:2044
|
||||
Cast Down:2025
|
||||
Demonlord Belzenlok:2016
|
||||
Eviscerate:2010
|
||||
Serra Angel:2000
|
||||
Slimefoot, the Stowaway:1995
|
||||
Seal Away:1985
|
||||
Tatyova, Benthic Druid:1981
|
||||
Zahid, Djinn of the Lamp:1971
|
||||
Darigaaz Reincarnated:1959
|
||||
Weatherlight:1952
|
||||
Phyrexian Scriptures:1951
|
||||
Forebear’s Blade:1928
|
||||
Adeliz, the Cinder Wind:1919
|
||||
The Eldest Reborn:1919
|
||||
Teshar, Ancestor’s Apostle:1913
|
||||
Territorial Allosaurus:1896
|
||||
Danitha Capashen, Paragon:1895
|
||||
Muldrotha, the Gravetide:1881
|
||||
Fight with Fire:1879
|
||||
Shivan Fire:1879
|
||||
Helm of the Host:1876
|
||||
Knight of Grace:1863
|
||||
Vicious Offering:1859
|
||||
Pegasus Courser:1856
|
||||
Icy Manipulator:1849
|
||||
Benalish Marshal:1837
|
||||
Untamed Kavu:1836
|
||||
Goblin Chainwhirler:1834
|
||||
Raff Capashen, Ship’s Mage:1834
|
||||
Blessed Light:1833
|
||||
Rite of Belzenlok:1827
|
||||
Naru Meha, Master Wizard:1824
|
||||
Grand Warlord Radha:1817
|
||||
Two-Headed Giant:1817
|
||||
Llanowar Elves:1815
|
||||
Shanna, Sisay’s Legacy:1814
|
||||
Steel Leaf Champion:1811
|
||||
Song of Freyalise:1807
|
||||
Settle the Score:1804
|
||||
Time of Ice:1804
|
||||
Grunn, the Lonely King:1793
|
||||
Knight of Malice:1786
|
||||
Arvad the Cursed:1783
|
||||
Jhoira, Weatherlight Captain:1780
|
||||
Saproling Migration:1780
|
||||
Wizard’s Lightning:1779
|
||||
Tempest Djinn:1777
|
||||
Urgoros, the Empty One:1773
|
||||
Cloudreader Sphinx:1769
|
||||
Baloth Gorger:1768
|
||||
Skittering Surveyor:1765
|
||||
Baird, Steward of Argive:1762
|
||||
Blackblade Reforged:1760
|
||||
Hallar, the Firefletcher:1760
|
||||
On Serra’s Wings:1753
|
||||
Evra, Halcyon Witness:1748
|
||||
Traxos, Scourge of Kroog:1746
|
||||
Blink of an Eye:1742
|
||||
Triumph of Gerrard:1725
|
||||
Deep Freeze:1723
|
||||
Kazarov, Sengir Pureblood:1718
|
||||
Tiana, Ship’s Caretaker:1712
|
||||
Merfolk Trickster:1709
|
||||
Squee, the Immortal:1708
|
||||
Valduk, Keeper of the Flame:1708
|
||||
Kwende, Pride of Femeref:1707
|
||||
Whisper, Blood Liturgist:1707
|
||||
Academy Drake:1705
|
||||
Jaya Ballard:1704
|
||||
Gideon’s Reproach:1703
|
||||
Warcry Phoenix:1703
|
||||
Sporecrown Thallid:1698
|
||||
Yavimaya Sapherd:1692
|
||||
Rona, Disciple of Gix:1686
|
||||
Wizard’s Retort:1684
|
||||
Elfhame Druid:1683
|
||||
Fiery Intervention:1682
|
||||
Torgaar, Famine Incarnate:1682
|
||||
Yawgmoth’s Vile Offering:1677
|
||||
Deathbloom Thallid:1665
|
||||
Fungal Infection:1662
|
||||
Daring Archaeologist:1658
|
||||
Cold-Water Snapper:1656
|
||||
Thorn Elemental:1656
|
||||
Call the Cavalry:1649
|
||||
Sylvan Awakening:1648
|
||||
Jaya’s Immolating Inferno:1646
|
||||
Verdant Force:1642
|
||||
Fungal Plots:1636
|
||||
Spore Swarm:1635
|
||||
Divination:1629
|
||||
Syncopate:1626
|
||||
Marwyn, the Nurturer:1625
|
||||
Sergeant-at-Arms:1625
|
||||
Garna, the Bloodflame:1624
|
||||
Ghitu Chronicler:1622
|
||||
Tetsuko Umezawa, Fugitive:1612
|
||||
Dread Shade:1602
|
||||
Stronghold Confessor:1601
|
||||
Academy Journeymage:1599
|
||||
Chainer’s Torment:1593
|
||||
Thallid Omnivore:1592
|
||||
Thallid Soothsayer:1592
|
||||
Jousting Lance:1587
|
||||
Firefist Adept:1581
|
||||
Goblin Barrage:1580
|
||||
Naban, Dean of Iteration:1579
|
||||
Caligo Skin-Witch:1577
|
||||
Karn’s Temporal Sundering:1577
|
||||
Keldon Overseer:1574
|
||||
Dauntless Bodyguard:1572
|
||||
Opt:1572
|
||||
Ghitu Journeymage:1570
|
||||
The Mending of Dominaria:1568
|
||||
The Mirari Conjecture:1568
|
||||
Wild Onslaught:1567
|
||||
Haphazard Bombardment:1566
|
||||
Skizzik:1565
|
||||
Mammoth Spider:1558
|
||||
Serra Disciple:1558
|
||||
Clifftop Retreat:1557
|
||||
Aven Sentry:1556
|
||||
Mishra’s Self-Replicator:1552
|
||||
Ancient Animus:1550
|
||||
D’Avenant Trapper:1550
|
||||
Gilded Lotus:1549
|
||||
Jhoira’s Familiar:1548
|
||||
Champion of the Flame:1547
|
||||
Ghitu Lavarunner:1547
|
||||
Woodland Cemetery:1543
|
||||
Keldon Raider:1541
|
||||
Grow from the Ashes:1536
|
||||
Radiating Lightning:1536
|
||||
Sanctum Spirit:1533
|
||||
Windgrace Acolyte:1532
|
||||
Urza’s Ruinous Blast:1531
|
||||
Sulfur Falls:1527
|
||||
The Antiquities War:1522
|
||||
Adamant Will:1519
|
||||
Goblin Warchief:1518
|
||||
Adventurous Impulse:1516
|
||||
Mesa Unicorn:1512
|
||||
Bloodtallow Candle:1510
|
||||
Hinterland Harbor:1509
|
||||
Lingering Phantom:1506
|
||||
Short Sword:1499
|
||||
Llanowar Scout:1495
|
||||
Juggernaut:1493
|
||||
Frenzied Rage:1490
|
||||
Slinn Voda, the Rising Deep:1489
|
||||
Dub:1484
|
||||
Cabal Paladin:1482
|
||||
Gift of Growth:1482
|
||||
Dark Bargain:1481
|
||||
Benalish Honor Guard:1480
|
||||
Isolated Chapel:1473
|
||||
Kamahl’s Druidic Vow:1472
|
||||
Memorial to Glory:1469
|
||||
Sentinel of the Pearl Trident:1466
|
||||
Krosan Druid:1465
|
||||
Guardians of Koilos:1457
|
||||
Llanowar Envoy:1455
|
||||
Pardic Wanderer:1450
|
||||
Soul Salvage:1449
|
||||
The Flame of Keld:1448
|
||||
Arcane Flight:1445
|
||||
Divest:1444
|
||||
Feral Abomination:1441
|
||||
Artificer’s Assistant:1439
|
||||
Memorial to Unity:1439
|
||||
Yargle, Glutton of Urborg:1436
|
||||
Sparring Construct:1431
|
||||
Mox Amber:1429
|
||||
Weight of Memory:1426
|
||||
Precognition Field:1424
|
||||
The First Eruption:1420
|
||||
Invoke the Divine:1414
|
||||
Unwind:1413
|
||||
Primordial Wurm:1409
|
||||
Bloodstone Goblin:1408
|
||||
Vodalian Arcanist:1401
|
||||
Cabal Stronghold:1400
|
||||
Urza’s Tome:1393
|
||||
Lich’s Mastery:1390
|
||||
Primevals’ Glorious Rebirth:1390
|
||||
Run Amok:1390
|
||||
Gaea’s Protector:1382
|
||||
Pierce the Sky:1382
|
||||
Relic Runner:1381
|
||||
Jodah, Archmage Eternal:1378
|
||||
Excavation Elephant:1377
|
||||
Knight of New Benalia:1377
|
||||
Aesthir Glider:1376
|
||||
Befuddle:1375
|
||||
Homarid Explorer:1372
|
||||
Memorial to Folly:1371
|
||||
Howling Golem:1369
|
||||
Voltaic Servant:1369
|
||||
Nature’s Spiral:1368
|
||||
Sorcerer’s Wand:1366
|
||||
Corrosive Ooze:1360
|
||||
Broken Bond:1357
|
||||
Curator’s Ward:1355
|
||||
Tolarian Scholar:1354
|
||||
Memorial to Genius:1349
|
||||
Rampaging Cyclops:1347
|
||||
Warlord’s Fury:1328
|
||||
Fervent Strike:1321
|
||||
Demonic Vigor:1320
|
||||
Keldon Warcaller:1319
|
||||
Arbor Armament:1314
|
||||
Final Parting:1313
|
||||
Diligent Excavator:1312
|
||||
Navigator’s Compass:1308
|
||||
Charge:1307
|
||||
Amaranthine Wall:1305
|
||||
Cabal Evangel:1305
|
||||
Fire Elemental:1304
|
||||
Shield of the Realm:1304
|
||||
Oath of Teferi:1300
|
||||
Tragic Poet:1283
|
||||
Blessing of Belzenlok:1272
|
||||
Board the Weatherlight:1258
|
||||
Thran Temporal Gateway:1256
|
||||
Drudge Sentinel:1248
|
||||
Orcish Vandal:1247
|
||||
Skirk Prospector:1246
|
||||
Zhalfirin Void:1239
|
||||
Sage of Lat-Nam:1232
|
||||
Rescue:1225
|
||||
Gaea’s Blessing:1218
|
||||
Healing Grace:1200
|
||||
Rat Colony:1191
|
||||
Powerstone Shard:1162
|
||||
Seismic Shift:1152
|
||||
Damping Sphere:1133
|
||||
Fall of the Thran:1104
|
||||
Memorial to War:1089
|
|
|
@ -0,0 +1,259 @@
|
|||
Doom Whisperer:2332
|
||||
Aurelia, Exemplar of Justice:2258
|
||||
Vraska, Golgari Queen:2211
|
||||
Ral, Izzet Viceroy:2196
|
||||
Dream Eater:2180
|
||||
Thief of Sanity:2164
|
||||
Assassin's Trophy:2153
|
||||
Trostani Discordant:2141
|
||||
Beast Whisperer:2102
|
||||
Nullhide Ferox:2102
|
||||
Legion Warboss:2100
|
||||
March of the Multitudes:2094
|
||||
Conclave Tribunal:2092
|
||||
Niv-Mizzet, Parun:2088
|
||||
Light of the Legion:2073
|
||||
Price of Fame:2036
|
||||
Etrata, the Silencer:2019
|
||||
Venerated Loxodon:2017
|
||||
Justice Strike:2016
|
||||
Tajic, Legion's Edge:2005
|
||||
Underrealm Lich:1985
|
||||
Pelt Collector:1984
|
||||
Izoni, Thousand-Eyed:1977
|
||||
Find // Finality:1976
|
||||
Lazav, the Multifarious:1973
|
||||
Nightveil Sprite:1968
|
||||
Midnight Reaper:1964
|
||||
Lava Coil:1963
|
||||
Watcher in the Mist:1961
|
||||
Response // Resurgence:1958
|
||||
Knight of Autumn:1950
|
||||
Dimir Spybug:1948
|
||||
Integrity // Intervention:1945
|
||||
Nightveil Predator:1943
|
||||
Emmara, Soul of the Accord:1942
|
||||
Luminous Bonds:1932
|
||||
Artful Takedown:1923
|
||||
Ritual of Soot:1914
|
||||
Blood Operative:1903
|
||||
Conclave Cavalier:1902
|
||||
Truefire Captain:1902
|
||||
Runaway Steam-Kin:1901
|
||||
Murmuring Mystic:1899
|
||||
Arclight Phoenix:1894
|
||||
Risk Factor:1893
|
||||
Boros Challenger:1887
|
||||
Dead Weight:1887
|
||||
Bounty of Might:1886
|
||||
Connive // Concoct:1886
|
||||
Status // Statue:1885
|
||||
Deadly Visit:1878
|
||||
Deafening Clarion:1878
|
||||
Roc Charger:1864
|
||||
Kraul Harpooner:1839
|
||||
Citywatch Sphinx:1837
|
||||
Assure // Assemble:1836
|
||||
Expansion // Explosion:1836
|
||||
Capture Sphere:1834
|
||||
Thoughtbound Phantasm:1832
|
||||
Crackling Drake:1830
|
||||
Dawn of Hope:1827
|
||||
Disinformation Campaign:1826
|
||||
House Guildmage:1824
|
||||
Quasiduplicate:1816
|
||||
Sunhome Stalwart:1815
|
||||
Skyknight Legionnaire:1805
|
||||
Darkblade Agent:1788
|
||||
Plaguecrafter:1786
|
||||
Goblin Cratermaker:1773
|
||||
Affectionate Indrik:1772
|
||||
Whisper Agent:1771
|
||||
Notion Rain:1761
|
||||
Ledev Champion:1757
|
||||
Charnel Troll:1751
|
||||
Thought Erasure:1750
|
||||
Golgari Findbroker:1749
|
||||
Chemister's Insight:1743
|
||||
Goblin Banneret:1737
|
||||
Swiftblade Vindicator:1736
|
||||
Command the Storm:1728
|
||||
Camaraderie:1726
|
||||
Wee Dragonauts:1723
|
||||
District Guide:1722
|
||||
Hypothesizzle:1715
|
||||
League Guildmage:1712
|
||||
Direct Current:1711
|
||||
Experimental Frenzy:1711
|
||||
Discovery // Dispersal:1708
|
||||
Rampaging Monument:1705
|
||||
Rosemane Centaur:1698
|
||||
Inescapable Blaze:1693
|
||||
Watery Grave:1687
|
||||
Legion Guildmage:1680
|
||||
Chamber Sentry:1674
|
||||
Inspiring Unicorn:1671
|
||||
Ionize:1669
|
||||
Flower // Flourish:1663
|
||||
Divine Visitation:1656
|
||||
Dimir Informant:1653
|
||||
Healer's Hawk:1651
|
||||
Conclave Guildmage:1648
|
||||
Sinister Sabotage:1647
|
||||
Parhelion Patrol:1640
|
||||
Ochran Assassin:1639
|
||||
Goblin Electromancer:1634
|
||||
Glowspore Shaman:1631
|
||||
Siege Wurm:1629
|
||||
Wojek Bodyguard:1629
|
||||
Hellkite Whelp:1626
|
||||
Hired Poisoner:1625
|
||||
Unexplained Disappearance:1625
|
||||
Overgrown Tomb:1624
|
||||
Prey Upon:1624
|
||||
Pitiless Gorgon:1622
|
||||
Flight of Equenauts:1621
|
||||
Hatchery Spider:1621
|
||||
Temple Garden:1621
|
||||
Beacon Bolt:1620
|
||||
Citywide Bust:1615
|
||||
Bounty Agent:1613
|
||||
Piston-Fist Cyclops:1605
|
||||
Steam Vents:1600
|
||||
Erratic Cyclops:1582
|
||||
Swarm Guildmage:1582
|
||||
Sacred Foundry:1581
|
||||
Mission Briefing:1580
|
||||
Muse Drake:1574
|
||||
Arboretum Elemental:1572
|
||||
Worldsoul Colossus:1572
|
||||
Skyline Scout:1569
|
||||
Smelt-Ward Minotaur:1568
|
||||
Burglar Rat:1561
|
||||
Whispering Snitch:1560
|
||||
Fresh-Faced Recruit:1555
|
||||
Necrotic Wound:1554
|
||||
Electrostatic Field:1541
|
||||
Disdainful Stroke:1534
|
||||
Gruesome Menagerie:1534
|
||||
Sprouting Renewal:1534
|
||||
Sonic Assault:1533
|
||||
Sure Strike:1527
|
||||
Severed Strands:1522
|
||||
Beamsplitter Mage:1521
|
||||
Chromatic Lantern:1516
|
||||
Ledev Guardian:1510
|
||||
Radical Idea:1502
|
||||
Pilfering Imp:1500
|
||||
Vernadi Shieldmate:1497
|
||||
Ornery Goblin:1495
|
||||
Gatekeeper Gargoyle:1489
|
||||
Barging Sergeant:1484
|
||||
Blade Instructor:1483
|
||||
Rhizome Lurcher:1481
|
||||
Invert // Invent:1477
|
||||
Ironshell Beetle:1477
|
||||
Generous Stray:1474
|
||||
Demotion:1469
|
||||
Might of the Masses:1468
|
||||
Molderhulk:1467
|
||||
Selective Snare:1466
|
||||
Hammer Dropper:1463
|
||||
Swathcutter Giant:1462
|
||||
Firemind's Research:1460
|
||||
Devkarin Dissident:1459
|
||||
Mnemonic Betrayal:1459
|
||||
Vigorspore Wurm:1459
|
||||
Haazda Marshal:1457
|
||||
Lotleth Giant:1455
|
||||
Righteous Blow:1451
|
||||
Fire Urchin:1446
|
||||
Gird for Battle:1441
|
||||
Kraul Swarm:1437
|
||||
Veiled Shade:1437
|
||||
Centaur Peacemaker:1434
|
||||
Golgari Raiders:1434
|
||||
Passwall Adept:1434
|
||||
Sworn Companions:1434
|
||||
Erstwhile Trooper:1432
|
||||
Hunted Witness:1431
|
||||
Kraul Foragers:1431
|
||||
Collar the Culprit:1427
|
||||
Mausoleum Secrets:1424
|
||||
Take Heart:1424
|
||||
Dazzling Lights:1419
|
||||
Rubblebelt Boar:1418
|
||||
Sumala Woodshaper:1418
|
||||
Intrusive Packbeast:1416
|
||||
Loxodon Restorer:1415
|
||||
Omnispell Adept:1415
|
||||
Spinal Centipede:1415
|
||||
Glaive of the Guildpact:1414
|
||||
Vivid Revival:1410
|
||||
Douser of Lights:1409
|
||||
Devious Cover-Up:1404
|
||||
Chance for Glory:1402
|
||||
Child of Night:1402
|
||||
Enhanced Surveillance:1399
|
||||
Hitchclaw Recluse:1398
|
||||
Mephitic Vapors:1395
|
||||
Circuitous Route:1389
|
||||
Cosmotronic Wave:1389
|
||||
Leapfrog:1379
|
||||
Goblin Locksmith:1377
|
||||
Guildmages' Forum:1370
|
||||
Guild Summit:1368
|
||||
Bartizan Bats:1367
|
||||
Undercity Uprising:1363
|
||||
Thousand-Year Storm:1355
|
||||
Drowned Secrets:1349
|
||||
Boros Guildgate :1345
|
||||
Grappling Sundew:1344
|
||||
Boros Guildgate :1343
|
||||
Tenth District Guard:1342
|
||||
Izzet Guildgate :1338
|
||||
Crushing Canopy:1335
|
||||
Portcullis Vine:1333
|
||||
Undercity Necrolisk:1332
|
||||
Dimir Guildgate :1331
|
||||
Barrier of Bones:1327
|
||||
Wild Ceratok:1327
|
||||
Izzet Guildgate :1326
|
||||
Gravitic Punch:1320
|
||||
Silent Dart:1310
|
||||
Wary Okapi:1309
|
||||
Pack's Favor:1307
|
||||
Garrison Sergeant:1303
|
||||
Vedalken Mesmerist:1303
|
||||
Golgari Guildgate :1295
|
||||
Golgari Guildgate :1286
|
||||
Dimir Guildgate :1280
|
||||
Maniacal Rage:1280
|
||||
Selesnya Guildgate :1280
|
||||
Urban Utopia:1278
|
||||
Wall of Mist:1273
|
||||
Maximize Altitude:1268
|
||||
Join Shields:1267
|
||||
Selesnya Guildgate :1266
|
||||
Book Devourer:1263
|
||||
Wishcoin Crab:1262
|
||||
Narcomoeba:1257
|
||||
Crush Contraband:1248
|
||||
Gateway Plaza:1248
|
||||
Fearless Halberdier:1246
|
||||
Torch Courier:1242
|
||||
Candlelight Vigil:1241
|
||||
Moodmark Painter:1230
|
||||
Creeping Chill:1218
|
||||
Izzet Locket:1217
|
||||
Dimir Locket:1202
|
||||
Maximize Velocity:1200
|
||||
Unmoored Ego:1184
|
||||
Never Happened:1175
|
||||
Golgari Locket:1173
|
||||
Selesnya Locket:1154
|
||||
Boros Locket:1128
|
||||
Street Riot:1110
|
||||
Vicious Rumors:1101
|
||||
Pause for Reflection:1089
|
||||
Wand of Vertebrae:1073
|
|
|
@ -0,0 +1,184 @@
|
|||
The Scarab God:2272
|
||||
Angel of Condemnation:2079
|
||||
The Locust God:2077
|
||||
The Scorpion God:2048
|
||||
Pride Sovereign:2046
|
||||
Crested Sunmare:1996
|
||||
Nicol Bolas, God-Pharaoh:1965
|
||||
Majestic Myriarch:1915
|
||||
Neheb, the Eternal:1906
|
||||
Hour of Devastation:1901
|
||||
Adorned Pouncer:1889
|
||||
Ammit Eternal:1881
|
||||
Samut, the Tested:1874
|
||||
Razaketh, the Foulblooded:1856
|
||||
Grind // Dust:1855
|
||||
Resilient Khenra:1832
|
||||
Sand Strangler:1822
|
||||
Ramunap Hydra:1818
|
||||
Abrade:1816
|
||||
Desert’s Hold:1813
|
||||
Champion of Wits:1810
|
||||
Bontu’s Last Reckoning:1807
|
||||
Nimble Obstructionist:1796
|
||||
Chaos Maw:1788
|
||||
Sifter Wurm:1783
|
||||
Unesh, Criosphinx Sovereign:1776
|
||||
Hour of Glory:1771
|
||||
River Hoopoe:1769
|
||||
Ominous Sphinx:1754
|
||||
Torment of Hailfire:1754
|
||||
Open Fire:1751
|
||||
Torment of Venom:1743
|
||||
Dreamstealer:1740
|
||||
Struggle // Survive:1737
|
||||
Burning-Fist Minotaur:1734
|
||||
Ambuscade:1732
|
||||
God-Pharaoh’s Gift:1731
|
||||
Accursed Horde:1729
|
||||
Doomfall:1727
|
||||
Earthshaker Khenra:1716
|
||||
Aerial Guide:1711
|
||||
Khenra Scrapper:1709
|
||||
Oketra’s Avenger:1691
|
||||
Bloodwater Entity:1689
|
||||
Rhonas’s Last Stand:1686
|
||||
Angel of the God-Pharaoh:1685
|
||||
Tenacious Hunter:1685
|
||||
Hour of Promise:1684
|
||||
Eternal of Harsh Truths:1680
|
||||
Fervent Paincaster:1677
|
||||
Lethal Sting:1673
|
||||
Vizier of the Anointed:1673
|
||||
Wildfire Eternal:1671
|
||||
Puncturing Blow:1668
|
||||
Sandblast:1668
|
||||
Sunscourge Champion:1661
|
||||
Spellweaver Eternal:1656
|
||||
Vizier of the True:1656
|
||||
Banewhip Punisher:1652
|
||||
Kefnet’s Last Word:1652
|
||||
Merciless Eternal:1648
|
||||
Vile Manifestation:1647
|
||||
Bitterbow Sharpshooters:1646
|
||||
Driven // Despair:1643
|
||||
Supreme Will:1638
|
||||
Hour of Revelation:1637
|
||||
Torment of Scarabs:1637
|
||||
Oasis Ritualist:1636
|
||||
Farm // Market:1628
|
||||
Unraveling Mummy:1628
|
||||
Obelisk Spider:1617
|
||||
Mirage Mirror:1615
|
||||
Manticore Eternal:1613
|
||||
Resolute Survivors:1610
|
||||
Ruin Rat:1610
|
||||
Overwhelming Splendor:1608
|
||||
Unconventional Tactics:1608
|
||||
Hour of Eternity:1606
|
||||
Devotee of Strength:1605
|
||||
Sinuous Striker:1604
|
||||
Sunset Pyramid:1602
|
||||
Riddleform:1600
|
||||
Solitary Camel:1600
|
||||
Harrier Naga:1598
|
||||
Steward of Solidarity:1597
|
||||
Sidewinder Naga:1595
|
||||
Dauntless Aven:1591
|
||||
Feral Prowler:1591
|
||||
Thorned Moloch:1586
|
||||
Striped Riverwinder:1584
|
||||
Frontline Devastator:1580
|
||||
Appeal // Authority:1578
|
||||
Aven of Enduring Hope:1577
|
||||
Mummy Paramount:1571
|
||||
Uncage the Menagerie:1570
|
||||
Consign // Oblivion:1564
|
||||
Hollow One:1561
|
||||
Aven Reedstalker:1560
|
||||
Rhonas’s Stalwart:1559
|
||||
Unsummon:1557
|
||||
Desert of the Glorified:1556
|
||||
Manalith:1555
|
||||
Hope Tender:1551
|
||||
Granitic Titan:1550
|
||||
Ifnir Deadlands:1550
|
||||
Blur of Blades:1547
|
||||
Marauding Boneslasher:1547
|
||||
Shefet Dunes:1547
|
||||
Claim // Fame:1545
|
||||
Magmaroth:1545
|
||||
Beneath the Sands:1543
|
||||
Ramunap Excavator:1542
|
||||
Desert of the Mindful:1541
|
||||
Khenra Eternal:1541
|
||||
Reason // Believe:1541
|
||||
Rampaging Hippo:1540
|
||||
Unquenchable Thirst:1539
|
||||
Razaketh’s Rite:1537
|
||||
Saving Grace:1532
|
||||
Steadfast Sentinel:1531
|
||||
Wall of Forgotten Pharaohs:1531
|
||||
Imminent Doom:1530
|
||||
Defiant Khenra:1526
|
||||
Cunning Survivor:1525
|
||||
Ramunap Ruins:1525
|
||||
Hashep Oasis:1524
|
||||
Overcome:1523
|
||||
Abandoned Sarcophagus:1514
|
||||
Carrion Screecher:1514
|
||||
Firebrand Archer:1510
|
||||
Frilled Sandwalla:1507
|
||||
Hazoret’s Undying Fury:1505
|
||||
Inferno Jet:1499
|
||||
Crypt of the Eternals:1496
|
||||
Gift of Strength:1495
|
||||
Kindled Fury:1493
|
||||
Ipnu Rivulet:1492
|
||||
Act of Heroism:1491
|
||||
Without Weakness:1489
|
||||
Desert of the Indomitable:1487
|
||||
Fraying Sanity:1485
|
||||
Hostile Desert:1484
|
||||
Traveler’s Amulet:1482
|
||||
God-Pharaoh’s Faithful:1477
|
||||
Desert of the Fervent:1476
|
||||
Apocalypse Demon:1474
|
||||
Wretched Camel:1472
|
||||
Dagger of the Worthy:1468
|
||||
Refuse // Cooperate:1468
|
||||
Quarry Beetle:1464
|
||||
Countervailing Winds:1460
|
||||
Gilded Cerodon:1455
|
||||
Djeru, With Eyes Open:1450
|
||||
Strategic Planning:1450
|
||||
Tragic Lesson:1449
|
||||
Scrounger of Souls:1447
|
||||
Dune Diviner:1438
|
||||
Desert of the True:1436
|
||||
Chandra’s Defeat:1433
|
||||
Proven Combatant:1430
|
||||
Survivors’ Encampment:1427
|
||||
Djeru’s Renunciation:1425
|
||||
Disposal Mummy:1422
|
||||
Imaginary Threats:1418
|
||||
Moaning Wall:1416
|
||||
Dutiful Servants:1403
|
||||
Oketra’s Last Mercy:1403
|
||||
Crash Through:1400
|
||||
Lurching Rotbeast:1397
|
||||
Swarm Intelligence:1397
|
||||
Life Goes On:1395
|
||||
Grisly Survivor:1388
|
||||
Dunes of the Dead:1381
|
||||
Jace’s Defeat:1369
|
||||
Endless Sands:1367
|
||||
Seer of the Last Tomorrow:1360
|
||||
Graven Abomination:1352
|
||||
Gideon’s Defeat:1346
|
||||
Liliana’s Defeat:1345
|
||||
Leave // Chance:1324
|
||||
Solemnity:1265
|
||||
Scavenger Grounds:1256
|
||||
Crook of Condemnation:1228
|
||||
Nissa’s Defeat:1185
|
|
|
@ -0,0 +1,249 @@
|
|||
Consecrated Sphinx:2182
|
||||
Ancestral Vision:2144
|
||||
Archangel of Thune:2141
|
||||
Elesh Norn, Grand Cenobite:2135
|
||||
Mana Drain:2124
|
||||
Urabrask the Hidden:2107
|
||||
Sheoldred, Whispering One:2106
|
||||
Swords to Plowshares:2106
|
||||
Primeval Titan:2103
|
||||
Ob Nixilis, the Fallen:2081
|
||||
Doom Blade:2064
|
||||
Rampaging Baloths:2056
|
||||
Thundermaw Hellkite:2053
|
||||
Restoration Angel:2044
|
||||
Keiga, the Tide Star:2042
|
||||
Avacyn, Angel of Hope:2029
|
||||
Kiki-Jiki, Mirror Breaker:2024
|
||||
Kokusho, the Evening Star:2020
|
||||
Cryptic Command:2012
|
||||
Supreme Verdict:2002
|
||||
Genesis Hydra:2001
|
||||
Fireball:2000
|
||||
Emeria Angel:1992
|
||||
Austere Command:1969
|
||||
Blood Baron of Vizkopa:1968
|
||||
Lotus Cobra:1955
|
||||
Sphinx of Uthuun:1927
|
||||
Yosei, the Morning Star:1924
|
||||
Rift Bolt:1912
|
||||
Scourge of Valkas:1909
|
||||
Bogardan Hellkite:1907
|
||||
Ryusei, the Falling Star:1907
|
||||
Spiritmonger:1900
|
||||
Vorinclex, Voice of Hunger:1897
|
||||
Indulgent Tormentor:1888
|
||||
Heroes’ Bane:1885
|
||||
Jugan, the Rising Star:1877
|
||||
Simic Sky Swallower:1874
|
||||
Serra Angel:1873
|
||||
Grisly Spectacle:1865
|
||||
Rune-Scarred Demon:1864
|
||||
Channel:1861
|
||||
Hypersonic Dragon:1856
|
||||
Lightning Helix:1856
|
||||
Teferi, Mage of Zhalfir:1854
|
||||
Knight of the Reliquary:1848
|
||||
Thran Dynamo:1848
|
||||
Thoughtseize:1839
|
||||
Anger of the Gods:1836
|
||||
Savageborn Hydra:1829
|
||||
Charmbreaker Devils:1828
|
||||
Staggershock:1824
|
||||
Malfegor:1812
|
||||
Palladium Myr:1808
|
||||
Draconic Roar:1796
|
||||
Ulcerate:1795
|
||||
Heat Ray:1794
|
||||
Mahamoti Djinn:1793
|
||||
Hoarding Dragon:1786
|
||||
Corpsejack Menace:1783
|
||||
Abyssal Persecutor:1774
|
||||
Firemane Angel:1771
|
||||
Curse of Predation:1766
|
||||
Electrolyze:1754
|
||||
Reave Soul:1754
|
||||
Oblivion Stone:1744
|
||||
Overgrown Battlement:1738
|
||||
Claustrophobia:1736
|
||||
Obstinate Baloth:1732
|
||||
Blizzard Specter:1724
|
||||
Pillar of Flame:1724
|
||||
Wall of Roots:1723
|
||||
Undercity Troll:1721
|
||||
Cephalid Broker:1717
|
||||
Abzan Battle Priest:1716
|
||||
Abzan Falconer:1698
|
||||
Mind Stone:1697
|
||||
Illusory Ambusher:1691
|
||||
Fog Bank:1690
|
||||
Mana Leak:1689
|
||||
Genesis Wave:1686
|
||||
Condescend:1685
|
||||
Rosheen Meanderer:1682
|
||||
Aether Vial:1681
|
||||
Wing Shards:1680
|
||||
Bladewing the Risen:1677
|
||||
Vizkopa Guildmage:1671
|
||||
Aetherize:1669
|
||||
Bloodghast:1667
|
||||
Horizon Canopy:1662
|
||||
Noxious Dragon:1661
|
||||
Seeker of the Way:1657
|
||||
Azorius Charm:1650
|
||||
Topan Freeblade:1650
|
||||
Ajani’s Pridemate:1649
|
||||
Guttersnipe:1648
|
||||
Orzhov Basilica:1648
|
||||
Necropotence:1645
|
||||
Prodigal Pyromancer:1641
|
||||
Monastery Swiftspear:1639
|
||||
Phantom Monster:1637
|
||||
Search for Tomorrow:1637
|
||||
Phyrexian Rager:1630
|
||||
Frost Lynx:1624
|
||||
Carven Caryatid:1621
|
||||
Hunt the Weak:1621
|
||||
Izzet Boilerworks:1620
|
||||
Blinding Mage:1616
|
||||
Amass the Components:1610
|
||||
Iona’s Judgment:1605
|
||||
Repeal:1602
|
||||
Serra Ascendant:1601
|
||||
Star Compass:1600
|
||||
Kiln Fiend:1597
|
||||
Simic Growth Chamber:1596
|
||||
Auriok Champion:1592
|
||||
Illusory Angel:1588
|
||||
Day of the Dragons:1587
|
||||
Jungle Barrier:1586
|
||||
Rakdos Carnarium:1586
|
||||
Dimir Aqueduct:1575
|
||||
Golgari Rot Farm:1572
|
||||
Jin-Gitaxias, Core Augur:1570
|
||||
Bladewing’s Thrall:1562
|
||||
Mnemonic Wall:1562
|
||||
Ainok Bond-Kin:1561
|
||||
Crowned Ceratok:1556
|
||||
Jhessian Thief:1555
|
||||
Boros Garrison:1551
|
||||
Selesnya Sanctuary:1551
|
||||
Grove of the Burnwillows:1547
|
||||
Chronicler of Heroes:1546
|
||||
Glimpse the Unthinkable:1543
|
||||
Manakin:1537
|
||||
Riverwheel Aerialists:1531
|
||||
Guardian Idol:1525
|
||||
Assault Formation:1520
|
||||
Graven Cairns:1520
|
||||
Mer-Ek Nightblade:1519
|
||||
Stalwart Aven:1518
|
||||
Netcaster Spider:1516
|
||||
Angelic Accord:1514
|
||||
Doomed Traveler:1514
|
||||
Thrill-Kill Assassin:1514
|
||||
Distortion Strike:1511
|
||||
Azorius Chancery:1509
|
||||
Skywise Teachings:1503
|
||||
Borderland Marauder:1497
|
||||
Sustainer of the Realm:1495
|
||||
Furnace Whelp:1494
|
||||
Sultai Flayer:1493
|
||||
Ivy Elemental:1490
|
||||
Darksteel Axe:1487
|
||||
Gruul Turf:1486
|
||||
Path of Bravery:1485
|
||||
Wight of Precinct Six:1480
|
||||
Dissolve:1477
|
||||
Doorkeeper:1476
|
||||
Evolving Wilds:1472
|
||||
Keldon Halberdier:1468
|
||||
Foul-Tongue Invocation:1465
|
||||
Durkwood Baloth:1462
|
||||
Nantuko Shaman:1462
|
||||
Vent Sentinel:1461
|
||||
Scion of Ugin:1460
|
||||
Splatter Thug:1459
|
||||
Mishra’s Bauble:1458
|
||||
Child of Night:1454
|
||||
Ojutai’s Breath:1454
|
||||
Night of Souls’ Betrayal:1449
|
||||
Greater Basilisk:1448
|
||||
Butcher’s Glee:1446
|
||||
Surreal Memoir:1443
|
||||
Magus of the Moon:1438
|
||||
Battle-Rattle Shaman:1435
|
||||
Guard Duty:1429
|
||||
Sandstone Oracle:1426
|
||||
Enlarge:1425
|
||||
Jace’s Phantasm:1425
|
||||
Pristine Talisman:1424
|
||||
Duskdale Wurm:1423
|
||||
Elusive Spellfist:1423
|
||||
Dragon Egg:1421
|
||||
Flusterstorm:1421
|
||||
Kolaghan Monument:1415
|
||||
Balustrade Spy:1410
|
||||
Dragon Bell Monk:1407
|
||||
Student of Ojutai:1407
|
||||
Dragon Tempest:1406
|
||||
Angel of Mercy:1405
|
||||
Dragonloft Idol:1395
|
||||
Sanguine Bond:1394
|
||||
Dead Reveler:1393
|
||||
Wrench Mind:1393
|
||||
Diminish:1392
|
||||
Wildsize:1392
|
||||
Windfall:1392
|
||||
Guided Strike:1391
|
||||
Survival Cache:1391
|
||||
Lord of the Pit:1390
|
||||
Nimbus Maze:1390
|
||||
Rakdos Drake:1384
|
||||
Phantom Tiger:1381
|
||||
River of Tears:1381
|
||||
Moonglove Extract:1380
|
||||
Timberland Guide:1378
|
||||
Trepanation Blade:1378
|
||||
Burrenton Forge-Tender:1376
|
||||
Virulent Swipe:1376
|
||||
Hunting Pack:1367
|
||||
Fury Charm:1364
|
||||
Infantry Veteran:1360
|
||||
Coordinated Assault:1356
|
||||
Jaddi Offshoot:1353
|
||||
Inspiring Call:1350
|
||||
Shriekgeist:1349
|
||||
Thought Scour:1345
|
||||
Pentarch Ward:1344
|
||||
Bogbrew Witch:1343
|
||||
Tavern Swindler:1342
|
||||
Prey’s Vengeance:1341
|
||||
Serum Powder:1340
|
||||
Rotfeaster Maggot:1338
|
||||
Emerge Unscathed:1322
|
||||
Lead the Stampede:1322
|
||||
Bala Ged Scorpion:1321
|
||||
Dragonlord’s Servant:1321
|
||||
Great Teacher’s Decree:1313
|
||||
Eternal Thirst:1312
|
||||
Hammerhand:1302
|
||||
Haunting Hymn:1301
|
||||
Festering Newt:1287
|
||||
Tormenting Voice:1286
|
||||
Earth Elemental:1278
|
||||
Benevolent Ancestor:1264
|
||||
Trumpet Blast:1253
|
||||
Bewilder:1252
|
||||
Mark of Mutiny:1245
|
||||
Crucible of Fire:1242
|
||||
Bubbling Cauldron:1241
|
||||
Duress:1236
|
||||
Lure:1228
|
||||
Mindcrank:1225
|
||||
Radiant Fountain:1224
|
||||
Disenchant:1215
|
||||
Runed Servitor:1213
|
||||
Aerial Predation:1196
|
||||
Shimmering Grotto:1163
|
||||
Nature’s Claim:1137
|
|
|
@ -0,0 +1,274 @@
|
|||
Sword of Feast and Famine:100
|
||||
Chandra, Torch of Defiance:99
|
||||
Skysovereign, Consul Flagship:98
|
||||
Noxious Gearhulk:97
|
||||
Sword of Fire and Ice:96
|
||||
Angel of Invention:95
|
||||
Verdurous Gearhulk:94
|
||||
Demon of Dark Schemes:94
|
||||
Sol Ring:93
|
||||
Cataclysmic Gearhulk:92
|
||||
Torrential Gearhulk:92
|
||||
Nissa, Vital Force:91
|
||||
Hangarback Walker:90
|
||||
Gonti, Lord of Luxury:90
|
||||
Steel Overseer:89
|
||||
Skyship Stalker:89
|
||||
Pia Nalaar:88
|
||||
Sword of Light and Shadow:88
|
||||
Smuggler's Copter:87
|
||||
Confiscation Coup:87
|
||||
Combustible Gearhulk:86
|
||||
Oviya Pashiri, Sage Lifecrafte:86
|
||||
Mana Crypt:86
|
||||
Solemn Simulacrum:85
|
||||
Mana Vault:85
|
||||
Harnessed Lightning:84
|
||||
Aetherstorm Roc:84
|
||||
Cultivator's Caravan:84
|
||||
Fairgrounds Warden:83
|
||||
Rashmi, Eternities Crafter:83
|
||||
Dovin Baan:83
|
||||
Aerial Responder:82
|
||||
Saheeli's Artistry:82
|
||||
Bristling Hydra:82
|
||||
Master Trinketeer:81
|
||||
Welding Sparks:81
|
||||
Cultivator of Blades:81
|
||||
Aethersquall Ancient:80
|
||||
Longtusk Cub:80
|
||||
Unlicensed Disintegration:80
|
||||
Snare Thopter:79
|
||||
Fleetwheel Cruiser:79
|
||||
Depala, Pilot Exemplar:79
|
||||
Multiform Wonder:79
|
||||
Cloudblazer:78
|
||||
Filigree Familiar:78
|
||||
Gauntlet of Power:78
|
||||
Skywhaler's Shot:78
|
||||
Renegade Freighter:77
|
||||
Fumigate:77
|
||||
Chromatic Lantern:77
|
||||
Champion's Helm:77
|
||||
Revoke Privileges:76
|
||||
Peema Outrider:76
|
||||
Arborback Stomper:76
|
||||
Architect of the Untamed:76
|
||||
Tidy Conclusion:75
|
||||
Servant of the Conduit:75
|
||||
Aetherborn Marauder:75
|
||||
Essence Extraction:75
|
||||
Saheeli Rai:74
|
||||
Chief of the Foundry:74
|
||||
Syndicate Trafficker:74
|
||||
Lathnu Hellion:74
|
||||
Bomat Bazaar Barge:73
|
||||
Visionary Augmenter:73
|
||||
Foundry Inspector:73
|
||||
Wispweaver Angel:73
|
||||
Gearshift Ace:73
|
||||
Mox Opal:72
|
||||
Key to the City:72
|
||||
Furious Reprisal:72
|
||||
Captured by the Consulate:72
|
||||
Scrapheap Scrounger:71
|
||||
Aethertorch Renegade:71
|
||||
Die Young:71
|
||||
Whirler Virtuoso:71
|
||||
Animation Module:71
|
||||
Æther Vial:70
|
||||
Marionette Master:70
|
||||
Nature's Way:70
|
||||
Chandra's Pyrohelix:70
|
||||
Long-Finned Skywhale:70
|
||||
Aether Meltdown:69
|
||||
Restoration Gearsmith:69
|
||||
Empyreal Voyager:69
|
||||
Ovalchase Daredevil:69
|
||||
Thriving Rhino:69
|
||||
Hunt the Weak:68
|
||||
Veteran Motorist:68
|
||||
Voltaic Brawler:68
|
||||
Lightning Greaves:68
|
||||
Dynavolt Tower:68
|
||||
Scroll Rack:67
|
||||
Padeem, Consul of Innovation:67
|
||||
Shrewd Negotiation:67
|
||||
Propeller Pioneer:67
|
||||
Kambal, Consul of Allocation:67
|
||||
Malfunction:66
|
||||
Brazen Scourge:66
|
||||
Chrome Mox:66
|
||||
Ballista Charger:66
|
||||
Sculpting Steel:66
|
||||
Glint-Sleeve Artisan:66
|
||||
Gearseeker Serpent:65
|
||||
Glint-Nest Crane:65
|
||||
Armorcraft Judge:65
|
||||
Thriving Grubs:65
|
||||
Sky Skiff:65
|
||||
Speedway Fanatic:64
|
||||
Riparian Tiger:64
|
||||
Underhanded Designs:64
|
||||
Kujar Seedsculptor:64
|
||||
Maulfist Doorbuster:64
|
||||
Subtle Strike:64
|
||||
Mind's Eye:63
|
||||
Impeccable Timing:63
|
||||
Spontaneous Artist:63
|
||||
Foundry Screecher:63
|
||||
Elegant Edgecrafters:63
|
||||
Weaponcraft Enthusiast:62
|
||||
Contraband Kingpin:62
|
||||
Consul's Shieldguard:62
|
||||
Glimmer of Genius:62
|
||||
Eliminate the Competition:62
|
||||
Metalwork Colossus:62
|
||||
Aetherworks Marvel:61
|
||||
Aviary Mechanic:61
|
||||
Aether Hub:61
|
||||
Fateful Showdown:61
|
||||
Prophetic Prism:61
|
||||
Experimental Aviator:60
|
||||
Metallurgic Summonings:60
|
||||
Aether Theorist:60
|
||||
Rings of Brighthearth:60
|
||||
Toolcraft Exemplar:60
|
||||
Attune with Aether:60
|
||||
Thriving Ibex:59
|
||||
Narnam Cobra:59
|
||||
Quicksmith Genius:59
|
||||
Fabrication Module:59
|
||||
Lotus Petal:59
|
||||
Thriving Rats:58
|
||||
Insidious Will:58
|
||||
Embraal Bruiser:58
|
||||
Maulfist Squad:58
|
||||
Dhund Operative:58
|
||||
Cloudstone Curio:58
|
||||
Salivating Gremlins:57
|
||||
Janjeet Sentry:57
|
||||
Static Orb:57
|
||||
Era of Innovation:57
|
||||
Fairgrounds Trumpeter:57
|
||||
Wind Drake:56
|
||||
Lawless Broker:56
|
||||
Ovalchase Dragster:56
|
||||
Fragmentize:56
|
||||
Blossoming Defense:56
|
||||
Built to Last:56
|
||||
Territorial Gorger:55
|
||||
Skyswirl Harrier:55
|
||||
Rush of Vitality:55
|
||||
Wild Wanderer:55
|
||||
Deadlock Trap:55
|
||||
Spireside Infiltrator:54
|
||||
Durable Handicraft:54
|
||||
Prakhata Pillar-Bug:54
|
||||
Dukhara Peafowl:54
|
||||
Sage of Shaila's Claim:54
|
||||
Incendiary Sabotage:54
|
||||
Weldfast Monitor:53
|
||||
Trusty Companion:53
|
||||
Iron League Steed:53
|
||||
Spark of Creativity:53
|
||||
Self-Assembler:53
|
||||
Make Obsolete:52
|
||||
Select for Inspection:52
|
||||
Live Fast:52
|
||||
Ambitious Aetherborn:52
|
||||
Thriving Turtle:52
|
||||
Nimble Innovator:51
|
||||
Eager Construct:51
|
||||
Servo Exhibition:51
|
||||
Appetite for the Unnatural:51
|
||||
Midnight Oil:51
|
||||
Eddytrail Hawk:50
|
||||
Æther Tradewinds:50
|
||||
Reckless Fireweaver:50
|
||||
Weldfast Wingsmith:50
|
||||
Ghirapur Guide:50
|
||||
Electrostatic Pummeler:49
|
||||
Painter's Servant:49
|
||||
Bastion Mastodon:49
|
||||
Highspire Artisan:49
|
||||
Cathartic Reunion:49
|
||||
Wayward Giant:48
|
||||
Acrobatic Maneuver:48
|
||||
Crucible of Worlds:48
|
||||
Built to Smash:48
|
||||
Prakhata Club Security:47
|
||||
Vedalken Blademaster:47
|
||||
Panharmonicon:47
|
||||
Decoction Module:47
|
||||
Inventor's Apprentice:47
|
||||
Fretwork Colony:46
|
||||
Hightide Hermit:46
|
||||
Spirebluff Canal:46
|
||||
Botanical Sanctum:46
|
||||
Blooming Marsh:45
|
||||
Whirlermaker:45
|
||||
Concealed Courtyard:45
|
||||
Wildest Dreams:45
|
||||
Tezzeret's Ambition:44
|
||||
Ninth Bridge Patrol:44
|
||||
Metalspinner's Puzzleknot:44
|
||||
Inspiring Vantage:44
|
||||
Ruinous Gremlin:43
|
||||
Inventors' Fair:43
|
||||
Herald of the Fair:43
|
||||
Hazardous Conditions:43
|
||||
Glassblower's Puzzleknot:42
|
||||
Hijack:42
|
||||
Engineered Might:42
|
||||
Bomat Courier:42
|
||||
Night Market Lookout:41
|
||||
Inventor's Goggles:41
|
||||
Cowl Prowler:41
|
||||
Dukhara Scavenger:41
|
||||
Ornamental Courage:40
|
||||
Fortuitous Find:40
|
||||
Demolition Stomper:40
|
||||
Cogworker's Puzzleknot:39
|
||||
Creeping Mold:39
|
||||
Aradara Express:39
|
||||
Minister of Inquiries:38
|
||||
Harsh Scrutiny:38
|
||||
Accomplished Automaton:38
|
||||
Woodweaver's Puzzleknot:37
|
||||
Failed Inspection:37
|
||||
Diabolic Tutor:37
|
||||
Consulate Skygate:36
|
||||
Refurbish:36
|
||||
Disappearing Act:36
|
||||
Pressure Point:35
|
||||
Authority of the Consuls:35
|
||||
Workshop Assistant:34
|
||||
Inspired Charge:34
|
||||
Take Down:34
|
||||
Renegade Tactics:33
|
||||
Larger Than Life:33
|
||||
Revolutionary Rebuff:32
|
||||
Ceremonious Rejection:32
|
||||
Torch Gauntlet:31
|
||||
Fireforger's Puzzleknot:31
|
||||
Morbid Curiosity:30
|
||||
Ghirapur Orrery:30
|
||||
Paradoxical Outcome:29
|
||||
Curio Vendor:28
|
||||
Aetherflux Reservoir:28
|
||||
Start Your Engines:27
|
||||
Terror of the Fairgrounds:26
|
||||
Demolish:26
|
||||
Wily Bandar:25
|
||||
Consulate Surveillance:24
|
||||
Giant Spectacle:23
|
||||
Mind Rot:22
|
||||
Lost Legacy:21
|
||||
Commencement of Festivities:20
|
||||
Sequestered Stash:18
|
||||
Madcap Experiment:16
|
||||
Tasseled Dromedary:14
|
||||
Dramatic Reversal:11
|
||||
Perpetual Timepiece:6
|
||||
Dubious Challenge:0
|
|
|
@ -0,0 +1,260 @@
|
|||
Resplendent Angel:2323
|
||||
Tezzeret, Artifice Master:2297
|
||||
Ajani, Adversary of Tyrants:2268
|
||||
Vivien Reid:2257
|
||||
Nicol Bolas, the Ravager:2210
|
||||
Bone Dragon:2163
|
||||
Demanding Dragon:2122
|
||||
Murder:2118
|
||||
Banefire:2116
|
||||
Lathliss, Dragon Queen:2111
|
||||
Djinn of Wishes:2092
|
||||
Isareth the Awakener:2083
|
||||
Demon of Catastrophes:2078
|
||||
Leonin Warleader:2036
|
||||
Hieromancer's Cage:2031
|
||||
Lightning Strike:2030
|
||||
Goreclaw, Terror of Qal Sisma:1990
|
||||
Angel of the Dawn:1965
|
||||
Vine Mare:1962
|
||||
Cleansing Nova:1957
|
||||
Luminous Bonds:1957
|
||||
Hungering Hydra:1956
|
||||
Pelakka Wurm:1948
|
||||
Palladia-Mors, the Ruiner:1940
|
||||
Thorn Lieutenant:1931
|
||||
Rabid Bite:1929
|
||||
Dismissive Pyromancer:1919
|
||||
Lena, Selfless Champion:1914
|
||||
Herald of Faith:1911
|
||||
Sigiled Sword of Valeron:1906
|
||||
Vaevictis Asmadi, the Dire:1898
|
||||
Lich's Caress:1895
|
||||
Graveyard Marshal:1885
|
||||
Pegasus Courser:1878
|
||||
Chromium, the Mutable:1875
|
||||
Volcanic Dragon:1869
|
||||
Mentor of the Meek:1866
|
||||
Vampire Sovereign:1860
|
||||
Valiant Knight:1855
|
||||
Poison-Tip Archer:1851
|
||||
Spit Flame:1851
|
||||
Windreader Sphinx:1846
|
||||
Death Baron:1844
|
||||
Skyrider Patrol:1844
|
||||
Shock:1841
|
||||
Regal Bloodlord:1840
|
||||
Ajani's Pridemate:1836
|
||||
Psychic Symbiont:1833
|
||||
Liliana, Untouched by Death:1825
|
||||
Exclusion Mage:1824
|
||||
Star-Crowned Stag:1823
|
||||
Sleep:1817
|
||||
Heroic Reinforcements:1805
|
||||
Patient Rebuilding:1804
|
||||
Druid of the Cowl:1790
|
||||
Horizon Scholar:1784
|
||||
Skymarch Bloodletter:1777
|
||||
Sarkhan, Fireblood:1776
|
||||
Runic Armasaur:1774
|
||||
Prodigious Growth:1773
|
||||
Take Vengeance:1772
|
||||
Aven Wind Mage:1770
|
||||
Dryad Greenseeker:1761
|
||||
Electrify:1751
|
||||
Sarkhan's Unsealing:1743
|
||||
Plague Mare:1739
|
||||
Gallant Cavalry:1736
|
||||
Mystic Archaeologist:1724
|
||||
Draconic Disciple:1723
|
||||
Essence Scatter:1723
|
||||
Vigilant Baloth:1719
|
||||
Skeleton Archer:1717
|
||||
Arcades, the Strategist:1715
|
||||
Militia Bugler:1715
|
||||
Departed Deckhand:1713
|
||||
Fell Specter:1708
|
||||
Strangling Spores:1703
|
||||
Bristling Boar:1699
|
||||
Snapping Drake:1693
|
||||
Enigma Drake:1692
|
||||
Knightly Valor:1692
|
||||
Gravedigger:1690
|
||||
Sai, Master Thopterist:1688
|
||||
Aviation Pioneer:1685
|
||||
Skyscanner:1683
|
||||
Shield Mare:1680
|
||||
Meteor Golem:1674
|
||||
Sparktongue Dragon:1673
|
||||
Brawl-Bash Ogre:1667
|
||||
Remorseful Cleric:1666
|
||||
Sift:1663
|
||||
Fiery Finish:1654
|
||||
Transmogrifying Wand:1653
|
||||
Aerial Engineer:1649
|
||||
Cavalry Drillmaster:1648
|
||||
Ghastbark Twins:1645
|
||||
Reclamation Sage:1640
|
||||
Ajani's Last Stand:1637
|
||||
Metamorphic Alteration:1634
|
||||
Mirror Image:1633
|
||||
Omenspeaker:1633
|
||||
Vivien's Invocation:1633
|
||||
Dark-Dweller Oracle:1630
|
||||
Boggart Brute:1628
|
||||
Dwindle:1625
|
||||
Goblin Trashmaster:1625
|
||||
Make a Stand:1624
|
||||
Liliana's Contract:1623
|
||||
Giant Spider:1622
|
||||
Open the Graves:1621
|
||||
Colossal Dreadmaw:1616
|
||||
Divination:1615
|
||||
Goblin Instigator:1614
|
||||
Supreme Phantom:1613
|
||||
Chaos Wand:1605
|
||||
Rhox Oracle:1603
|
||||
Elvish Rejuvenator:1602
|
||||
Skilled Animator:1600
|
||||
Leonin Vanguard:1597
|
||||
Declare Dominance:1596
|
||||
Reassembling Skeleton:1595
|
||||
Daggerback Basilisk:1591
|
||||
Bone to Ash:1585
|
||||
Rise from the Grave:1585
|
||||
Gift of Paradise:1582
|
||||
Titanic Growth:1582
|
||||
Arcane Encyclopedia:1581
|
||||
Switcheroo:1581
|
||||
Doomed Dissenter:1579
|
||||
Gigantosaurus:1579
|
||||
Siegebreaker Giant:1577
|
||||
Child of Night:1575
|
||||
Surge Mare:1575
|
||||
Cancel:1561
|
||||
Volley Veteran:1560
|
||||
Epicure of Blood:1559
|
||||
Vampire Neonate:1555
|
||||
Guttersnipe:1554
|
||||
Aethershield Artificer:1553
|
||||
Rogue's Gloves:1553
|
||||
Macabre Waltz:1550
|
||||
Hired Blade:1548
|
||||
Salvager of Secrets:1545
|
||||
Diamond Mare:1543
|
||||
Blood Divination:1542
|
||||
Nightmare's Thirst:1542
|
||||
Gargoyle Sentinel:1539
|
||||
Act of Treason:1538
|
||||
Lightning Mare:1534
|
||||
Abnormal Endurance:1531
|
||||
Inspired Charge:1531
|
||||
Gearsmith Guardian:1527
|
||||
Dragon Egg:1521
|
||||
Anticipate:1519
|
||||
Viashino Pyromancer:1519
|
||||
Rustwing Falcon:1514
|
||||
Two-Headed Zombie:1513
|
||||
Blanchwood Armor:1511
|
||||
Hostile Minotaur:1510
|
||||
Druid of Horns:1508
|
||||
Marauder's Axe:1508
|
||||
Diregraf Ghoul:1507
|
||||
Havoc Devils:1506
|
||||
Satyr Enchanter:1505
|
||||
Centaur Courser:1502
|
||||
Plummet:1497
|
||||
Disperse:1494
|
||||
Sure Strike:1494
|
||||
Inferno Hellion:1491
|
||||
Novice Knight:1491
|
||||
Oakenform:1483
|
||||
Knight of the Tusk:1482
|
||||
Fountain of Renewal:1477
|
||||
Ravenous Harpy:1474
|
||||
Knight's Pledge:1469
|
||||
Thornhide Wolves:1463
|
||||
Dragon's Hoard:1461
|
||||
Daybreak Chaplain:1459
|
||||
Ghirapur Guide:1457
|
||||
Greenwood Sentinel:1456
|
||||
Recollect:1455
|
||||
Goblin Motivator:1452
|
||||
Talons of Wildwood:1449
|
||||
Colossal Majesty:1447
|
||||
Gearsmith Prodigy:1441
|
||||
Scholar of Stars:1439
|
||||
Ajani's Welcome:1433
|
||||
Mighty Leap:1432
|
||||
Naturalize:1431
|
||||
Trusty Packbeast:1431
|
||||
Dwarven Priest:1426
|
||||
Uncomfortable Chill:1423
|
||||
Oreskos Swiftclaw:1422
|
||||
Psychic Corrosion:1421
|
||||
Loxodon Line Breaker:1419
|
||||
Aether Tunnel:1404
|
||||
Frilled Sea Serpent:1403
|
||||
Infernal Scarring:1403
|
||||
Phylactery Lich:1398
|
||||
Mind Rot:1396
|
||||
Explosive Apparatus:1395
|
||||
Amulet of Safekeeping:1390
|
||||
Duress:1390
|
||||
Magistrate's Scepter:1388
|
||||
Suspicious Bookcase:1388
|
||||
Invoke the Divine:1385
|
||||
Manalith:1384
|
||||
Onakke Ogre:1384
|
||||
Tormenting Voice:1384
|
||||
One with the Machine:1378
|
||||
Meandering River:1374
|
||||
Lava Axe:1369
|
||||
Stone Quarry:1369
|
||||
Thud:1368
|
||||
Field Creeper:1367
|
||||
Rupture Spire:1366
|
||||
Elvish Clancaller:1365
|
||||
Wall of Mist:1363
|
||||
Suncleanser:1357
|
||||
Highland Game:1352
|
||||
Walking Corpse:1352
|
||||
Fire Elemental:1351
|
||||
Tectonic Rift:1348
|
||||
Totally Lost:1348
|
||||
Woodland Stream:1346
|
||||
Trumpet Blast:1339
|
||||
Millstone:1329
|
||||
Crash Through:1327
|
||||
Bogstomper:1326
|
||||
Aegis of the Heavens:1323
|
||||
Forsaken Sanctuary:1323
|
||||
Apex of Power:1307
|
||||
Tranquil Expanse:1304
|
||||
Cinder Barrens:1296
|
||||
Infernal Reckoning:1294
|
||||
Revitalize:1293
|
||||
Wall of Vines:1292
|
||||
Detection Tower:1283
|
||||
Timber Gorge:1282
|
||||
Submerged Boneyard:1277
|
||||
Mistcaller:1273
|
||||
Ghostform:1272
|
||||
Catalyst Elemental:1268
|
||||
Omniscience:1267
|
||||
Tolarian Scholar:1267
|
||||
Stitcher's Supplier:1263
|
||||
Desecrated Tomb:1258
|
||||
Scapeshift:1251
|
||||
Sovereign's Bite:1250
|
||||
Highland Lake:1245
|
||||
Infectious Horror:1241
|
||||
Doublecast:1240
|
||||
Fraying Omnipotence:1220
|
||||
Crucible of Worlds:1209
|
||||
Root Snare:1201
|
||||
Smelt:1199
|
||||
Reliquary Tower:1197
|
||||
Foul Orchard:1190
|
||||
Isolate:1139
|
||||
Alpine Moon:1068
|
|
|
@ -0,0 +1,249 @@
|
|||
Jace, the Mind Sculptor:2196
|
||||
Master of the Wild Hunt:2148
|
||||
Lightning Bolt:2107
|
||||
Swords to Plowshares:2060
|
||||
Vendilion Clique:2058
|
||||
Ravenous Chupacabra:2057
|
||||
Courser of Kruphix:1981
|
||||
Reef Worm:1962
|
||||
Vindicate:1961
|
||||
Pillory of the Sleepless:1926
|
||||
Akroma, Angel of Fury:1923
|
||||
Gisela, Blade of Goldnight:1918
|
||||
Akroma, Angel of Wrath:1913
|
||||
Animar, Soul of Elements:1902
|
||||
Murder:1900
|
||||
Ruric Thar, the Unbowed:1896
|
||||
Protean Hulk:1894
|
||||
Pacifism:1888
|
||||
Akroma’s Vengeance:1885
|
||||
Murder of Crows:1885
|
||||
Phyrexian Obliterator:1882
|
||||
Rancor:1864
|
||||
Vesuvan Shapeshifter:1858
|
||||
Niv-Mizzet, the Firemind:1854
|
||||
Shadowmage Infiltrator:1854
|
||||
Fiend Hunter:1844
|
||||
Pernicious Deed:1841
|
||||
Thalia, Guardian of Thraben:1829
|
||||
Living Death:1827
|
||||
Man-o’-War:1827
|
||||
Elvish Piper:1825
|
||||
Imperial Recruiter:1810
|
||||
Sundering Titan:1806
|
||||
Decree of Justice:1803
|
||||
Prossh, Skyraider of Kher:1803
|
||||
Cloudblazer:1798
|
||||
Laquatus’s Champion:1795
|
||||
Darien, King of Kjeldor:1787
|
||||
Grenzo, Dungeon Warden:1787
|
||||
Pyroclasm:1787
|
||||
Brion Stoutarm:1786
|
||||
Utopia Sprawl:1785
|
||||
Counterspell:1772
|
||||
Coalition Relic:1765
|
||||
Disfigure:1755
|
||||
Kongming, “Sleeping Dragon”:1752
|
||||
Spikeshot Goblin:1752
|
||||
Blightning:1750
|
||||
Arbor Elf:1748
|
||||
Bident of Thassa:1743
|
||||
Hell’s Caretaker:1739
|
||||
Cultivate:1728
|
||||
Kindle:1726
|
||||
Luminarch Ascension:1719
|
||||
Fallen Angel:1718
|
||||
Krosan Tusker:1718
|
||||
Promise of Bunrei:1713
|
||||
Squadron Hawk:1712
|
||||
Mystic Snake:1711
|
||||
Horseshoe Crab:1707
|
||||
Ensnaring Bridge:1706
|
||||
Lorescale Coatl:1702
|
||||
Nicol Bolas:1702
|
||||
Boros Charm:1701
|
||||
Treasure Keeper:1701
|
||||
Undead Gladiator:1699
|
||||
Baloth Null:1698
|
||||
Chandra’s Outrage:1691
|
||||
Notion Thief:1691
|
||||
Merfolk Looter:1689
|
||||
Willbender:1689
|
||||
Azusa, Lost but Seeking:1686
|
||||
Quicksilver Dagger:1686
|
||||
Armageddon:1683
|
||||
Dusk Legion Zealot:1678
|
||||
Zombify:1678
|
||||
Urbis Protector:1676
|
||||
Rishadan Port:1673
|
||||
Blue Sun’s Zenith:1672
|
||||
Mesmeric Fiend:1669
|
||||
Chalice of the Void:1668
|
||||
Zulaport Cutthroat:1662
|
||||
Epic Confrontation:1658
|
||||
Exclude:1658
|
||||
Eidolon of the Great Revel:1655
|
||||
Nyx-Fleece Ram:1653
|
||||
Diabolic Edict:1651
|
||||
Brainstorm:1648
|
||||
Magus of the Wheel:1648
|
||||
Zada, Hedron Grinder:1645
|
||||
Court Hussar:1638
|
||||
Sift:1638
|
||||
Iwamori of the Open Fist:1637
|
||||
Twisted Abomination:1633
|
||||
Izzet Chemister:1632
|
||||
Ire Shaman:1629
|
||||
Kavu Predator:1628
|
||||
Street Wraith:1628
|
||||
Dauntless Cathar:1625
|
||||
Cloudshift:1622
|
||||
Mystic of the Hidden Way:1622
|
||||
Summoner’s Pact:1622
|
||||
Ball Lightning:1621
|
||||
Skeletonize:1620
|
||||
Ruthless Ripper:1614
|
||||
Hordeling Outburst:1609
|
||||
Path of Peace:1609
|
||||
Loyal Sentry:1607
|
||||
Eladamri’s Call:1606
|
||||
Mishra’s Factory:1604
|
||||
Ash Barrens:1602
|
||||
Griffin Protector:1591
|
||||
Myriad Landscape:1588
|
||||
Hanna, Ship’s Navigator:1586
|
||||
Flash:1585
|
||||
Prophetic Prism:1585
|
||||
Unearth:1584
|
||||
Enthralling Victor:1583
|
||||
Freed from the Real:1581
|
||||
Fathom Seer:1578
|
||||
Sai of the Shinobi:1578
|
||||
Ancient Craving:1577
|
||||
Bloodhunter Bat:1577
|
||||
Invigorate:1576
|
||||
Watchwolf:1575
|
||||
Mogg Flunkies:1571
|
||||
Vessel of Nascency:1571
|
||||
Whitemane Lion:1571
|
||||
Swiftfoot Boots:1570
|
||||
Plague Wind:1569
|
||||
Perilous Myr:1568
|
||||
Karona’s Zealot:1567
|
||||
Geist of the Moors:1563
|
||||
Jalira, Master Polymorphist:1563
|
||||
Cascade Bluffs:1560
|
||||
Elvish Aberration:1560
|
||||
Kavu Climber:1555
|
||||
Thresher Lizard:1555
|
||||
Horror of the Broken Lands:1551
|
||||
Ainok Survivalist:1549
|
||||
Genju of the Falls:1549
|
||||
Frenzied Goblin:1547
|
||||
Pyre Hound:1545
|
||||
Stangg:1544
|
||||
Twilight Mire:1544
|
||||
Broodhatch Nantuko:1542
|
||||
Kor Firewalker:1542
|
||||
Ratcatcher:1542
|
||||
Presence of Gond:1541
|
||||
Noble Templar:1539
|
||||
Brine Elemental:1537
|
||||
Death’s-Head Buzzard:1537
|
||||
Fierce Empath:1537
|
||||
Timberpack Wolf:1537
|
||||
Skirk Commando:1536
|
||||
Ghost Ship:1535
|
||||
Ember Weaver:1533
|
||||
Pact of Negation:1531
|
||||
Shoreline Ranger:1531
|
||||
Woolly Loxodon:1526
|
||||
Curiosity:1525
|
||||
Gods Willing:1523
|
||||
Deadly Designs:1521
|
||||
Phyrexian Ghoul:1519
|
||||
Giant Growth:1518
|
||||
Fortune Thief:1517
|
||||
Genju of the Spires:1517
|
||||
Angelic Page:1516
|
||||
Nettle Sentinel:1516
|
||||
Wildheart Invoker:1514
|
||||
Ambassador Oak:1513
|
||||
Nezumi Cutthroat:1511
|
||||
Knight of the Skyward Eye:1510
|
||||
Dark Ritual:1509
|
||||
Supernatural Stamina:1509
|
||||
Flooded Grove:1503
|
||||
Ordeal of Heliod:1503
|
||||
Fetid Heath:1500
|
||||
Accumulated Knowledge:1498
|
||||
Balduvian Horde:1497
|
||||
Vampire Lacerator:1491
|
||||
Chartooth Cougar:1487
|
||||
Lunarch Mantle:1487
|
||||
Pendelhaven:1487
|
||||
Doomsday:1486
|
||||
Colossal Dreadmaw:1485
|
||||
Krosan Colossus:1483
|
||||
Retraction Helix:1473
|
||||
Arcane Denial:1472
|
||||
Quicksand:1472
|
||||
Fencing Ace:1470
|
||||
Goblin War Drums:1467
|
||||
Self-Assembler:1463
|
||||
Rugged Prairie:1461
|
||||
Caustic Tar:1459
|
||||
Erg Raiders:1458
|
||||
Simian Spirit Guide:1458
|
||||
Regrowth:1454
|
||||
Mikokoro, Center of the Sea:1450
|
||||
Returned Phalanx:1449
|
||||
Cursecatcher:1445
|
||||
Tree of Redemption:1445
|
||||
Soulbright Flamekin:1444
|
||||
Primal Clay:1443
|
||||
Uncaged Fury:1443
|
||||
Will-o’-the-Wisp:1443
|
||||
Browbeat:1434
|
||||
Heavy Arbalest:1430
|
||||
Echoing Courage:1429
|
||||
Blood Moon:1425
|
||||
Choking Tethers:1424
|
||||
Stampede Driver:1422
|
||||
Crimson Mage:1421
|
||||
Relentless Rats:1421
|
||||
Living Wish:1420
|
||||
Totally Lost:1418
|
||||
Humble Defector:1417
|
||||
Ihsan’s Shade:1417
|
||||
Zoetic Cavern:1412
|
||||
Act of Treason:1405
|
||||
Savannah Lions:1404
|
||||
Coralhelm Guide:1398
|
||||
Trumpet Blast:1397
|
||||
Twisted Image:1397
|
||||
Dragon’s Eye Savants:1392
|
||||
Blue Elemental Blast:1385
|
||||
Ancient Stirrings:1377
|
||||
Phantasmal Bear:1374
|
||||
Rest in Peace:1373
|
||||
Dirge of Dread:1372
|
||||
Red Elemental Blast:1361
|
||||
Triskaidekaphobia:1361
|
||||
Cinder Storm:1352
|
||||
Auramancer:1346
|
||||
Haunted Fengraf:1343
|
||||
Strionic Resonator:1342
|
||||
Act of Heroism:1341
|
||||
Borrowing 100,000 Arrows:1338
|
||||
Jackal Pup:1337
|
||||
Valor in Akros:1337
|
||||
Nihil Spellbomb:1316
|
||||
Assembly-Worker:1301
|
||||
Pillage:1300
|
||||
Disenchant:1271
|
||||
Renewed Faith:1250
|
||||
Plummet:1238
|
||||
Congregate:1218
|
||||
Lull:1212
|
||||
Conflux:1208
|
|
|
@ -0,0 +1,191 @@
|
|||
Rekindling Phoenix:2418
|
||||
Tetzimoc, Primal Death:2401
|
||||
Ravenous Chupacabra:2290
|
||||
Twilight Prophet:2282
|
||||
Etali, Primal Storm:2192
|
||||
Angrath, the Flame-Chained:2180
|
||||
The Immortal Sun:2168
|
||||
Profane Procession:2155
|
||||
Jadelight Ranger:2143
|
||||
Ghalta, Primal Hunger:2131
|
||||
Tendershoot Dryad:2121
|
||||
Bishop of Binding:2103
|
||||
Kumena, Tyrant of Orazca:2098
|
||||
Dire Fleet Poisoner:2094
|
||||
Trapjaw Tyrant:2087
|
||||
Bombard:2052
|
||||
Moment of Craving:2039
|
||||
Huatli, Radiant Champion:2029
|
||||
Hadana’s Climb:2019
|
||||
Reaver Ambush:2001
|
||||
Warkite Marauder:2001
|
||||
Champion of Dusk:2000
|
||||
Baffling End:1990
|
||||
Luminous Bonds:1970
|
||||
Impale:1966
|
||||
Golden Demise:1946
|
||||
Journey to Eternity:1941
|
||||
Crested Herdcaller:1936
|
||||
Azor, the Lawbringer:1914
|
||||
Thrashing Brontodon:1908
|
||||
Raging Regisaur:1902
|
||||
Zacama, Primal Calamity:1901
|
||||
Legion Lieutenant:1898
|
||||
Deeproot Elite:1893
|
||||
Sadistic Skymarcher:1893
|
||||
Needletooth Raptor:1889
|
||||
Elenda, the Dusk Rose:1888
|
||||
Dire Fleet Daredevil:1883
|
||||
Merfolk Mistbinder:1881
|
||||
Hunt the Weak:1839
|
||||
Forerunner of the Legion:1828
|
||||
Zetalpa, Primal Dawn:1820
|
||||
Golden Guardian:1819
|
||||
Radiant Destiny:1816
|
||||
Vona’s Hunger:1798
|
||||
Polyraptor:1793
|
||||
Tilonalli’s Summoner:1792
|
||||
Swift Warden:1774
|
||||
Slaughter the Strong:1767
|
||||
Protean Raider:1764
|
||||
Waterknot:1762
|
||||
Seafloor Oracle:1761
|
||||
Forerunner of the Empire:1760
|
||||
Divine Verdict:1759
|
||||
Reckless Rage:1758
|
||||
Dusk Legion Zealot:1755
|
||||
Squire’s Devotion:1754
|
||||
Temple Altisaur:1753
|
||||
Forerunner of the Heralds:1749
|
||||
Deadeye Brawler:1748
|
||||
Nezahal, Primal Tide:1742
|
||||
Captain’s Hook:1722
|
||||
Curious Obsession:1720
|
||||
Charging Tuskodon:1717
|
||||
Azor’s Gateway:1706
|
||||
Dire Fleet Neckbreaker:1703
|
||||
Wayward Swordtooth:1699
|
||||
Resplendent Griffin:1698
|
||||
Jungle Creeper:1693
|
||||
Siegehorn Ceratops:1690
|
||||
Kitesail Corsair:1689
|
||||
Martyr of Dusk:1689
|
||||
Exultant Skymarcher:1686
|
||||
Sailor of Means:1683
|
||||
Silvergill Adept:1680
|
||||
Atzocan Seer:1675
|
||||
Jungleborn Pioneer:1674
|
||||
Path of Discovery:1669
|
||||
Skymarcher Aspirant:1667
|
||||
Siren Reaver:1661
|
||||
Paladin of Atonement:1655
|
||||
Forerunner of the Coalition:1652
|
||||
Mutiny:1648
|
||||
Storm Fleet Sprinter:1638
|
||||
Relentless Raptor:1634
|
||||
Everdawn Champion:1625
|
||||
Goblin Trailblazer:1622
|
||||
Storm Fleet Swashbuckler:1606
|
||||
Spire Winder:1600
|
||||
Strength of the Pack:1594
|
||||
Secrets of the Golden City:1593
|
||||
Mausoleum Harpy:1586
|
||||
Slippery Scoundrel:1585
|
||||
Colossal Dreadmaw:1584
|
||||
Knight of the Stampede:1584
|
||||
Dusk Charger:1579
|
||||
Expel from Orazca:1578
|
||||
Oathsworn Vampire:1578
|
||||
Overgrown Armasaur:1576
|
||||
Daring Buccaneer:1562
|
||||
Deadeye Rig-Hauler:1557
|
||||
Sun-Crested Pterodon:1557
|
||||
Soul of the Rapids:1549
|
||||
Cherished Hatchling:1547
|
||||
Crashing Tide:1538
|
||||
Recover:1538
|
||||
Arch of Orazca:1537
|
||||
Majestic Heliopterus:1531
|
||||
Sanguine Glorifier:1525
|
||||
Form of the Dinosaur:1523
|
||||
Pride of Conquerors:1523
|
||||
Famished Paladin:1516
|
||||
Moment of Triumph:1515
|
||||
Silverclad Ferocidons:1511
|
||||
Frilled Deathspitter:1509
|
||||
Kumena’s Awakening:1505
|
||||
Snubhorn Sentry:1504
|
||||
Voracious Vampire:1504
|
||||
Fathom Fleet Boarder:1501
|
||||
Buccaneer’s Bravado:1492
|
||||
Thunderherd Migration:1487
|
||||
Legion Conquistador:1483
|
||||
See Red:1481
|
||||
Riverwise Augur:1478
|
||||
Cacophodon:1477
|
||||
Tomb Robber:1475
|
||||
Giltgrove Stalker:1472
|
||||
Swaggering Corsair:1472
|
||||
Evolving Wilds:1463
|
||||
Dinosaur Hunter:1461
|
||||
World Shaper:1452
|
||||
Path of Mettle:1447
|
||||
Hardy Veteran:1446
|
||||
Mist-Cloaked Herald:1443
|
||||
Fanatical Firebrand:1442
|
||||
Jadecraft Artisan:1440
|
||||
Stampeding Horncrest:1439
|
||||
Admiral’s Order:1436
|
||||
Timestream Navigator:1433
|
||||
Brazen Freebooter:1427
|
||||
Imperial Ceratops:1415
|
||||
Aggressive Urge:1413
|
||||
Traveler’s Amulet:1412
|
||||
Grasping Scoundrel:1403
|
||||
Jade Bearer:1384
|
||||
Aquatic Incursion:1375
|
||||
Shake the Foundations:1374
|
||||
Vampire Revenant:1368
|
||||
Orazca Raptor:1363
|
||||
Sun Sentinel:1362
|
||||
Hornswoggle:1350
|
||||
Mastermind’s Acquisition:1344
|
||||
Raptor Companion:1340
|
||||
Sea Legs:1332
|
||||
Sun-Collared Raptor:1322
|
||||
Tilonalli’s Crown:1318
|
||||
Gleaming Barrier:1307
|
||||
Enter the Unknown:1301
|
||||
Storm the Vault:1297
|
||||
Crafty Cutpurse:1291
|
||||
Pitiless Plunderer:1288
|
||||
Forsaken Sanctuary:1281
|
||||
Pirate’s Pillage:1274
|
||||
Arterial Flow:1255
|
||||
Woodland Stream:1246
|
||||
Orazca Frillback:1244
|
||||
Dead Man’s Chest:1233
|
||||
River Darter:1233
|
||||
Naturalize:1224
|
||||
Cleansing Ray:1203
|
||||
Highland Lake:1199
|
||||
Strider Harness:1198
|
||||
Negate:1195
|
||||
Stone Quarry:1192
|
||||
Dark Inquiry:1187
|
||||
Release to the Wind:1165
|
||||
Plummet:1160
|
||||
Foul Orchard:1146
|
||||
Orazca Relic:1123
|
||||
Flood of Recollection:1121
|
||||
Canal Monitor:1094
|
||||
Blazing Hope:1069
|
||||
Brass’s Bounty:1064
|
||||
Sworn Guardian:1060
|
||||
Blood Sun:1059
|
||||
Gruesome Fate:1036
|
||||
Awakened Amalgam:1017
|
||||
Induced Amnesia:1003
|
||||
Silent Gravestone:968
|
||||
Sphinx’s Decree:961
|
||||
Shatter:907
|
|
|
@ -0,0 +1,19 @@
|
|||
# this file specifies which sets have set files.
|
||||
# each line must be exactly the 3 letter expansion code. this corresponds to a csv resource file in the same directory
|
||||
# The <set>.csv files have a strict format:
|
||||
# each line must be:
|
||||
# cardname : integer rating
|
||||
# each set's ratings are post-processed to have a normalized score [1..100], so the files don't need to have the same rating system.
|
||||
# I created the first few files with draftaholicsanonymous but you can use any integer rating system you want
|
||||
grn
|
||||
m19
|
||||
dom
|
||||
rix
|
||||
xln
|
||||
hou
|
||||
akh
|
||||
aer
|
||||
kld
|
||||
mm3
|
||||
ima
|
||||
m13
|
|
|
@ -0,0 +1,259 @@
|
|||
Vraska, Relic Seeker:2381
|
||||
Hostage Taker:2336
|
||||
Carnage Tyrant:2332
|
||||
Regisaur Alpha:2276
|
||||
Ripjaw Raptor:2228
|
||||
Captivating Crew:2225
|
||||
Vraska’s Contempt:2214
|
||||
Vona, Butcher of Magan:2192
|
||||
Huatli, Warrior Poet:2173
|
||||
Repeating Barrage:2144
|
||||
Charging Monstrosaur:2133
|
||||
Lightning Strike:2122
|
||||
Walk the Plank:2096
|
||||
Ixalan’s Binding:2083
|
||||
Burning Sun’s Avatar:2068
|
||||
Mavren Fein, Dusk Apostle:2061
|
||||
Settle the Wreckage:2057
|
||||
Waker of the Wilds:2033
|
||||
Kinjalli’s Sunwing:2032
|
||||
Sanctum Seeker:2003
|
||||
Rampaging Ferocidon:2000
|
||||
Legion’s Landing:1999
|
||||
Territorial Hammerskull:1990
|
||||
Dreamcaller Siren:1983
|
||||
Bishop of Rebirth:1975
|
||||
Vanquish the Weak:1969
|
||||
River’s Rebuke:1967
|
||||
Fathom Fleet Captain:1950
|
||||
Imperial Aerosaur:1939
|
||||
Drover of the Mighty:1932
|
||||
Deathgorge Scavenger:1917
|
||||
Snapping Sailback:1916
|
||||
Shapers of Nature:1913
|
||||
Entrancing Melody:1911
|
||||
Contract Killing:1910
|
||||
Adanto Vanguard:1901
|
||||
Air Elemental:1901
|
||||
Dire Fleet Ravager:1889
|
||||
Merfolk Branchwalker:1889
|
||||
Jace, Cunning Castaway:1881
|
||||
Savage Stomp:1878
|
||||
Kitesail Freebooter:1877
|
||||
Raging Swordtooth:1858
|
||||
Ruin Raider:1856
|
||||
Vance’s Blasting Cannons:1854
|
||||
Unfriendly Fire:1844
|
||||
Captain Lannery Storm:1843
|
||||
Pious Interdiction:1842
|
||||
Firecannon Blast:1837
|
||||
Ranging Raptors:1835
|
||||
Treasure Map:1832
|
||||
Sky Terror:1824
|
||||
Vanquisher’s Banner:1823
|
||||
Watertrap Weaver:1811
|
||||
Pirate’s Cutlass:1806
|
||||
Emperor’s Vanguard:1805
|
||||
Storm Fleet Aerialist:1805
|
||||
Tempest Caller:1798
|
||||
Daring Saboteur:1795
|
||||
Search for Azcanta:1794
|
||||
Rowdy Crew:1793
|
||||
Seekers’ Squire:1777
|
||||
Skulduggery:1773
|
||||
Glorifier of Dusk:1757
|
||||
Siren Lookout:1757
|
||||
One With the Wind:1754
|
||||
Admiral Beckett Brass:1752
|
||||
Bishop of the Bloodstained:1752
|
||||
Wanted Scoundrels:1750
|
||||
Pounce:1748
|
||||
Jade Guardian:1740
|
||||
Vineshaper Mystic:1740
|
||||
Skymarch Bloodletter:1739
|
||||
Gishath, Sun’s Avatar:1733
|
||||
Call to the Feast:1730
|
||||
Paladin of the Bloodstained:1729
|
||||
Emissary of Sunrise:1725
|
||||
Otepec Huntmaster:1719
|
||||
Thundering Spineback:1710
|
||||
Tishana’s Wayfinder:1707
|
||||
Fiery Cannonade:1697
|
||||
Verdant Sun’s Avatar:1692
|
||||
Dark Nourishment:1682
|
||||
Deadeye Tracker:1679
|
||||
Siren Stormtamer:1679
|
||||
Chart a Course:1674
|
||||
Dire Fleet Captain:1673
|
||||
Inspiring Cleric:1671
|
||||
Bishop’s Soldier:1669
|
||||
Deathless Ancient:1669
|
||||
Deeproot Warrior:1669
|
||||
Tilonalli’s Knight:1669
|
||||
Deadeye Plunderers:1664
|
||||
Conqueror’s Galleon:1657
|
||||
Bright Reprisal:1654
|
||||
Shining Aerosaur:1654
|
||||
Raptor Hatchling:1653
|
||||
Wakening Sun’s Avatar:1651
|
||||
Fell Flagship:1649
|
||||
Herald of Secret Streams:1645
|
||||
Headstrong Brute:1643
|
||||
Fathom Fleet Firebrand:1641
|
||||
Colossal Dreadmaw:1637
|
||||
Vicious Conquistador:1636
|
||||
Bloodcrazed Paladin:1635
|
||||
Bellowing Aegisaur:1629
|
||||
Tishana, Voice of Thunder:1628
|
||||
Kopala, Warden of Waves:1626
|
||||
New Horizons:1624
|
||||
Deadeye Tormentor:1621
|
||||
Marauding Looter:1621
|
||||
Kumena’s Speaker:1619
|
||||
Vampire’s Zeal:1618
|
||||
Duskborne Skymarcher:1616
|
||||
Ixalli’s Diviner:1616
|
||||
Ravenous Daggertooth:1615
|
||||
Angrath’s Marauders:1613
|
||||
Perilous Voyage:1613
|
||||
Slash of Talons:1613
|
||||
Shaper Apprentice:1612
|
||||
Wildgrowth Walker:1609
|
||||
Storm Fleet Spy:1607
|
||||
Sailor of Means:1605
|
||||
Bonded Horncrest:1600
|
||||
Grazing Whiptail:1597
|
||||
Thaumatic Compass:1596
|
||||
Thrash of Raptors:1594
|
||||
Legion’s Judgment:1591
|
||||
Queen’s Commission:1590
|
||||
Deeproot Champion:1587
|
||||
Steadfast Armasaur:1581
|
||||
River Heralds’ Boon:1579
|
||||
Rigging Runner:1575
|
||||
Goring Ceratops:1572
|
||||
Skittering Heartstopper:1572
|
||||
Storm Fleet Arsonist:1571
|
||||
Dire Fleet Hoarder:1569
|
||||
Commune with Dinosaurs:1566
|
||||
Atzocan Archer:1562
|
||||
River Sneak:1562
|
||||
Skyblade of the Legion:1560
|
||||
Run Aground:1558
|
||||
Anointed Deacon:1557
|
||||
Pterodon Knight:1557
|
||||
Mark of the Vampire:1555
|
||||
Fathom Fleet Cutthroat:1552
|
||||
Prosperous Pirates:1549
|
||||
Shipwreck Looter:1546
|
||||
Arguel’s Blood Fast:1536
|
||||
Wind Strider:1535
|
||||
Legion Conquistador:1533
|
||||
Depths of Desire:1531
|
||||
Ruthless Knave:1531
|
||||
Sunbird’s Invocation:1531
|
||||
Growing Rites of Itlimoc:1525
|
||||
Lookout’s Dispersal:1525
|
||||
Lightning-Rig Crew:1517
|
||||
Sure Strike:1517
|
||||
Boneyard Parley:1515
|
||||
Dusk Legion Dreadnought:1515
|
||||
Priest of the Wakening Sun:1514
|
||||
Brazen Buccaneers:1513
|
||||
Star of Extinction:1513
|
||||
Raptor Companion:1511
|
||||
Rallying Roar:1505
|
||||
Heartless Pillage:1501
|
||||
Sleek Schooner:1500
|
||||
Fleet Swallower:1498
|
||||
Ixalli’s Keeper:1497
|
||||
Dive Down:1496
|
||||
Sheltering Light:1492
|
||||
Sun-Crowned Hunters:1483
|
||||
Cobbled Wings:1474
|
||||
Dire Fleet Interloper:1473
|
||||
Lurking Chupacabra:1465
|
||||
Storm Fleet Pyromancer:1463
|
||||
Dowsing Dagger:1456
|
||||
Shadowed Caravel:1455
|
||||
Spike-Tailed Ceratops:1455
|
||||
Kinjalli’s Caller:1454
|
||||
Deeproot Waters:1452
|
||||
Rootbound Crag:1451
|
||||
Verdant Rebirth:1451
|
||||
Storm Sculptor:1448
|
||||
Frenzied Raptor:1446
|
||||
Opt:1440
|
||||
Jungle Delver:1438
|
||||
Sword-Point Diplomacy:1438
|
||||
Nest Robber:1436
|
||||
Tilonalli’s Skinshifter:1434
|
||||
Siren’s Ruse:1433
|
||||
Crushing Canopy:1431
|
||||
Dinosaur Stampede:1429
|
||||
Overflowing Insight:1425
|
||||
Swashbuckling:1418
|
||||
Crash the Ramparts:1413
|
||||
Sunpetal Grove:1412
|
||||
Favorable Winds:1406
|
||||
Shapers’ Sanctuary:1406
|
||||
Queen’s Bay Soldier:1405
|
||||
Deadeye Quartermaster:1401
|
||||
Queen’s Agent:1397
|
||||
Dual Shot:1396
|
||||
Pirate’s Prize:1394
|
||||
March of the Drowned:1387
|
||||
Blossom Dryad:1385
|
||||
Drowned Catacomb:1383
|
||||
Tocatli Honor Guard:1373
|
||||
Dragonskull Summit:1372
|
||||
Raiders’ Wake:1371
|
||||
Spell Swindle:1368
|
||||
Sunrise Seeker:1361
|
||||
Desperate Castaways:1342
|
||||
Prying Blade:1338
|
||||
Sorcerous Spyglass:1334
|
||||
Blight Keeper:1330
|
||||
Costly Plunder:1310
|
||||
Primal Amulet:1306
|
||||
Unclaimed Territory:1306
|
||||
Fire Shrine Keeper:1301
|
||||
Imperial Lancer:1297
|
||||
Belligerent Brontodon:1296
|
||||
Emergent Growth:1293
|
||||
Wily Goblin:1293
|
||||
Cancel:1287
|
||||
Duress:1286
|
||||
Old-Growth Dryads:1282
|
||||
Navigator’s Ruin:1273
|
||||
Glacial Fortress:1262
|
||||
Trove of Temptation:1259
|
||||
Pillar of Origins:1252
|
||||
Hijack:1236
|
||||
Rile:1234
|
||||
Revel in Riches:1232
|
||||
Headwater Sentries:1225
|
||||
Grim Captain’s Call:1214
|
||||
Elaborate Firecannon:1209
|
||||
Looming Altisaur:1206
|
||||
Encampment Keeper:1199
|
||||
Slice in Twain:1198
|
||||
Spell Pierce:1186
|
||||
Makeshift Munitions:1183
|
||||
Rummaging Goblin:1182
|
||||
Axis of Mortality:1179
|
||||
Unknown Shores:1173
|
||||
Shore Keeper:1172
|
||||
Ancient Brontodon:1165
|
||||
Sanguine Sacrament:1162
|
||||
Arcane Adaptation:1151
|
||||
Ashes of the Abhorrent:1135
|
||||
Ritual of Rejuvenation:1102
|
||||
Field of Ruin:1097
|
||||
Hierophant’s Chalice:1077
|
||||
Gilded Sentinel:1035
|
||||
Blinding Fog:1033
|
||||
Demystify:1023
|
||||
Sentinel Totem:998
|
||||
Demolish:994
|
||||
Spreading Rot:935
|
|
|
@ -22,7 +22,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.3.2</version>
|
||||
<version>3.8.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.16.1</version>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -194,58 +194,58 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>1.2.4</version>
|
||||
<version>1.4.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.api-client</groupId>
|
||||
<artifactId>google-api-client</artifactId>
|
||||
<version>1.21.0</version>
|
||||
<version>1.25.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-gmail</artifactId>
|
||||
<version>v1-rev35-1.21.0</version>
|
||||
<version>v1-rev82-1.23.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.oauth-client</groupId>
|
||||
<artifactId>google-oauth-client-java6</artifactId>
|
||||
<version>1.19.0</version>
|
||||
<version>1.25.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.oauth-client</groupId>
|
||||
<artifactId>google-oauth-client-jetty</artifactId>
|
||||
<version>1.19.0</version>
|
||||
<version>1.25.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-core</artifactId>
|
||||
<version>1.19</version>
|
||||
<version>1.19.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>1.19</version>
|
||||
<version>1.19.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-multipart</artifactId>
|
||||
<version>1.19</version>
|
||||
<version>1.19.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.7.2</version>
|
||||
<version>3.25.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -254,7 +254,7 @@
|
|||
<plugin>
|
||||
<groupId>org.jvnet.jaxb2.maven2</groupId>
|
||||
<artifactId>maven-jaxb2-plugin</artifactId>
|
||||
<version>0.12.3</version>
|
||||
<version>0.14.0</version>
|
||||
<configuration>
|
||||
<generatePackage>mage.server.util.config</generatePackage>
|
||||
<schemaDirectory>./src/main/xml-resources/jaxb/Config/</schemaDirectory>
|
||||
|
|
|
@ -172,8 +172,8 @@ public enum ChatManager {
|
|||
+ "<br/>\\whisper or \\w [player name] [text] - whisper to the player with the given name"
|
||||
+ "<br/>\\card Card Name - Print oracle text for card"
|
||||
+ "<br/>[Card Name] - Show a highlighted card name"
|
||||
+ "<br/>\\ignore - shows current ignore list on this server."
|
||||
+ "<br/>\\ignore [username] - add a username to your ignore list on this server."
|
||||
+ "<br/>\\ignore - shows your ignore list on this server."
|
||||
+ "<br/>\\ignore [username] - add username to ignore list (they won't be able to chat or join to your game)."
|
||||
+ "<br/>\\unignore [username] - remove a username from your ignore list on this server.";
|
||||
|
||||
final Pattern getCardTextPattern = Pattern.compile("^.card *(.*)");
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -7,18 +6,18 @@ import java.util.Map.Entry;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneAllEffect;
|
||||
import mage.abilities.keyword.CyclingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -42,7 +41,14 @@ public final class AbandonedSarcophagus extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// You may cast nonland cards with cycling from your graveyard.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusCastFromGraveyardEffect()));
|
||||
FilterCard filter = new FilterCard("nonland cards with cycling");
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
|
||||
filter.add(new AbilityPredicate(CyclingAbility.class));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
|
||||
new PlayFromNotOwnHandZoneAllEffect(filter,
|
||||
Zone.GRAVEYARD, true, TargetController.YOU, Duration.WhileOnBattlefield)
|
||||
.setText("You may cast nonland cards with cycling from your graveyard"))
|
||||
);
|
||||
|
||||
// If a card with cycling would be put into your graveyard from anywhere and it wasn't cycled, exile it instead.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbandonedSarcophagusReplacementEffect()), new AbandonedSarcophagusWatcher());
|
||||
|
@ -59,46 +65,6 @@ public final class AbandonedSarcophagus extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class AbandonedSarcophagusCastFromGraveyardEffect extends AsThoughEffectImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("nonland cards with cycling");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
|
||||
filter.add(new AbilityPredicate(CyclingAbility.class));
|
||||
}
|
||||
|
||||
AbandonedSarcophagusCastFromGraveyardEffect() {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
staticText = "You may cast nonland cards with cycling from your graveyard";
|
||||
}
|
||||
|
||||
AbandonedSarcophagusCastFromGraveyardEffect(final AbandonedSarcophagusCastFromGraveyardEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbandonedSarcophagusCastFromGraveyardEffect copy() {
|
||||
return new AbandonedSarcophagusCastFromGraveyardEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
Card card = game.getCard(objectId);
|
||||
if (card != null) {
|
||||
return (affectedControllerId.equals(source.getControllerId())
|
||||
&& filter.match(card, game)
|
||||
&& game.getState().getZone(card.getId()) == Zone.GRAVEYARD);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class AbandonedSarcophagusReplacementEffect extends ReplacementEffectImpl {
|
||||
|
||||
boolean cardHasCycling;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -8,6 +7,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
|||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
|
||||
import mage.abilities.keyword.ProwessAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -75,7 +75,7 @@ class AbbotOfKeralKeepExileEffect extends OneShotEffect {
|
|||
if (card != null) {
|
||||
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>";
|
||||
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
|
||||
ContinuousEffect effect = new AbbotOfKeralKeepCastFromExileEffect();
|
||||
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
@ -12,26 +13,24 @@ import mage.abilities.keyword.TransformAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.p.PerfectedForm;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class AberrantResearcher extends CardImpl {
|
||||
|
||||
public AberrantResearcher(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.INSECT);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = PerfectedForm.class;
|
||||
this.secondSideCardClazz = mage.cards.p.PerfectedForm.class;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
|
@ -14,7 +15,6 @@ import mage.abilities.keyword.TransformAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.i.InfectiousCurse;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -23,7 +23,6 @@ import mage.target.Target;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author halljared
|
||||
*/
|
||||
public final class AccursedWitch extends CardImpl {
|
||||
|
@ -36,7 +35,7 @@ public final class AccursedWitch extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = InfectiousCurse.class;
|
||||
this.secondSideCardClazz = mage.cards.i.InfectiousCurse.class;
|
||||
|
||||
// Spells your opponents cast that target Accursed Witch cost {1} less to cast.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AccursedWitchSpellsCostReductionEffect()));
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -6,9 +5,9 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -44,7 +43,7 @@ class ActOnImpulseExileEffect extends OneShotEffect {
|
|||
|
||||
public ActOnImpulseExileEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way.";
|
||||
this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way";
|
||||
}
|
||||
|
||||
public ActOnImpulseExileEffect(final ActOnImpulseExileEffect effect) {
|
||||
|
@ -71,7 +70,7 @@ class ActOnImpulseExileEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
if (!cards.isEmpty()) {
|
||||
ContinuousEffect effect = new ActOnImpulseMayPlayExiledEffect();
|
||||
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTargets(cards, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
|
@ -82,31 +81,3 @@ class ActOnImpulseExileEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
class ActOnImpulseMayPlayExiledEffect extends AsThoughEffectImpl {
|
||||
|
||||
public ActOnImpulseMayPlayExiledEffect() {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
|
||||
}
|
||||
|
||||
public ActOnImpulseMayPlayExiledEffect(final ActOnImpulseMayPlayExiledEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActOnImpulseMayPlayExiledEffect copy() {
|
||||
return new ActOnImpulseMayPlayExiledEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return affectedControllerId.equals(source.getControllerId())
|
||||
&& getTargetPointer().getTargets(game, source).contains(objectId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -27,8 +26,8 @@ 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) {
|
||||
|
|
47
Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java
Normal file
47
Mage.Sets/src/mage/cards/a/AdventurersGuildhouse.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class AdventurersGuildhouse extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Green legendary creatures");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
|
||||
}
|
||||
|
||||
public AdventurersGuildhouse(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// Green legendary creatures you control have "bands with other legendary creatures."
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter)));
|
||||
}
|
||||
|
||||
public AdventurersGuildhouse(final AdventurersGuildhouse card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdventurersGuildhouse copy() {
|
||||
return new AdventurersGuildhouse(this);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -6,18 +5,18 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Library;
|
||||
|
@ -81,7 +80,7 @@ class AerialCaravanExileEffect extends OneShotEffect {
|
|||
if (card != null) {
|
||||
String exileName = sourcePermanent.getIdName() + " <this card may be played the turn it was exiled>";
|
||||
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName);
|
||||
ContinuousEffect effect = new AerialCaravanCastFromExileEffect();
|
||||
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
|
@ -90,31 +89,3 @@ class AerialCaravanExileEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class AerialCaravanCastFromExileEffect extends AsThoughEffectImpl {
|
||||
|
||||
public AerialCaravanCastFromExileEffect() {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
|
||||
staticText = "You may play the card from exile";
|
||||
}
|
||||
|
||||
public AerialCaravanCastFromExileEffect(final AerialCaravanCastFromExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AerialCaravanCastFromExileEffect copy() {
|
||||
return new AerialCaravanCastFromExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return source.isControlledBy(affectedControllerId)
|
||||
&& objectId.equals(getTargetPointer().getFirst(game, source));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
@ -11,24 +12,22 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.w.WerewolfRansacker;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward
|
||||
*/
|
||||
public final class AfflictedDeserter extends CardImpl {
|
||||
|
||||
public AfflictedDeserter(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WEREWOLF);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = WerewolfRansacker.class;
|
||||
this.secondSideCardClazz = mage.cards.w.WerewolfRansacker.class;
|
||||
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(2);
|
||||
|
|
|
@ -44,7 +44,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
|||
}
|
||||
|
||||
public AminatouTheFateShifter(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{W}{U}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{W}{U}{B}");
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.AMINATOU);
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
|||
|
||||
// -1: Exile another target permanent you own, then return it to the battlefield under your control.
|
||||
ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1);
|
||||
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect());
|
||||
ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(true));
|
||||
ability.addTarget(new TargetPermanent(filter));
|
||||
this.addAbility(ability);
|
||||
|
||||
|
@ -68,6 +68,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
|||
// Aminatou, the Fateshifter can be your commander.
|
||||
this.addAbility(CanBeYourCommanderAbility.getInstance());
|
||||
}
|
||||
|
||||
public AminatouTheFateShifter(final AminatouTheFateShifter card) {
|
||||
super(card);
|
||||
}
|
||||
|
@ -79,6 +80,7 @@ public class AminatouTheFateShifter extends CardImpl {
|
|||
}
|
||||
|
||||
class AminatouPlusEffect extends OneShotEffect {
|
||||
|
||||
public AminatouPlusEffect() {
|
||||
super(Outcome.DrawCard);
|
||||
staticText = "draw a card, then put a card from your hand on top of your library";
|
||||
|
@ -118,10 +120,11 @@ class AminatouPlusEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
class AminatouUltimateEffect extends OneShotEffect {
|
||||
public AminatouUltimateEffect (){
|
||||
|
||||
public AminatouUltimateEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou," +
|
||||
" the Fateshifter controlled by the next player in the chosen direction.";
|
||||
staticText = "Choose left or right. Each player gains control of all nonland permanents other than Aminatou,"
|
||||
+ " the Fateshifter controlled by the next player in the chosen direction.";
|
||||
}
|
||||
|
||||
public AminatouUltimateEffect(final AminatouUltimateEffect effect) {
|
||||
|
@ -129,7 +132,9 @@ class AminatouUltimateEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AminatouUltimateEffect copy(){return new AminatouUltimateEffect(this);}
|
||||
public AminatouUltimateEffect copy() {
|
||||
return new AminatouUltimateEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
|
@ -154,7 +159,7 @@ class AminatouUltimateEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
// skip players out of range
|
||||
if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)){
|
||||
if (!game.getState().getPlayersInRange(controller.getId(), game).contains(nextPlayer)) {
|
||||
continue;
|
||||
}
|
||||
// save first next player to check for iteration stop
|
||||
|
@ -164,7 +169,7 @@ class AminatouUltimateEffect extends OneShotEffect {
|
|||
FilterNonlandPermanent nextPlayerNonlandPermanentsFilter = new FilterNonlandPermanent();
|
||||
nextPlayerNonlandPermanentsFilter.add(new ControllerIdPredicate(nextPlayer));
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(nextPlayerNonlandPermanentsFilter, game)) {
|
||||
if (permanent.getId().equals(source.getSourceId())){
|
||||
if (permanent.getId().equals(source.getSourceId())) {
|
||||
continue;
|
||||
}
|
||||
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, currentPlayer);
|
||||
|
@ -188,4 +193,3 @@ class AminatouUltimateEffect extends OneShotEffect {
|
|||
return nextPlayerId;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
48
Mage.Sets/src/mage/cards/a/AmphibiousKavu.java
Normal file
48
Mage.Sets/src/mage/cards/a/AmphibiousKavu.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.common.BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class AmphibiousKavu extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue and/or black creatures");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.BLACK)));
|
||||
}
|
||||
|
||||
public AmphibiousKavu(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
|
||||
this.subtype.add(SubType.KAVU);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
// Whenever Amphibious Kavu blocks or becomes blocked by one or more blue and/or black creatures, Amphibious Kavu gets +3/+3 until end of turn.
|
||||
this.addAbility(new BlocksOrBecomesBlockedByOneOrMoreTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), filter, false));
|
||||
}
|
||||
|
||||
public AmphibiousKavu(final AmphibiousKavu card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmphibiousKavu copy() {
|
||||
return new AmphibiousKavu(this);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
|
||||
|
@ -15,7 +16,6 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.d.DarthVader;
|
||||
import mage.constants.*;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
|
@ -27,7 +27,6 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
|||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Styxo
|
||||
*/
|
||||
public final class AnakinSkywalker extends CardImpl {
|
||||
|
@ -41,7 +40,7 @@ public final class AnakinSkywalker extends CardImpl {
|
|||
this.toughness = new MageInt(4);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = DarthVader.class;
|
||||
this.secondSideCardClazz = mage.cards.d.DarthVader.class;
|
||||
|
||||
// Whenever another creature dies, put a +1/+1 counter on Anakin Skywalker.
|
||||
this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, true));
|
||||
|
|
|
@ -1,34 +1,23 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.ZoneChangeTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ExileTargetForSourceEffect;
|
||||
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.AnotherPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardIdPredicate;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
import mage.target.common.TargetCardInGraveyardOrBattlefield;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -36,8 +25,10 @@ import mage.util.CardUtil;
|
|||
*/
|
||||
public final class AngelOfSerenity extends CardImpl {
|
||||
|
||||
private static final String rule = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.";
|
||||
|
||||
public AngelOfSerenity(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{W}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}{W}");
|
||||
this.subtype.add(SubType.ANGEL);
|
||||
|
||||
this.power = new MageInt(5);
|
||||
|
@ -47,7 +38,12 @@ public final class AngelOfSerenity extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// When Angel of Serenity enters the battlefield, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards.
|
||||
this.addAbility(new AngelOfSerenityTriggeredAbility());
|
||||
FilterCreatureCard filter = new FilterCreatureCard("creatures from the battlefield and/or a graveyard");
|
||||
filter.add(Predicates.not(new CardIdPredicate(this.getId())));
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect().setText(rule), true);
|
||||
Target target = new TargetCardInGraveyardOrBattlefield(0, 3, filter);
|
||||
ability.addTarget(target);
|
||||
this.addAbility(ability);
|
||||
|
||||
// When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands.
|
||||
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.HAND, false, true), false));
|
||||
|
@ -62,92 +58,3 @@ public final class AngelOfSerenity extends CardImpl {
|
|||
return new AngelOfSerenity(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility {
|
||||
|
||||
public AngelOfSerenityTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new AngelOfSerenityEnterEffect(), "When {this} enters the battlefield, ", true);
|
||||
}
|
||||
|
||||
public AngelOfSerenityTriggeredAbility(AngelOfSerenityTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (super.checkTrigger(event, game)) {
|
||||
getTargets().clear();
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("up to three other target creatures");
|
||||
filter.add(new AnotherPredicate());
|
||||
TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, 3, filter, false);
|
||||
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target1, this, game);
|
||||
if (!target1.getTargets().isEmpty()) {
|
||||
getTargets().add(target1);
|
||||
|
||||
}
|
||||
int leftTargets = 3 - target1.getTargets().size();
|
||||
if (leftTargets > 0) {
|
||||
FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1 ? "s" : "") + " from graveyards");
|
||||
TargetCardInGraveyard target2 = new TargetCardInGraveyard(0, leftTargets, filter2);
|
||||
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target2, this, game);
|
||||
if (!target2.getTargets().isEmpty()) {
|
||||
getTargets().add(target2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AngelOfSerenityTriggeredAbility copy() {
|
||||
return new AngelOfSerenityTriggeredAbility(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AngelOfSerenityEnterEffect extends OneShotEffect {
|
||||
|
||||
public AngelOfSerenityEnterEffect() {
|
||||
super(Outcome.ReturnToHand);
|
||||
this.staticText = "you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards";
|
||||
}
|
||||
|
||||
public AngelOfSerenityEnterEffect(final AngelOfSerenityEnterEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AngelOfSerenityEnterEffect copy() {
|
||||
return new AngelOfSerenityEnterEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
boolean result = true;
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (controller != null && sourceObject != null && !source.getTargets().isEmpty()) {
|
||||
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
for (Target target : source.getTargets()) {
|
||||
if (target instanceof TargetCreaturePermanent) {
|
||||
for (UUID permanentId : target.getTargets()) {
|
||||
Permanent permanent = game.getPermanent(permanentId);
|
||||
if (permanent != null) {
|
||||
result |= controller.moveCardToExileWithInfo(permanent, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (target instanceof TargetCardInGraveyard) {
|
||||
for (UUID cardId : target.getTargets()) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
result |= controller.moveCardToExileWithInfo(card, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
53
Mage.Sets/src/mage/cards/a/AngelicReward.java
Normal file
53
Mage.Sets/src/mage/cards/a/AngelicReward.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTappedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.TotemArmorAbility;
|
||||
import mage.abilities.mana.AnyColorManaAbility;
|
||||
import mage.abilities.mana.WhiteManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
||||
public final class AngelicReward extends CardImpl {
|
||||
|
||||
public AngelicReward(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{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 gets +3/+3 and has flying.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA)));
|
||||
}
|
||||
|
||||
public AngelicReward(final AngelicReward card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AngelicReward copy() {
|
||||
return new AngelicReward(this);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -12,10 +10,12 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.permanent.token.custom.CreatureToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
*/
|
||||
|
@ -25,12 +25,18 @@ public final class AngelsTomb extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
|
||||
|
||||
// Whenever a creature enters the battlefield under your control, you may have Angel's Tomb become a 3/3 white Angel artifact creature with flying until end of turn.
|
||||
this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new BecomesCreatureSourceEffect(
|
||||
new CreatureToken(3, 3, "3/3 white Angel artifact creature with flying")
|
||||
Effect effect = new BecomesCreatureSourceEffect(new CreatureToken(3, 3, "3/3 white Angel artifact creature with flying")
|
||||
.withColor("W")
|
||||
.withSubType(SubType.ANGEL)
|
||||
.withAbility(FlyingAbility.getInstance()),
|
||||
"", Duration.EndOfTurn), true));
|
||||
"", Duration.EndOfTurn)
|
||||
.setText("have {this} become a 3/3 white Angel artifact creature with flying until end of turn");
|
||||
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
effect,
|
||||
StaticFilters.FILTER_PERMANENT_CREATURE_A,
|
||||
true)
|
||||
);
|
||||
}
|
||||
|
||||
public AngelsTomb(final AngelsTomb card) {
|
||||
|
|
64
Mage.Sets/src/mage/cards/a/Antagonism.java
Normal file
64
Mage.Sets/src/mage/cards/a/Antagonism.java
Normal file
|
@ -0,0 +1,64 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.common.BloodthirstWatcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class Antagonism extends CardImpl {
|
||||
|
||||
private static final String rule = "{this} deals 2 damage to that player unless one of his or her opponents was dealt damage this turn";
|
||||
|
||||
public Antagonism(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
|
||||
|
||||
// At the beginning of each player's end step, Antagonism deals 2 damage to that player unless one of his or her opponents was dealt damage this turn.
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(new ConditionalOneShotEffect(new DamageTargetEffect(2),
|
||||
new OpponentWasNotDealtDamageCondition(), rule), TargetController.ANY, false));
|
||||
|
||||
}
|
||||
|
||||
public Antagonism(final Antagonism card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Antagonism copy() {
|
||||
return new Antagonism(this);
|
||||
}
|
||||
}
|
||||
|
||||
class OpponentWasNotDealtDamageCondition implements Condition {
|
||||
|
||||
public OpponentWasNotDealtDamageCondition() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID activePlayer = game.getState().getActivePlayerId();
|
||||
if (activePlayer != null) {
|
||||
BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get(BloodthirstWatcher.class.getSimpleName(), activePlayer);
|
||||
if (watcher != null) {
|
||||
return !watcher.conditionMet();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "if an opponent was dealt damage this turn";
|
||||
}
|
||||
}
|
|
@ -4,14 +4,13 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
|
||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
|
@ -79,7 +78,7 @@ class ApexOfPowerSpellEffect extends OneShotEffect {
|
|||
if (card.isLand()) {
|
||||
continue;
|
||||
}
|
||||
ContinuousEffect effect = new ApexOfPowerCastFromExileEffect();
|
||||
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
|
@ -87,34 +86,6 @@ class ApexOfPowerSpellEffect extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
|
||||
class ApexOfPowerCastFromExileEffect extends AsThoughEffectImpl {
|
||||
|
||||
public ApexOfPowerCastFromExileEffect() {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
|
||||
staticText = "You may play the card from exile";
|
||||
}
|
||||
|
||||
public ApexOfPowerCastFromExileEffect(final ApexOfPowerCastFromExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApexOfPowerCastFromExileEffect copy() {
|
||||
return new ApexOfPowerCastFromExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
return source.isControlledBy(affectedControllerId)
|
||||
&& objectId.equals(getTargetPointer().getFirst(game, source));
|
||||
}
|
||||
}
|
||||
|
||||
class ApexOfPowerManaEffect extends OneShotEffect {
|
||||
|
||||
public ApexOfPowerManaEffect() {
|
||||
|
|
67
Mage.Sets/src/mage/cards/a/ArcheryTraining.java
Normal file
67
Mage.Sets/src/mage/cards/a/ArcheryTraining.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -14,14 +15,12 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.t.TempleOfAclazotz;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ArguelsBloodFast extends CardImpl {
|
||||
|
@ -31,7 +30,7 @@ public final class ArguelsBloodFast extends CardImpl {
|
|||
|
||||
addSuperType(SuperType.LEGENDARY);
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = TempleOfAclazotz.class;
|
||||
this.secondSideCardClazz = mage.cards.t.TempleOfAclazotz.class;
|
||||
|
||||
// {1}{B}, Pay 2 life: Draw a card.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}"));
|
||||
|
|
|
@ -28,7 +28,6 @@ import mage.constants.SubType;
|
|||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
|
@ -38,8 +37,6 @@ import mage.game.permanent.Permanent;
|
|||
*/
|
||||
public final class ArixmethesSlumberingIsle extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("a spell");
|
||||
|
||||
public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.condition.common.EquippedSourceCondition;
|
||||
|
@ -9,27 +10,25 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.l.LunarchInquisitors;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class AvacynianMissionaries extends CardImpl {
|
||||
|
||||
public AvacynianMissionaries(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.HUMAN);
|
||||
this.subtype.add(SubType.CLERIC);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = LunarchInquisitors.class;
|
||||
this.secondSideCardClazz = mage.cards.l.LunarchInquisitors.class;
|
||||
|
||||
// At the beginning of your end step, if Avacynian Missionaries is equipped, transform it.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
93
Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java
Normal file
93
Mage.Sets/src/mage/cards/a/AvatarOfGrowth.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.cost.SpellCostReductionSourceForOpponentsEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class AvatarOfGrowth extends CardImpl {
|
||||
|
||||
public AvatarOfGrowth(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
|
||||
this.subtype.add(SubType.ELEMENTAL);
|
||||
this.subtype.add(SubType.AVATAR);
|
||||
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// This spell costs {1} less to cast for each opponent you have.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceForOpponentsEffect("This spell costs {1} less to cast for each opponent you have")));
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// When Avatar of Growth enters the battlefield, each player searches their library for up to two basic land cards, puts them onto the battlefield, then shuffles their library.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new AvatarOfGrowthSearchEffect()));
|
||||
}
|
||||
|
||||
public AvatarOfGrowth(final AvatarOfGrowth card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AvatarOfGrowth copy() {
|
||||
return new AvatarOfGrowth(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarOfGrowthSearchEffect extends OneShotEffect {
|
||||
|
||||
public AvatarOfGrowthSearchEffect() {
|
||||
super(Outcome.Detriment);
|
||||
this.staticText = "each player searches their library for up to two basic land cards, puts them onto the battlefield, then shuffles their libarary";
|
||||
}
|
||||
|
||||
public AvatarOfGrowthSearchEffect(final AvatarOfGrowthSearchEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AvatarOfGrowthSearchEffect copy() {
|
||||
return new AvatarOfGrowthSearchEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LAND);
|
||||
if (player.searchLibrary(target, game)) {
|
||||
if (!target.getTargets().isEmpty()) {
|
||||
player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game);
|
||||
}
|
||||
}
|
||||
player.shuffleLibrary(source, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ package mage.cards.a;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -16,7 +17,6 @@ import mage.abilities.keyword.TransformAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.s.SanctumOfTheSun;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
|
@ -28,7 +28,6 @@ import mage.target.common.TargetCardInHand;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class AzorsGateway extends CardImpl {
|
||||
|
@ -38,7 +37,7 @@ public final class AzorsGateway extends CardImpl {
|
|||
|
||||
this.addSuperType(SuperType.LEGENDARY);
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = SanctumOfTheSun.class;
|
||||
this.secondSideCardClazz = mage.cards.s.SanctumOfTheSun.class;
|
||||
|
||||
// {1}, {T}: Draw a card, then exile a card from your hand. If cards with five or more different converted mana costs are exiled with Azor's Gateway, you gain 5 life, untap Azor's Gateway, and transform it.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -23,8 +23,9 @@ import mage.target.Target;
|
|||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BeamsplitterMage extends CardImpl {
|
||||
|
@ -156,7 +157,7 @@ class BeamsplitterMageEffect extends OneShotEffect {
|
|||
if (usedTarget == null) {
|
||||
return false;
|
||||
}
|
||||
FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId());
|
||||
FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId(), source.getControllerId());
|
||||
Target target1 = new TargetPermanent(filter);
|
||||
target1.setNotTarget(true);
|
||||
if (controller.choose(outcome, target1, source.getSourceId(), game)) {
|
||||
|
@ -199,10 +200,11 @@ class BeamsplitterMageFilter extends FilterControlledPermanent {
|
|||
private final Target target;
|
||||
private final UUID notId;
|
||||
|
||||
public BeamsplitterMageFilter(Target target, UUID notId) {
|
||||
public BeamsplitterMageFilter(Target target, UUID notId, UUID controllerId) {
|
||||
super("creature this spell could target");
|
||||
this.target = target;
|
||||
this.notId = notId;
|
||||
this.add(new ControllerIdPredicate(controllerId));
|
||||
}
|
||||
|
||||
public BeamsplitterMageFilter(final BeamsplitterMageFilter filter) {
|
||||
|
|
36
Mage.Sets/src/mage/cards/b/BeastInShow.java
Normal file
36
Mage.Sets/src/mage/cards/b/BeastInShow.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class BeastInShow extends CardImpl {
|
||||
|
||||
public BeastInShow(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}");
|
||||
this.subtype.add(SubType.BEAST);
|
||||
this.power = new MageInt(6);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
}
|
||||
|
||||
public BeastInShow(final BeastInShow card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeastInShow copy() {
|
||||
return new BeastInShow(this);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -10,6 +9,8 @@ import mage.constants.CardType;
|
|||
import mage.game.permanent.token.BeckonApparitionToken;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
*/
|
||||
|
@ -18,6 +19,7 @@ public final class BeckonApparition extends CardImpl {
|
|||
public BeckonApparition(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W/B}");
|
||||
|
||||
// Exile target card from a graveyard. Create a 1/1 white and black Spirit creature token with flying.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard());
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new BeckonApparitionToken(), 1));
|
||||
|
|
199
Mage.Sets/src/mage/cards/b/BendOrBreak.java
Normal file
199
Mage.Sets/src/mage/cards/b/BendOrBreak.java
Normal file
|
@ -0,0 +1,199 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
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.FilterPlayer;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.other.PlayerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.players.PlayerList;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2 & L_J
|
||||
*/
|
||||
public final class BendOrBreak extends CardImpl {
|
||||
|
||||
public BendOrBreak(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}");
|
||||
|
||||
// Each player separates all nontoken lands they control into two piles. For each player, one of their piles is chosen by one of their opponents of their choice. Destroy all lands in the chosen piles. Tap all lands in the other piles.
|
||||
this.getSpellAbility().addEffect(new BendOrBreakEffect());
|
||||
}
|
||||
|
||||
public BendOrBreak(final BendOrBreak card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BendOrBreak copy() {
|
||||
return new BendOrBreak(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BendOrBreakEffect extends OneShotEffect {
|
||||
|
||||
|
||||
public BendOrBreakEffect() {
|
||||
super(Outcome.DestroyPermanent);
|
||||
this.staticText = "Each player separates all nontoken lands they control into two piles. For each player, one of their piles is chosen by one of their opponents of their choice. Destroy all lands in the chosen piles. Tap all lands in the other piles";
|
||||
}
|
||||
|
||||
public BendOrBreakEffect(final BendOrBreakEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BendOrBreakEffect copy() {
|
||||
return new BendOrBreakEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
|
||||
// Map of players and their piles
|
||||
Map<UUID, List<List<Permanent>>> playerPermanents = new LinkedHashMap<>();
|
||||
|
||||
PlayerList playerList = game.getState().getPlayerList().copy();
|
||||
while (!playerList.get().equals(source.getControllerId()) && controller.canRespond()) {
|
||||
playerList.getNext();
|
||||
}
|
||||
Player currentPlayer = game.getPlayer(playerList.get());
|
||||
Player nextPlayer;
|
||||
UUID firstNextPlayer = null;
|
||||
|
||||
while (!getNextPlayerInDirection(true, playerList, game).equals(firstNextPlayer) && controller.canRespond()) {
|
||||
nextPlayer = game.getPlayer(playerList.get());
|
||||
if (nextPlayer == null) {
|
||||
return false;
|
||||
}
|
||||
if (firstNextPlayer == null) {
|
||||
firstNextPlayer = nextPlayer.getId();
|
||||
}
|
||||
if (!nextPlayer.canRespond()) {
|
||||
continue;
|
||||
}
|
||||
// Each player separates all nontoken lands they control into two piles
|
||||
if (currentPlayer != null && game.getState().getPlayersInRange(controller.getId(), game).contains(currentPlayer.getId())) {
|
||||
List<Permanent> firstPile = new ArrayList<>();
|
||||
List<Permanent> secondPile = new ArrayList<>();
|
||||
FilterControlledLandPermanent filter = new FilterControlledLandPermanent("lands you control to assign to the first pile (lands not chosen will be assigned to the second pile)");
|
||||
TargetPermanent target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true);
|
||||
if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game)) {
|
||||
if (currentPlayer.chooseTarget(Outcome.Neutral, target, source, game)) {
|
||||
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, currentPlayer.getId(), game)) {
|
||||
if (target.getTargets().contains(permanent.getId())) {
|
||||
firstPile.add(permanent);
|
||||
} else {
|
||||
secondPile.add(permanent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder("First pile of ").append(currentPlayer.getLogName()).append(": ");
|
||||
sb.append(firstPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
|
||||
|
||||
game.informPlayers(sb.toString());
|
||||
|
||||
sb = new StringBuilder("Second pile of ").append(currentPlayer.getLogName()).append(": ");
|
||||
sb.append(secondPile.stream().map(Permanent::getLogName).collect(Collectors.joining(", ")));
|
||||
|
||||
game.informPlayers(sb.toString());
|
||||
}
|
||||
List<List<Permanent>> playerPiles = new ArrayList<>();
|
||||
playerPiles.add(firstPile);
|
||||
playerPiles.add(secondPile);
|
||||
playerPermanents.put(currentPlayer.getId(), playerPiles);
|
||||
}
|
||||
currentPlayer = nextPlayer;
|
||||
}
|
||||
|
||||
// For each player, one of their piles is chosen by one of their opponents of their choice
|
||||
for (Map.Entry<UUID, List<List<Permanent>>> playerPiles : playerPermanents.entrySet()) {
|
||||
Player player = game.getPlayer(playerPiles.getKey());
|
||||
if (player != null) {
|
||||
FilterPlayer filter = new FilterPlayer("opponent");
|
||||
List<PlayerIdPredicate> opponentPredicates = new ArrayList<>();
|
||||
for (UUID opponentId : game.getOpponents(player.getId())) {
|
||||
opponentPredicates.add(new PlayerIdPredicate(opponentId));
|
||||
}
|
||||
filter.add(Predicates.or(opponentPredicates));
|
||||
Target target = new TargetPlayer(1, 1, true, filter);
|
||||
target.setTargetController(player.getId());
|
||||
target.setAbilityController(source.getControllerId());
|
||||
if (player.chooseTarget(outcome, target, source, game)) {
|
||||
Player chosenOpponent = game.getPlayer(target.getFirstTarget());
|
||||
if (chosenOpponent != null) {
|
||||
List<Permanent> firstPile = playerPiles.getValue().get(0);
|
||||
List<Permanent> secondPile = playerPiles.getValue().get(1);
|
||||
game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to choose his pile");
|
||||
if (chosenOpponent.choosePile(outcome, "Piles of " + player.getName(), firstPile, secondPile, game)) {
|
||||
List<List<Permanent>> lists = playerPiles.getValue();
|
||||
lists.clear();
|
||||
lists.add(firstPile);
|
||||
lists.add(secondPile);
|
||||
game.informPlayers(player.getLogName() + " will have their first pile destroyed");
|
||||
} else {
|
||||
List<List<Permanent>> lists = playerPiles.getValue();
|
||||
lists.clear();
|
||||
lists.add(secondPile);
|
||||
lists.add(firstPile);
|
||||
game.informPlayers(player.getLogName() + " will have their second pile destroyed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Destroy all lands in the chosen piles. Tap all lands in the other piles
|
||||
for (Map.Entry<UUID, List<List<Permanent>>> playerPiles : playerPermanents.entrySet()) {
|
||||
Player player = game.getPlayer(playerPiles.getKey());
|
||||
if (player != null) {
|
||||
List<Permanent> pileToSac = playerPiles.getValue().get(0);
|
||||
List<Permanent> pileToTap = playerPiles.getValue().get(1);
|
||||
for (Permanent permanent : pileToSac) {
|
||||
if (permanent != null) {
|
||||
permanent.destroy(source.getSourceId(), game, false);
|
||||
}
|
||||
}
|
||||
for (Permanent permanent : pileToTap) {
|
||||
if (permanent != null) {
|
||||
permanent.tap(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private UUID getNextPlayerInDirection(boolean left, PlayerList playerList, Game game) {
|
||||
UUID nextPlayerId;
|
||||
if (left) {
|
||||
nextPlayerId = playerList.getNext();
|
||||
} else {
|
||||
nextPlayerId = playerList.getPrevious();
|
||||
}
|
||||
return nextPlayerId;
|
||||
}
|
||||
}
|
71
Mage.Sets/src/mage/cards/b/BetrothedOfFire.java
Normal file
71
Mage.Sets/src/mage/cards/b/BetrothedOfFire.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.SacrificeAttachedCost;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
import mage.abilities.keyword.EnchantAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterControlledPermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.permanent.TappedPredicate;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class BetrothedOfFire extends CardImpl {
|
||||
|
||||
private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("an untapped creature");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new TappedPredicate()));
|
||||
}
|
||||
|
||||
public BetrothedOfFire(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{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);
|
||||
|
||||
// Sacrifice an untapped creature: Enchanted creature gets +2/+0 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
new BoostEnchantedEffect(2, 0, Duration.EndOfTurn),
|
||||
new SacrificeTargetCost(new TargetControlledPermanent(filter))
|
||||
));
|
||||
|
||||
// Sacrifice enchanted creature: Creatures you control get +2/+0 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
new BoostControlledEffect(2, 0, Duration.EndOfTurn),
|
||||
new SacrificeAttachedCost()
|
||||
));
|
||||
}
|
||||
|
||||
public BetrothedOfFire(final BetrothedOfFire card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BetrothedOfFire copy() {
|
||||
return new BetrothedOfFire(this);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ import mage.constants.SubType;
|
|||
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);
|
||||
|
@ -26,8 +26,10 @@ public final class BlindingAngel extends CardImpl {
|
|||
|
||||
// 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));
|
||||
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipCombatStepEffect(Duration.OneUse).setText("that player skips their next combat phase."), false, true));
|
||||
|
||||
}
|
||||
|
||||
public BlindingAngel(final BlindingAngel card) {
|
||||
|
|
40
Mage.Sets/src/mage/cards/b/BlindingRadiance.java
Normal file
40
Mage.Sets/src/mage/cards/b/BlindingRadiance.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.effects.common.TapAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.common.FilterOpponentsCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ToughnessPredicate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class BlindingRadiance extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterOpponentsCreaturePermanent("creatures your opponents control with toughness 2 or less");
|
||||
static {
|
||||
filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, 3));
|
||||
}
|
||||
|
||||
public BlindingRadiance(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}");
|
||||
|
||||
// Tap all creatures your opponents control with toughness 2 or less.
|
||||
TapAllEffect effect = new TapAllEffect(filter);
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
|
||||
public BlindingRadiance(final BlindingRadiance card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlindingRadiance copy() {
|
||||
return new BlindingRadiance(this);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.ActivateIfConditionActivatedAbility;
|
||||
|
@ -15,7 +16,6 @@ import mage.abilities.keyword.FlyingAbility;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.l.LordOfLineage;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.SubType;
|
||||
|
@ -25,7 +25,6 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
|
|||
import mage.game.permanent.token.VampireToken;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class BloodlineKeeper extends CardImpl {
|
||||
|
@ -44,7 +43,7 @@ public final class BloodlineKeeper extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = LordOfLineage.class;
|
||||
this.secondSideCardClazz = mage.cards.l.LordOfLineage.class;
|
||||
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
// {T}: Create a 2/2 black Vampire creature token with flying.
|
||||
|
|
|
@ -31,8 +31,11 @@ public final class BoarUmbra extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Enchanted creature gets +3/+3.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
|
||||
|
||||
// Totem armor
|
||||
this.addAbility(new TotemArmorAbility());
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
@ -11,25 +12,23 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.n.NeckBreaker;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class BreakneckRider extends CardImpl {
|
||||
|
||||
public BreakneckRider(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
|
||||
this.subtype.add(SubType.HUMAN, SubType.SCOUT, SubType.WEREWOLF);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = NeckBreaker.class;
|
||||
this.secondSideCardClazz = mage.cards.n.NeckBreaker.class;
|
||||
|
||||
// At the beginning of each upkeep, if no spells were cast last turn, transform Breakneck Rider.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -111,6 +110,7 @@ class BrilliantUltimatumEffect extends OneShotEffect {
|
|||
TargetCard targetExiledCard = new TargetCard(Zone.EXILED, new FilterCard());
|
||||
if (controller.chooseTarget(Outcome.PlayForFree, selectedPile, targetExiledCard, source, game)) {
|
||||
Card card = selectedPile.get(targetExiledCard.getFirstTarget(), game);
|
||||
controller.canPlayLand();
|
||||
if (controller.playCard(card, game, true, true, new MageObjectReference(source.getSourceObject(game), game))) {
|
||||
selectedPileCards.remove(card);
|
||||
selectedPile.remove(card);
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
|
||||
import mage.abilities.effects.common.counter.AddCountersAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class CatharsCrusade extends CardImpl {
|
||||
|
||||
public CatharsCrusade(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}");
|
||||
|
||||
|
||||
// Whenever a creature enters the battlefield under your control, put a +1/+1 counter on each creature you control.
|
||||
this.addAbility(new CreatureEntersBattlefieldTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent())));
|
||||
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
|
||||
Zone.BATTLEFIELD,
|
||||
new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()),
|
||||
StaticFilters.FILTER_PERMANENT_CREATURE_A,
|
||||
false)
|
||||
);
|
||||
}
|
||||
|
||||
public CatharsCrusade(final CatharsCrusade card) {
|
||||
|
|
47
Mage.Sets/src/mage/cards/c/CathedralOfSerra.java
Normal file
47
Mage.Sets/src/mage/cards/c/CathedralOfSerra.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.keyword.BandsWithOtherAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.filter.predicate.mageobject.SupertypePredicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class CathedralOfSerra extends CardImpl {
|
||||
|
||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("White legendary creatures");
|
||||
|
||||
static {
|
||||
filter.add(new ColorPredicate(ObjectColor.WHITE));
|
||||
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
|
||||
}
|
||||
|
||||
public CathedralOfSerra(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
// White legendary creatures you control have "bands with other legendary creatures."
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new BandsWithOtherAbility(SuperType.LEGENDARY), Duration.WhileOnBattlefield, filter)));
|
||||
}
|
||||
|
||||
public CathedralOfSerra(final CathedralOfSerra card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CathedralOfSerra copy() {
|
||||
return new CathedralOfSerra(this);
|
||||
}
|
||||
}
|
|
@ -135,7 +135,7 @@ class CelestialDawnToWhiteEffect extends ContinuousEffectImpl {
|
|||
// Command
|
||||
for (CommandObject commandObject : game.getState().getCommand()) {
|
||||
if (commandObject instanceof Commander) {
|
||||
if (commandObject.getControllerId().equals(controller.getId())) {
|
||||
if (commandObject.isControlledBy(controller.getId())) {
|
||||
setColor(commandObject.getColor(game), game);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
|
||||
import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ChanceForGlory extends CardImpl {
|
||||
|
@ -19,9 +20,10 @@ public final class ChanceForGlory extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}");
|
||||
|
||||
// Creatures you control gain indestructible. Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.
|
||||
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
|
||||
IndestructibleAbility.getInstance(), Duration.EndOfGame
|
||||
).setText("Creatures you control gain indestructible"));
|
||||
this.getSpellAbility().addEffect(new GainAbilityAllEffect(
|
||||
IndestructibleAbility.getInstance(), Duration.EndOfGame,
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURES
|
||||
).setText("Creatures you control gain indestructible."));
|
||||
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect(true));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -9,9 +8,9 @@ import mage.MageObjectReference;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
|
||||
import mage.abilities.effects.common.combat.CantBlockTargetEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
|
@ -20,7 +19,6 @@ import mage.filter.common.FilterInstantOrSorceryCard;
|
|||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.players.Library;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
|
@ -177,12 +175,13 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) {
|
||||
Library library = controller.getLibrary();
|
||||
Card card = library.getFromTop(game);
|
||||
if (controller != null && sourceObject != null) {
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " <this card may be played the turn it was exiled>", source.getSourceId(), game, Zone.LIBRARY, true);
|
||||
game.addEffect(new ChandraPyromasterPlayEffect(new MageObjectReference(card, game)), source);
|
||||
controller.moveCards(card, Zone.EXILED, source, game);
|
||||
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
|
||||
effect.setTargetPointer(new FixedTarget(card, game));
|
||||
game.addEffect(effect, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -190,45 +189,6 @@ class ChandraPyromasterEffect2 extends OneShotEffect {
|
|||
}
|
||||
}
|
||||
|
||||
class ChandraPyromasterPlayEffect extends AsThoughEffectImpl {
|
||||
|
||||
private final MageObjectReference objectReference;
|
||||
|
||||
public ChandraPyromasterPlayEffect(MageObjectReference objectReference) {
|
||||
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
|
||||
this.objectReference = objectReference;
|
||||
staticText = "you may play that card until end of turn";
|
||||
}
|
||||
|
||||
public ChandraPyromasterPlayEffect(final ChandraPyromasterPlayEffect effect) {
|
||||
super(effect);
|
||||
this.objectReference = effect.objectReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChandraPyromasterPlayEffect copy() {
|
||||
return new ChandraPyromasterPlayEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (objectReference.refersTo(objectId, game) && affectedControllerId.equals(source.getControllerId())) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
return true;
|
||||
} else {
|
||||
discard();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ChandraPyromasterEffect3 extends OneShotEffect {
|
||||
|
||||
public ChandraPyromasterEffect3() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -11,7 +12,6 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.m.MarkovsServant;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
@ -22,7 +22,6 @@ import mage.filter.predicate.permanent.TappedPredicate;
|
|||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class ChosenOfMarkov extends CardImpl {
|
||||
|
@ -34,14 +33,14 @@ public final class ChosenOfMarkov extends CardImpl {
|
|||
}
|
||||
|
||||
public ChosenOfMarkov(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = MarkovsServant.class;
|
||||
this.secondSideCardClazz = mage.cards.m.MarkovsServant.class;
|
||||
|
||||
// {tap}, Tap an untapped Vampire you control: Transform Chosen of Markov.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -11,7 +12,6 @@ import mage.abilities.keyword.TransformAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.h.HomicidalBrute;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
|
@ -29,12 +29,12 @@ import mage.watchers.Watcher;
|
|||
public final class CivilizedScholar extends CardImpl {
|
||||
|
||||
public CivilizedScholar(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.ADVISOR);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = HomicidalBrute.class;
|
||||
this.secondSideCardClazz = mage.cards.h.HomicidalBrute.class;
|
||||
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(1);
|
||||
|
|
92
Mage.Sets/src/mage/cards/c/ClearTheLand.java
Normal file
92
Mage.Sets/src/mage/cards/c/ClearTheLand.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
package mage.cards.c;
|
||||
|
||||
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.game.Game;
|
||||
import mage.players.Library;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author davidmfritz
|
||||
*/
|
||||
public final class ClearTheLand extends CardImpl {
|
||||
|
||||
public ClearTheLand(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
|
||||
|
||||
|
||||
// Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.
|
||||
getSpellAbility().addEffect(new ClearTheLandEffect());
|
||||
}
|
||||
|
||||
public ClearTheLand(final ClearTheLand card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClearTheLand copy() {
|
||||
return new ClearTheLand(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ClearTheLandEffect extends OneShotEffect {
|
||||
|
||||
public ClearTheLandEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.";
|
||||
}
|
||||
|
||||
public ClearTheLandEffect(final ClearTheLandEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClearTheLandEffect copy() {
|
||||
return new ClearTheLandEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
|
||||
boolean tapped = true;
|
||||
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
||||
if (controller != null) {
|
||||
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
Library library = player.getLibrary();
|
||||
Cards cardsToReveal = new CardsImpl();
|
||||
cardsToReveal.addAll(library.getTopCards(game, 5));
|
||||
if (!cardsToReveal.isEmpty()) {
|
||||
player.revealCards(source, "Revealed cards for " + player.getName(), cardsToReveal, game);
|
||||
Cards cardsToPutOnBattlefield = new CardsImpl();
|
||||
Cards cardsToExile = new CardsImpl();
|
||||
for (Card card : cardsToReveal.getCards(game)) {
|
||||
if (card.isLand()) {
|
||||
cardsToPutOnBattlefield.add(card);
|
||||
} else {
|
||||
cardsToExile.add(card);
|
||||
}
|
||||
}
|
||||
player.moveCards(cardsToPutOnBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, tapped, false, true, null);
|
||||
player.moveCards(cardsToExile.getCards(game), Zone.EXILED, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -2,32 +2,31 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.u.UnholyFiend;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class CloisteredYouth extends CardImpl {
|
||||
|
||||
public CloisteredYouth(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = UnholyFiend.class;
|
||||
this.secondSideCardClazz = mage.cards.u.UnholyFiend.class;
|
||||
|
||||
// At the beginning of your upkeep, you may transform Cloistered Youth.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.FlashbackAbility;
|
||||
|
@ -11,21 +10,21 @@ import mage.constants.CardType;
|
|||
import mage.constants.TimingRule;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author cbt33, jonubuu (Withered Wretch)
|
||||
*/
|
||||
|
||||
public final class CoffinPurge extends CardImpl {
|
||||
|
||||
public CoffinPurge(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}");
|
||||
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
|
||||
|
||||
// Exile target card from a graveyard.
|
||||
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard());
|
||||
|
||||
// Flashback {B}
|
||||
this.addAbility(new FlashbackAbility(new ManaCostsImpl("{B}"), TimingRule.INSTANT));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -23,7 +22,7 @@ import mage.util.CardUtil;
|
|||
public final class CommuneWithLava extends CardImpl {
|
||||
|
||||
public CommuneWithLava(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
|
||||
|
||||
// Exile the top X cards of your library. Until the end of your next turn, you may play those cards.
|
||||
this.getSpellAbility().addEffect(new CommuneWithLavaEffect());
|
||||
|
|
45
Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java
Normal file
45
Mage.Sets/src/mage/cards/c/ConfrontTheAssault.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
|
||||
import mage.abilities.condition.common.AttackedThisStepCondition;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.TurnPhase;
|
||||
import mage.game.permanent.token.SpiritWhiteToken;
|
||||
import mage.watchers.common.PlayerAttackedStepWatcher;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class ConfrontTheAssault extends CardImpl {
|
||||
|
||||
public ConfrontTheAssault(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{W}");
|
||||
|
||||
// Cast this spell only if a creature is attacking you.
|
||||
Ability ability = new CastOnlyDuringPhaseStepSourceAbility(
|
||||
TurnPhase.COMBAT, PhaseStep.DECLARE_ATTACKERS, AttackedThisStepCondition.instance,
|
||||
"Cast this spell only if a creature is attacking you."
|
||||
);
|
||||
ability.addWatcher(new PlayerAttackedStepWatcher());
|
||||
this.addAbility(ability);
|
||||
|
||||
// Create three 1/1 white Spirit creature tokens with flying.
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new SpiritWhiteToken("ANA"), 3));
|
||||
}
|
||||
|
||||
public ConfrontTheAssault(final ConfrontTheAssault card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfrontTheAssault copy() {
|
||||
return new ConfrontTheAssault(this);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
@ -11,26 +12,24 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
|||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.b.BrandedHowler;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class ConvictedKiller extends CardImpl {
|
||||
|
||||
public ConvictedKiller(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WEREWOLF);
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(2);
|
||||
|
||||
this.transformable = true;
|
||||
this.secondSideCardClazz = BrandedHowler.class;
|
||||
this.secondSideCardClazz = mage.cards.b.BrandedHowler.class;
|
||||
|
||||
// At the beginning of each upkeep, if no spells were cast last turn, transform Convicted Killer.
|
||||
this.addAbility(new TransformAbility());
|
||||
|
|
|
@ -88,7 +88,7 @@ class CoverOfWinterEffect extends PreventionEffectImpl {
|
|||
|
||||
if (event.getType() == GameEvent.EventType.DAMAGE_CREATURE) {
|
||||
Permanent permanent = game.getPermanent(event.getTargetId());
|
||||
if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) {
|
||||
if (permanent != null && permanent.isControlledBy(source.getControllerId())) {
|
||||
return super.applies(event, source, game);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
|
@ -19,13 +20,12 @@ import mage.target.TargetPermanent;
|
|||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class CrabUmbra extends CardImpl {
|
||||
|
||||
public CrabUmbra(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}");
|
||||
this.subtype.add(SubType.AURA);
|
||||
|
||||
|
||||
|
@ -35,8 +35,11 @@ public final class CrabUmbra extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
|
||||
Ability ability = new EnchantAbility(auraTarget.getTargetName());
|
||||
this.addAbility(ability);
|
||||
|
||||
// {2}{U}: Untap enchanted creature.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new ManaCostsImpl("{2}{U}")));
|
||||
|
||||
// Totem armor
|
||||
this.addAbility(new TotemArmorAbility());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -9,17 +8,21 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Loki
|
||||
*/
|
||||
public final class Cremate extends CardImpl {
|
||||
|
||||
public Cremate(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
|
||||
|
||||
// Exile target card from a graveyard.
|
||||
this.getSpellAbility().addEffect(new ExileTargetEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard());
|
||||
|
||||
// Draw a card.
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue