Merge remote-tracking branch 'refs/remotes/magefree/master'

This commit is contained in:
shootbot 2016-06-30 19:01:13 +06:00
commit 94f63acf0a
150 changed files with 6454 additions and 1018 deletions

View file

@ -1,5 +1,5 @@
XMage.de 1 (Europe/Germany) fast :xmage.de:17171
woogerworks (North America/USA) :xmage.woogerworks.info:17171
woogerworks (North America/USA) :xmage.woogerworks.com:17171
XMage Testserver (Europe/France) 1.4.8v0 :176.31.186.181:17171
XMage BR (South America/Brazil) :ec2-54-233-67-0.sa-east-1.compute.amazonaws.com:17171
XMage.tahiti :xmage.tahiti.one:443

View file

@ -43,6 +43,7 @@ import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
@ -61,6 +62,7 @@ import javax.imageio.ImageIO;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
@ -75,6 +77,7 @@ import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.JToolBar.Separator;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@ -116,6 +119,7 @@ import mage.client.table.TablesPane;
import mage.client.tournament.TournamentPane;
import mage.client.util.EDTExceptionHandler;
import mage.client.util.GUISizeHelper;
import mage.client.util.ImageCaches;
import mage.client.util.SettingsManager;
import mage.client.util.SystemUtil;
import mage.client.util.audio.MusicPlayer;
@ -242,6 +246,18 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
try {
UIManager.put("desktop", new Color(0, 0, 0, 0));
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
// stop JSplitPane from eating F6 and F8 or any other function keys
{
Object value = UIManager.get("SplitPane.ancestorInputMap");
if(value instanceof InputMap) {
InputMap map = (InputMap)value;
for(int vk = KeyEvent.VK_F2; vk <= KeyEvent.VK_F12; ++vk) {
map.remove(KeyStroke.getKeyStroke(vk, 0));
}
}
}
GUISizeHelper.calculateGUISizes();
// UIManager.put("Table.rowHeight", GUISizeHelper.tableRowHeight);
} catch (Exception ex) {
@ -1455,6 +1471,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
public void changeGUISize() {
ImageCaches.flush();
setGUISize();
Plugins.getInstance().changeGUISize();
CountryUtil.changeGUISize();

View file

@ -54,6 +54,7 @@ import mage.client.plugins.impl.Plugins;
import mage.client.util.ImageHelper;
import mage.constants.EnlargeMode;
import org.jdesktop.swingx.JXPanel;
import mage.client.util.TransformedImageCache;
/**
* Class for displaying big image of the card
@ -103,7 +104,13 @@ public class BigCard extends JComponent {
}
public void setCard(UUID cardId, EnlargeMode enlargeMode, Image image, List<String> strings) {
public void setCard(UUID cardId, EnlargeMode enlargeMode, Image image, List<String> strings, boolean rotate) {
if (rotate && getWidth() > getHeight()) {
image = TransformedImageCache.getRotatedResizedImage((BufferedImage)image, getHeight(), getWidth(), Math.toRadians(90.0));
} else {
image = TransformedImageCache.getResizedImage((BufferedImage)image, getWidth(), getHeight());
}
if (this.cardId == null || !enlargeMode.equals(this.enlargeMode) || !this.cardId.equals(cardId)) {
if (this.panel != null) {
remove(this.panel);

View file

@ -374,7 +374,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
@Override
public void mouseMoved(MouseEvent arg0) {
this.bigCard.showTextComponent();
this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules());
this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules(), false);
}
@Override

View file

@ -236,7 +236,7 @@ public class CardArea extends JPanel implements MouseListener {
public void mousePressed(MouseEvent e) {
if (e.getClickCount() >= 1 && !e.isConsumed()) {
Object obj = e.getSource();
if (e.getClickCount() == 2) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
e.consume();
if (obj instanceof Card) {
if (e.isAltDown()) {

View file

@ -308,7 +308,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener,
// End of variables declaration//GEN-END:variables
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && !e.isConsumed()) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
Object obj = e.getSource();
if (obj instanceof Card) {

View file

@ -200,7 +200,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar
mainTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 2 && !e.isConsumed()) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
if (e.isAltDown()) {
handleAltDoubleClick();
@ -755,7 +755,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar
public void mousePressed(MouseEvent e) {
if (e.getClickCount() >= 1 && !e.isConsumed()) {
Object obj = e.getSource();
if (e.getClickCount() == 2) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
e.consume();
if (obj instanceof Card) {
if (e.isAltDown()) {

View file

@ -183,7 +183,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
if (e.getButton() == MouseEvent.BUTTON1) {
Object obj = e.getSource();
if (obj instanceof MageCard) {

View file

@ -56,6 +56,8 @@ import mage.client.util.ImageHelper;
import mage.constants.CardType;
import mage.view.CounterView;
import mage.view.PermanentView;
import org.mage.plugins.card.images.ImageCache;
import mage.client.util.TransformedImageCache;
/**
*
@ -215,7 +217,7 @@ public class Permanent extends Card {
Graphics2D g = (Graphics2D) tappedImage.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(this.createImage(ImageHelper.rotate(small, dimension)), 0, 0, this);
g.drawImage(TransformedImageCache.getRotatedResizedImage(small, dimension.frameWidth, dimension.frameHeight, Math.toRadians(90.0)), 0, 0, this);
g.dispose();
}

View file

@ -139,9 +139,7 @@ public class ColorPane extends JEditorPane {
if (hyperlinkEnabled) {
text = text.replaceAll("(<font color=[^>]*>([^<]*)) (\\[[0-9a-fA-F]*\\])</font>", "<a href=\"#$2\">$1</a> $3");
}
setEditable(true);
kit.insertHTML(doc, doc.getLength(), text, 0, 0, null);
setEditable(false);
int len = getDocument().getLength();
setCaretPosition(len);

View file

@ -1,12 +1,18 @@
package mage.client.components;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.Objects;
import javax.swing.JPanel;
import mage.client.util.ImageCaches;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import org.jdesktop.swingx.graphics.ShadowRenderer;
@ -21,23 +27,145 @@ public class MageRoundPane extends JPanel {
private int X_OFFSET = 30;
private int Y_OFFSET = 30;
private BufferedImage shadow = null;
private final Color defaultBackgroundColor = new Color(255, 255, 255, 200);
private Color backgroundColor = defaultBackgroundColor;
private final int alpha = 0;
private static Map<ShadowKey, BufferedImage> SHADOW_IMAGE_CACHE;
private static Map<Key, BufferedImage> IMAGE_CACHE;
static {
SHADOW_IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<ShadowKey, BufferedImage>() {
@Override
public BufferedImage apply(ShadowKey key) {
return createShadowImage(key);
}
}));
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, BufferedImage>() {
@Override
public BufferedImage apply(Key key) {
return createImage(key);
}
}));
}
private final static class ShadowKey
{
final int width;
final int height;
public ShadowKey(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + this.width;
hash = 97 * hash + this.height;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ShadowKey other = (ShadowKey) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
return true;
}
}
private final static class Key
{
final int width;
final int height;
final int xOffset;
final int yOffset;
final Color backgroundColor;
public Key(int width, int height, int xOffset, int yOffset, Color backgroundColor) {
this.width = width;
this.height = height;
this.xOffset = xOffset;
this.yOffset = yOffset;
this.backgroundColor = backgroundColor;
}
@Override
public int hashCode() {
int hash = 5;
hash = 59 * hash + this.width;
hash = 59 * hash + this.height;
hash = 59 * hash + this.xOffset;
hash = 59 * hash + this.yOffset;
hash = 59 * hash + Objects.hashCode(this.backgroundColor);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
if (this.xOffset != other.xOffset) {
return false;
}
if (this.yOffset != other.yOffset) {
return false;
}
if (!Objects.equals(this.backgroundColor, other.backgroundColor)) {
return false;
}
return true;
}
}
@Override
protected void paintComponent(Graphics g) {
int x = X_OFFSET;
int y = Y_OFFSET;
int w = getWidth() - 2 * X_OFFSET;
int h = getHeight() - 2 * Y_OFFSET;
g.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), X_OFFSET, Y_OFFSET, backgroundColor)), 0, 0, null);
}
private static BufferedImage createImage(Key key) {
int x = key.xOffset;
int y = key.yOffset;
int w = key.width - 2 * key.xOffset;
int h = key.height - 2 * key.yOffset;
int arc = 10;
Graphics2D g2 = (Graphics2D) g.create();
BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (shadow != null) {
BufferedImage shadow = SHADOW_IMAGE_CACHE.get(new ShadowKey(w, h));
{
int xOffset = (shadow.getWidth() - w) / 2;
int yOffset = (shadow.getHeight() - h) / 2;
g2.drawImage(shadow, x - xOffset, y - yOffset, null);
@ -54,7 +182,7 @@ public class MageRoundPane extends JPanel {
g2.fillRoundRect(x, y, w, h, arc, arc);
}*/
g2.setColor(backgroundColor);
g2.setColor(key.backgroundColor);
g2.fillRoundRect(x, y, w, h, arc, arc);
//////////////////////////////////////////////////////////////////
@ -66,6 +194,7 @@ public class MageRoundPane extends JPanel {
// ////////////////////////////////////////////////////////////////
g2.dispose();
return image;
}
public void setXOffset(int x_offset) {
@ -76,24 +205,21 @@ public class MageRoundPane extends JPanel {
Y_OFFSET = y_offset;
}
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
int w = getWidth() - 2 * X_OFFSET;
int h = getHeight() - 2 * Y_OFFSET;
private static BufferedImage createShadowImage(ShadowKey key) {
int w = key.width;
int h = key.height;
int arc = 10;
int shadowSize = 50;
shadow = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
Graphics2D g2 = shadow.createGraphics();
BufferedImage base = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
Graphics2D g2 = base.createGraphics();
g2.setColor(Color.WHITE);
g2.fillRoundRect(0, 0, w, h, arc, arc);
g2.dispose();
ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f,
Color.GRAY);
shadow = renderer.createShadow(shadow);
return renderer.createShadow(base);
}
public void showDialog(boolean bShow) {

View file

@ -13,6 +13,8 @@ import org.mage.card.arcane.UI;
* @author nantuko
*/
public class MageTextArea extends JEditorPane {
private String currentText;
private int currentPanelWidth;
public MageTextArea() {
UI.setHTMLEditorKit(this);
@ -31,6 +33,12 @@ public class MageTextArea extends JEditorPane {
return;
}
if(text.equals(currentText) && panelWidth == currentPanelWidth)
return;
currentText = text;
currentPanelWidth = panelWidth;
final StringBuilder buffer = new StringBuilder(512);
// Dialog is a java logical font family, so it should work on all systems
buffer.append("<html><body style='font-family:Dialog;font-size:");

View file

@ -157,7 +157,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
mainTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 2 && !e.isConsumed()) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
if (e.isAltDown()) {
jButtonAddToSideboardActionPerformed(null);

View file

@ -409,8 +409,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
Image image = Plugins.getInstance().getOriginalImage(card);
if (image != null && image instanceof BufferedImage) {
// XXX: scaled to fit width
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth());
bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, new ArrayList<String>());
bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, new ArrayList<String>(), false);
} else {
drawCardText(card);
}

View file

@ -228,7 +228,7 @@ public class DraftPanel extends javax.swing.JPanel {
int height = left * 18;
lblTableImage.setSize(new Dimension(lblTableImage.getWidth(), height));
Image tableImage = ImageHelper.getImageFromResources(draftView.getBoosterNum() == 2 ? "/draft/table_left.png" : "/draft/table_right.png");
BufferedImage resizedTable = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(tableImage, BufferedImage.TYPE_INT_ARGB), lblTableImage.getWidth());
BufferedImage resizedTable = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(tableImage, BufferedImage.TYPE_INT_ARGB), lblTableImage.getWidth(), lblTableImage.getHeight());
lblTableImage.setIcon(new ImageIcon(resizedTable));
int count = 0;

View file

@ -30,6 +30,7 @@ package mage.client.game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
@ -156,6 +157,7 @@ public final class GamePanel extends javax.swing.JPanel {
private static final String CMD_AUTO_ORDER_RESET_ALL = "cmdAutoOrderResetAll";
private final Map<UUID, PlayAreaPanel> players = new HashMap<>();
private final Map<UUID, Boolean> playersWhoLeft = new HashMap<>();
// non modal frames
private final Map<UUID, CardInfoWindowDialog> exiles = new HashMap<>();
@ -309,6 +311,7 @@ public final class GamePanel extends javax.swing.JPanel {
playAreaPanelEntry.getValue().CleanUp();
}
this.players.clear();
this.playersWhoLeft.clear();
jLayeredPane.remove(abilityPicker);
this.abilityPicker.cleanUp();
@ -594,6 +597,7 @@ public final class GamePanel extends javax.swing.JPanel {
private void addPlayers(GameView game) {
this.players.clear();
this.playersWhoLeft.clear();
this.pnlBattlefield.removeAll();
//arrange players in a circle with the session player at the bottom left
int numSeats = game.getPlayers().size();
@ -614,6 +618,7 @@ public final class GamePanel extends javax.swing.JPanel {
PlayAreaPanel playAreaPanel = new PlayAreaPanel(player, bigCard, gameId, game.getPriorityTime(), this,
new PlayAreaPanelOptions(game.isPlayer(), game.isPlayer(), game.isRollbackTurnsAllowed()));
players.put(player.getPlayerId(), playAreaPanel);
playersWhoLeft.put(player.getPlayerId(), false);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.5;
@ -622,8 +627,19 @@ public final class GamePanel extends javax.swing.JPanel {
c.gridwidth = 2;
}
c.gridx = col;
c.gridy = row;
this.pnlBattlefield.add(playAreaPanel, c);
c.gridy = 0;
// Top panel (row=0)
JPanel topPanel = new JPanel();
topPanel.setOpaque(false);
// Bottom panel (row=1)
JPanel bottomPanel = new JPanel();
bottomPanel.setOpaque(false);
topPanel.setLayout(new GridBagLayout());
bottomPanel.setLayout(new GridBagLayout());
bottomPanel.add(playAreaPanel, c);
playAreaPanel.setVisible(true);
if (oddNumber) {
col++;
@ -646,13 +662,20 @@ public final class GamePanel extends javax.swing.JPanel {
PlayAreaPanel playerPanel = new PlayAreaPanel(player, bigCard, gameId, game.getPriorityTime(), this,
new PlayAreaPanelOptions(game.isPlayer(), false, game.isRollbackTurnsAllowed()));
players.put(player.getPlayerId(), playerPanel);
playersWhoLeft.put(player.getPlayerId(), false);
c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.5;
c.weighty = 0.5;
c.gridx = col;
c.gridy = row;
this.pnlBattlefield.add(playerPanel, c);
c.gridy = 0;
if (row == 0) {
topPanel.add(playerPanel, c);
} else {
bottomPanel.add(playerPanel, c);
}
playerPanel.setVisible(true);
playerNum++;
if (playerNum >= numSeats) {
@ -665,6 +688,16 @@ public final class GamePanel extends javax.swing.JPanel {
for (PlayAreaPanel p : players.values()) {
p.sizePlayer(smallMode);
}
GridBagConstraints panelC = new GridBagConstraints();
panelC.fill = GridBagConstraints.BOTH;
panelC.weightx = 0.5;
panelC.weighty = 0.5;
panelC.gridwidth = 1;
panelC.gridy = 0;
this.pnlBattlefield.add(topPanel, panelC);
panelC.gridy = 1;
this.pnlBattlefield.add(bottomPanel, panelC);
}
public synchronized void updateGame(GameView game) {
@ -838,6 +871,42 @@ public final class GamePanel extends javax.swing.JPanel {
CombatManager.getInstance().hideCombat(gameId);
}
for (PlayerView player : game.getPlayers()) {
if (player.hasLeft() && !playersWhoLeft.get(player.getPlayerId())) {
PlayAreaPanel playerLeftPanel = players.get(player.getPlayerId());
playersWhoLeft.put(player.getPlayerId(), true);
Container parent = playerLeftPanel.getParent();
GridBagLayout layout = (GridBagLayout) parent.getLayout();
for (Component otherPanel : parent.getComponents()) {
if (otherPanel instanceof PlayAreaPanel) {
GridBagConstraints gbc = layout.getConstraints(otherPanel);
if (gbc.weightx > 0.1) {
gbc.weightx = 0.99;
}
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.WEST;
if (gbc.gridx > 0) {
gbc.anchor = GridBagConstraints.EAST;
}
if (otherPanel == playerLeftPanel) {
gbc.weightx = 0.01;
Dimension d = playerLeftPanel.getPreferredSize();
d.width = 95;
otherPanel.setPreferredSize(d);
}
parent.remove(otherPanel);
parent.add(otherPanel, gbc);
}
}
parent.validate();
parent.repaint();
}
}
feedbackPanel.disableUndo();
this.revalidate();
@ -1431,6 +1500,15 @@ public final class GamePanel extends javax.swing.JPanel {
}
});
ks = KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0);
this.getInputMap(c).put(ks, "F6_PRESS");
this.getActionMap().put("F6_PRESS", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
btnEndTurnSkipStackActionPerformed(actionEvent);
}
});
btnSkipToNextMain.setContentAreaFilled(false);
btnSkipToNextMain.setBorder(new EmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
btnSkipToNextMain.setIcon(new ImageIcon(ImageManagerImpl.getInstance().getSkipMainButtonImage()));
@ -2023,6 +2101,12 @@ public final class GamePanel extends javax.swing.JPanel {
updateSkipButtons(false, true, false, false, false, false);
}
private void btnEndTurnSkipStackActionPerformed(java.awt.event.ActionEvent evt) {
session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
AudioManager.playOnSkipButton();
updateSkipButtons(true, false, false, false, true, false);
}
private void btnUntilNextMainPhaseActionPerformed(java.awt.event.ActionEvent evt) {
session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
AudioManager.playOnSkipButton();

View file

@ -178,6 +178,10 @@ public class PlayAreaPanel extends javax.swing.JPanel {
gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
break;
}
case "F6": {
gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
break;
}
case "F7": {
gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
break;
@ -211,6 +215,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
popupMenu.add(skipMenu);
String tooltipText = "<html>This skip actions stops if something goes to <br><b>stack</b> and if <b>attackers</b> or <b>blocker</b> have to be <b>declared</b>.";
String everythingTooltipText = "<html>This skip actions stops if <b>attackers</b> or <b>blocker</b> have to be <b>declared</b>, but not if something goes to the <b>stack</b>.";
menuItem = new JMenuItem("<html><b>F4</b> - Phases until next turn");
menuItem.setActionCommand("F4");
menuItem.setToolTipText(tooltipText);
@ -225,6 +230,13 @@ public class PlayAreaPanel extends javax.swing.JPanel {
skipMenu.add(menuItem);
menuItem.addActionListener(skipListener);
menuItem = new JMenuItem("<html><b>F6</b> - Everything until the next turn");
menuItem.setActionCommand("F6");
menuItem.setToolTipText(everythingTooltipText);
menuItem.setMnemonic(KeyEvent.VK_U);
skipMenu.add(menuItem);
menuItem.addActionListener(skipListener);
menuItem = new JMenuItem("<html><b>F7</b> - Phases until begin of next main phase");
menuItem.setToolTipText(tooltipText);
menuItem.setActionCommand("F7");
@ -234,14 +246,14 @@ public class PlayAreaPanel extends javax.swing.JPanel {
menuItem = new JMenuItem("<html><b>F9</b> - Everything until your own next turn");
menuItem.setActionCommand("F9");
menuItem.setToolTipText(tooltipText);
menuItem.setToolTipText(everythingTooltipText);
menuItem.setMnemonic(KeyEvent.VK_V);
skipMenu.add(menuItem);
menuItem.addActionListener(skipListener);
menuItem = new JMenuItem("<html><b>F11</b> - Everything until end step prior to your own next turn");
menuItem.setActionCommand("F11");
menuItem.setToolTipText(tooltipText);
menuItem.setToolTipText(everythingTooltipText);
menuItem.setMnemonic(KeyEvent.VK_P);
skipMenu.add(menuItem);
menuItem.addActionListener(skipListener);

View file

@ -112,6 +112,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
private static final Border RED_BORDER = new LineBorder(Color.red, 2);
private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(0, 0, 0, 0);
private final Color greenBackgroundColor = new Color(180, 255, 180, 200);
private final Color deadBackgroundColor = new Color(200, 180, 180, 200);
private int avatarId = -1;
private String flagName;
@ -222,7 +223,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
}
graveLabel.setText(Integer.toString(graveCards));
graveLabel.setToolTipText("Card Types: " + qtyCardTypes(player.getGraveyard()));
int exileCards = player.getExile().size();
if (exileCards > 99) {
if (!changedFontExile) {
@ -282,6 +283,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
if (player.hasLeft()) {
this.avatar.setBorder(RED_BORDER);
this.btnPlayer.setBorder(RED_BORDER);
setDeadBackgroundColor();
} else {
this.avatar.setBorder(EMPTY_BORDER);
this.btnPlayer.setBorder(EMPTY_BORDER);
@ -299,6 +301,10 @@ public class PlayerPanelExt extends javax.swing.JPanel {
panelBackground.setBackgroundColor(greenBackgroundColor);
}
private void setDeadBackgroundColor() {
panelBackground.setBackgroundColor(deadBackgroundColor);
}
/**
* Updates the avatar image and tooltip text
*/
@ -878,7 +884,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
if (cardTypesPresent.isEmpty()) return 0;
else return cardTypesPresent.size();
}
private HoverButton avatar;
private JLabel avatarFlag;
private JButton btnPlayer;

View file

@ -155,6 +155,7 @@ public class MageActionCallback implements ActionCallback {
}
data.locationOnScreen = data.component.getLocationOnScreen();
}
data.popupText.updateText();
tooltipPopup = factory.getPopup(data.component, data.popupText, (int) data.locationOnScreen.getX() + data.popupOffsetX, (int) data.locationOnScreen.getY() + data.popupOffsetY + 40);
tooltipPopup.show();
// hack to get popup to resize to fit text
@ -597,13 +598,7 @@ public class MageActionCallback implements ActionCallback {
private void displayCardInfo(MageCard mageCard, Image image, BigCard bigCard) {
if (image != null && image instanceof BufferedImage) {
// XXX: scaled to fit width
if (mageCard.getOriginal().isToRotate() && bigCard.getWidth() > bigCard.getHeight()) {
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getHeight());
image = ImageHelper.rotate((BufferedImage) image, Math.toRadians(90));
} else {
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth());
}
bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules());
bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules(), mageCard.getOriginal().isToRotate());
// if it's an ability, show only the ability text as overlay
if (mageCard.getOriginal().isAbility() && enlargeMode.equals(EnlargeMode.NORMAL)) {
bigCard.showTextComponent();

View file

@ -391,6 +391,7 @@ public class CallbackClientImpl implements CallbackClient {
.append("<br/><b>F2</b> - Confirm \"Ok\", \"Yes\" or \"Done\" button")
.append("<br/><b>F4</b> - Skip current turn but stop on declare attackers/blockers and something on the stack")
.append("<br/><b>F5</b> - Skip to next end step but stop on declare attackers/blockers and something on the stack")
.append("<br/><b>F6</b> - Skip current turn but stop on declare attackers/blockers")
.append("<br/><b>F7</b> - Skip to next main phase but stop on declare attackers/blockers and something on the stack")
.append("<br/><b>F9</b> - Skip everything until your next turn")
.append("<br/><b>F11</b> - Skip everything until the end step just prior to your turn")

View file

@ -418,6 +418,40 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFilterActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JToolBar$Separator" name="jSeparator5">
</Component>
<Component class="javax.swing.JToggleButton" name="btnOpen">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="Open"/>
<Property name="toolTipText" type="java.lang.String" value="Show open games"/>
<Property name="focusPainted" type="boolean" value="false"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
<Property name="verifyInputWhenFocusTarget" type="boolean" value="false"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFilterActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JToggleButton" name="btnPassword">
<Properties>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" value="PW"/>
<Property name="toolTipText" type="java.lang.String" value="Show passworded games"/>
<Property name="focusPainted" type="boolean" value="false"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="requestFocusEnabled" type="boolean" value="false"/>
<Property name="verifyInputWhenFocusTarget" type="boolean" value="false"/>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnFilterActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="btnQuickStart">

View file

@ -158,7 +158,7 @@ public class TablesPanel extends javax.swing.JPanel {
filterButtons = new JToggleButton[]{btnStateWaiting, btnStateActive, btnStateFinished,
btnTypeMatch, btnTypeTourneyConstructed, btnTypeTourneyLimited,
btnFormatBlock, btnFormatStandard, btnFormatModern, btnFormatLegacy, btnFormatVintage, btnFormatCommander, btnFormatTinyLeader, btnFormatLimited, btnFormatOther,
btnSkillBeginner, btnSkillCasual, btnSkillSerious, btnRated, btnUnrated};
btnSkillBeginner, btnSkillCasual, btnSkillSerious, btnRated, btnUnrated, btnOpen, btnPassword};
JComponent[] components = new JComponent[]{chatPanelMain, jSplitPane1, jScrollPaneTablesActive, jScrollPaneTablesFinished, jPanelTop, jPanelTables};
for (JComponent component : components) {
@ -625,9 +625,19 @@ public class TablesPanel extends javax.swing.JPanel {
if (btnUnrated.isSelected()){
ratingFilterList.add(RowFilter.regexFilter("^Unrated", TableTableModel.COLUMN_RATING));
}
// Password
List<RowFilter<Object, Object>> passwordFilterList = new ArrayList<>();
if (btnOpen.isSelected()) {
passwordFilterList.add(RowFilter.regexFilter("^$", TableTableModel.COLUMN_PASSWORD));
}
if (btnPassword.isSelected()) {
passwordFilterList.add(RowFilter.regexFilter("^\\*\\*\\*$", TableTableModel.COLUMN_PASSWORD));
}
if (stateFilterList.isEmpty() || typeFilterList.isEmpty() || formatFilterList.isEmpty()
|| skillFilterList.isEmpty() || ratingFilterList.isEmpty()) { // no selection
|| skillFilterList.isEmpty() || ratingFilterList.isEmpty()
|| passwordFilterList.isEmpty()) { // no selection
activeTablesSorter.setRowFilter(RowFilter.regexFilter("Nothing", TableTableModel.COLUMN_SKILL));
} else {
List<RowFilter<Object, Object>> filterList = new ArrayList<>();
@ -661,6 +671,12 @@ public class TablesPanel extends javax.swing.JPanel {
} else if (ratingFilterList.size() == 1) {
filterList.addAll(ratingFilterList);
}
if (passwordFilterList.size() > 1) {
filterList.add(RowFilter.orFilter(passwordFilterList));
} else if (passwordFilterList.size() == 1) {
filterList.addAll(passwordFilterList);
}
if (filterList.size() == 1) {
activeTablesSorter.setRowFilter(filterList.get(0));
@ -710,6 +726,9 @@ public class TablesPanel extends javax.swing.JPanel {
jSeparator2 = new javax.swing.JToolBar.Separator();
btnFormatLimited = new javax.swing.JToggleButton();
btnFormatOther = new javax.swing.JToggleButton();
jSeparator5 = new javax.swing.JToolBar.Separator();
btnOpen = new javax.swing.JToggleButton();
btnPassword = new javax.swing.JToggleButton();
btnQuickStart = new javax.swing.JButton();
jSplitPane1 = new javax.swing.JSplitPane();
jPanelTables = new javax.swing.JPanel();
@ -1079,6 +1098,39 @@ public class TablesPanel extends javax.swing.JPanel {
}
});
filterBar2.add(btnFormatOther);
filterBar2.add(jSeparator5);
btnOpen.setSelected(true);
btnOpen.setText("Open");
btnOpen.setToolTipText("Show open games");
btnOpen.setFocusPainted(false);
btnOpen.setFocusable(false);
btnOpen.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnOpen.setRequestFocusEnabled(false);
btnOpen.setVerifyInputWhenFocusTarget(false);
btnOpen.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFilterActionPerformed(evt);
}
});
filterBar2.add(btnOpen);
btnPassword.setSelected(true);
btnPassword.setText("PW");
btnPassword.setToolTipText("Show passworded games");
btnPassword.setFocusPainted(false);
btnPassword.setFocusable(false);
btnPassword.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
btnPassword.setRequestFocusEnabled(false);
btnPassword.setVerifyInputWhenFocusTarget(false);
btnPassword.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
btnPassword.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnFilterActionPerformed(evt);
}
});
filterBar2.add(btnPassword);
btnQuickStart.setText("Quick Start");
btnQuickStart.setFocusable(false);
@ -1290,6 +1342,8 @@ public class TablesPanel extends javax.swing.JPanel {
private javax.swing.JToggleButton btnFormatVintage;
private javax.swing.JButton btnNewTable;
private javax.swing.JButton btnNewTournament;
private javax.swing.JToggleButton btnOpen;
private javax.swing.JToggleButton btnPassword;
private javax.swing.JButton btnQuickStart;
private javax.swing.JToggleButton btnSkillBeginner;
private javax.swing.JToggleButton btnSkillCasual;
@ -1337,12 +1391,14 @@ class TableTableModel extends AbstractTableModel {
public static final int COLUMN_GAME_TYPE = 3;
public static final int COLUMN_INFO = 4;
public static final int COLUMN_STATUS = 5;
public static final int COLUMN_SKILL = 7;
public static final int COLUMN_RATING = 8;
public static final int COLUMN_QUIT_RATIO = 9;
public static final int ACTION_COLUMN = 10; // column the action is located (starting with 0)
public static final int COLUMN_PASSWORD = 6;
public static final int COLUMN_CREATED = 7;
public static final int COLUMN_SKILL = 8;
public static final int COLUMN_RATING = 9;
public static final int COLUMN_QUIT_RATIO = 10;
public static final int ACTION_COLUMN = 11; // column the action is located (starting with 0)
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"};
private final String[] columnNames = new String[]{"M/T", "Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Password", "Created / Started", "Skill Level", "Rating", "Quit %", "Action"};
private TableView[] tables = new TableView[0];
private static final DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss");
@ -1385,14 +1441,16 @@ class TableTableModel extends AbstractTableModel {
case 5:
return tables[arg0].getTableStateText();
case 6:
return timeFormatter.format(tables[arg0].getCreateTime());
return tables[arg0].isPassworded() ? "***" : "";
case 7:
return tables[arg0].getSkillLevel();
return timeFormatter.format(tables[arg0].getCreateTime());
case 8:
return tables[arg0].isRated() ? "Rated" : "Unrated";
return tables[arg0].getSkillLevel();
case 9:
return tables[arg0].getQuitRatio();
return tables[arg0].isRated() ? "Rated" : "Unrated";
case 10:
return tables[arg0].getQuitRatio();
case 11:
switch (tables[arg0].getTableState()) {
case WAITING:
@ -1419,14 +1477,14 @@ class TableTableModel extends AbstractTableModel {
default:
return "";
}
case 11:
return tables[arg0].isTournament();
case 12:
return tables[arg0].isTournament();
case 13:
if (!tables[arg0].getGames().isEmpty()) {
return tables[arg0].getGames().get(0);
}
return null;
case 13:
case 14:
return tables[arg0].getTableId();
}
return "";

View file

@ -111,7 +111,7 @@ public class ButtonColumn extends AbstractCellEditor implements TableCellRendere
@Override
public void actionPerformed(ActionEvent e) {
if (table.getRowCount() > 0 && table.getRowCount() >= table.getEditingRow()) {
if (table.getRowCount() > 0 && table.getRowCount() >= table.getEditingRow() && table.getEditingRow() >= 0) {
int row = table.convertRowIndexToModel(table.getEditingRow());
fireEditingStopped();
ActionEvent event = new ActionEvent(table, ActionEvent.ACTION_PERFORMED, "" + row);

View file

@ -0,0 +1,34 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.util;
import java.util.Map;
import java.util.Vector;
/**
*
* @author user
*/
public class ImageCaches {
private static Vector<Map> IMAGE_CACHES;
static {
IMAGE_CACHES = new Vector<Map>();
}
public static Map register(Map map)
{
IMAGE_CACHES.add(map);
return map;
}
public static void flush()
{
for (Map map : IMAGE_CACHES) {
map.clear();
}
}
}

View file

@ -52,6 +52,7 @@ import static mage.client.constants.Constants.FRAME_MAX_WIDTH;
import static mage.client.constants.Constants.SYMBOL_MAX_SPACE;
import mage.view.CardView;
import org.mage.card.arcane.UI;
import org.mage.plugins.card.images.ImageCache;
/**
*
@ -70,21 +71,6 @@ public class ImageHelper {
return null;
}
/**
*
* @param ref - image name
* @param height - height after scaling
* @return a scaled image that preserves the original aspect ratio, with a
* specified height
*/
public static BufferedImage loadImage(String ref, int height) {
BufferedImage image = loadImage(ref);
if (image != null) {
return scaleImage(image, height);
}
return null;
}
public static BufferedImage loadImage(String ref) {
if (!images.containsKey(ref)) {
try {
@ -107,67 +93,7 @@ public class ImageHelper {
}
public static BufferedImage scaleImage(BufferedImage image, int width, int height) {
BufferedImage scaledImage = image;
int w = image.getWidth();
int h = image.getHeight();
do {
w /= 2;
h /= 2;
if (w < width || h < height) {
w = width;
h = height;
}
BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = newImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(scaledImage, 0, 0, w, h, null);
graphics2D.dispose();
scaledImage = newImage;
} while (w != width || h != height);
return scaledImage;
}
public static BufferedImage scaleImage(BufferedImage image, int height) {
double ratio = height / (double) image.getHeight();
int width = (int) (image.getWidth() * ratio);
return scaleImage(image, width, height);
}
public static MemoryImageSource rotate(Image image, CardDimensions dimensions) {
int buffer[] = new int[dimensions.frameWidth * dimensions.frameHeight];
int rotate[] = new int[dimensions.frameHeight * dimensions.frameWidth];
PixelGrabber grabber = new PixelGrabber(image, 0, 0, dimensions.frameWidth, dimensions.frameHeight, buffer, 0, dimensions.frameWidth);
try {
grabber.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int y = 0; y < dimensions.frameHeight; y++) {
for (int x = 0; x < dimensions.frameWidth; x++) {
rotate[((dimensions.frameWidth - x - 1) * dimensions.frameHeight) + y] = buffer[(y * dimensions.frameWidth) + x];
}
}
return new MemoryImageSource(dimensions.frameHeight, dimensions.frameWidth, rotate, 0, dimensions.frameHeight);
}
public static BufferedImage rotate(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
int w = image.getWidth(), h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = result.createGraphics();
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.drawRenderedImage(image, null);
g.dispose();
return result;
return TransformedImageCache.getResizedImage(image, width, height);
}
public static void drawCosts(List<String> costs, Graphics2D g, int xOffset, int yOffset, ImageObserver o) {
@ -191,26 +117,7 @@ public class ImageHelper {
* @return
*/
public static BufferedImage getResizedImage(BufferedImage original, int width, int height) {
ResampleOp resampleOp = new ResampleOp(width, height);
BufferedImage image = resampleOp.filter(original, null);
return image;
}
/**
* Returns an image scaled to fit width panel
*
* @param original
* @param width
* @return
*/
public static BufferedImage getResizedImage(BufferedImage original, int width) {
if (width != original.getWidth()) {
double ratio = width / (double) original.getWidth();
int height = (int) (original.getHeight() * ratio);
return getResizedImage(original, width, height);
} else {
return original;
}
return TransformedImageCache.getResizedImage(original, width, height);
}
/**
@ -223,17 +130,7 @@ public class ImageHelper {
* @return scaled image
*/
public static BufferedImage scale(BufferedImage sbi, int imageType, int dWidth, int dHeight) {
BufferedImage dbi = null;
if (sbi != null) {
double fWidth = dWidth / sbi.getWidth();
double fHeight = dHeight / sbi.getHeight();
dbi = new BufferedImage(dWidth, dHeight, imageType);
Graphics2D g = dbi.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(fWidth, fHeight);
g.drawRenderedImage(sbi, at);
g.dispose();
}
return dbi;
return TransformedImageCache.getResizedImage(sbi, dWidth, dHeight);
}
/**
@ -244,9 +141,7 @@ public class ImageHelper {
* @return
*/
public static BufferedImage getResizedImage(BufferedImage original, Rectangle sizeNeed) {
ResampleOp resampleOp = new ResampleOp(sizeNeed.width, sizeNeed.height);
BufferedImage image = resampleOp.filter(original, null);
return image;
return TransformedImageCache.getResizedImage(original, sizeNeed.width, sizeNeed.height);
}
/**

View file

@ -0,0 +1,153 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.util;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import com.mortennobel.imagescaling.ResampleOp;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.util.Map;
import mage.client.util.ImageHelper;
/**
*
* @author user
*/
public class TransformedImageCache {
private final static class Key
{
final int width;
final int height;
final double angle;
public Key(int width, int height, double angle) {
this.width = width;
this.height = height;
this.angle = angle;
}
@Override
public int hashCode() {
int hash = 3;
hash = 53 * hash + this.width;
hash = 53 * hash + this.height;
hash = 53 * hash + (int) (Double.doubleToLongBits(this.angle) ^ (Double.doubleToLongBits(this.angle) >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
if (Double.doubleToLongBits(this.angle) != Double.doubleToLongBits(other.angle)) {
return false;
}
return true;
}
}
static Map<Key, Map<BufferedImage, BufferedImage>> IMAGE_CACHE;
static
{
// TODO: can we use a single map?
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, Map<BufferedImage, BufferedImage>>() {
@Override
public Map<BufferedImage, BufferedImage> apply(final Key key) {
return new MapMaker().weakKeys().softValues().makeComputingMap(new Function<BufferedImage, BufferedImage>() {
@Override
public BufferedImage apply(BufferedImage image) {
if(key.width != image.getWidth() || key.height != image.getHeight())
image = resizeImage(image, key.width, key.height);
if(key.angle != 0.0)
image = rotateImage(image, key.angle);
return image;
}
});
}
}));
}
private static BufferedImage rotateImage(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
int w = image.getWidth(), h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = result.createGraphics();
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.drawRenderedImage(image, null);
g.dispose();
return result;
}
private static BufferedImage resizeImage(BufferedImage original, int width, int height) {
ResampleOp resampleOp = new ResampleOp(width, height);
BufferedImage image = resampleOp.filter(original, null);
return image;
}
public static BufferedImage getResizedImage(BufferedImage image, int width, int height)
{
return getRotatedResizedImage(image, width, height, 0.0);
}
public static BufferedImage getRotatedImage(BufferedImage image, double angle)
{
return getRotatedResizedImage(image, -1, -1, angle);
}
public static BufferedImage getRotatedResizedImage(BufferedImage image, int width, int height, double angle)
{
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
if(angle == 0.0 && (width < 0 || imageWidth == width) && (height < 0 || imageHeight == height))
return image;
int resWidth;
int resHeight;
if(width < 0 && height < 0) {
resWidth = imageWidth;
resHeight = imageHeight;
} else if((height < 0) || (width >= 0 && imageHeight * width <= imageWidth * height)) {
resWidth = width;
resHeight = imageHeight * width / imageWidth;
} else {
resWidth = imageWidth * height / imageHeight;
resHeight = height;
}
if(angle == 0.0 && imageWidth == resWidth && imageHeight == resHeight)
return image;
return IMAGE_CACHE.get(new Key(resWidth, resHeight, angle)).get(image);
}
}

View file

@ -5,6 +5,10 @@ import java.util.LinkedList;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
@ -19,8 +23,6 @@ import javax.sound.sampled.SourceDataLine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import mage.utils.ThreadUtils;
public class LinePool {
private final Logger log = LoggerFactory.getLogger(getClass());
@ -41,12 +43,25 @@ public class LinePool {
private Mixer mixer;
private int alwaysActive;
private ThreadPoolExecutor threadPool;
private int threadCount;
public LinePool() {
this(new AudioFormat(22050, 16, 1, true, false), 4, 1);
}
public LinePool(AudioFormat audioFormat, int size, int alwaysActive) {
threadPool = new ThreadPoolExecutor(alwaysActive, size, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadFactory() {
@Override
public Thread newThread (Runnable runnable) {
threadCount++;
Thread thread = new Thread(runnable, "Audio" + threadCount);
thread.setDaemon(true);
return thread;
}
});
threadPool.prestartAllCoreThreads();
format = audioFormat;
this.alwaysActive = alwaysActive;
mixer = AudioSystem.getMixer(null);
@ -95,7 +110,7 @@ public class LinePool {
busyLines.add(line);
logLineStats();
}
ThreadUtils.threadPool.submit(new Runnable() {
threadPool.submit(new Runnable() {
@Override
public void run() {

View file

@ -8,6 +8,8 @@ import java.util.Timer;
import java.util.TimerTask;
public abstract class Animation {
private static boolean ENABLED = true;
private static final long TARGET_MILLIS_PER_FRAME = 30;
private static Timer timer = new Timer("Animation", true);
@ -25,6 +27,18 @@ public abstract class Animation {
}
public Animation (final long duration, long delay) {
if(!ENABLED) {
UI.invokeLater(new Runnable() {
@Override
public void run () {
start();
//update(1.0f);
end();
}
});
return;
}
timerTask = new TimerTask() {
@Override
public void run () {
@ -171,6 +185,12 @@ public abstract class Animation {
@Override
protected void end () {
if (!state) {
parent.toggleTransformed();
}
state = true;
panel.transformAngle = 0;
parent.onEndAnimation();
parent.repaint();
}

View file

@ -1,5 +1,7 @@
package org.mage.card.arcane;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
@ -23,6 +25,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;
import javax.swing.BorderFactory;
@ -38,6 +41,7 @@ import mage.cards.action.TransferData;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ImageCaches;
import mage.client.util.ImageHelper;
import mage.client.util.audio.AudioManager;
import mage.components.ImagePanel;
@ -52,8 +56,7 @@ import mage.view.PermanentView;
import mage.view.StackAbilityView;
import net.java.truevfs.access.TFile;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
import org.mage.plugins.card.images.ImageCache;
@ -160,6 +163,111 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
// if this is set, it's opened if the user right clicks on the card panel
private JPopupMenu popupMenu;
private static Map<Key, BufferedImage> IMAGE_CACHE;
private final static class Key
{
final int width;
final int height;
final int cardWidth;
final int cardHeight;
final int cardXOffset;
final int cardYOffset;
final boolean hasImage;
final boolean isSelected;
final boolean isChoosable;
final boolean isPlayable;
final boolean canAttack;
public Key(int width, int height, int cardWidth, int cardHeight, int cardXOffset, int cardYOffset, boolean hasImage, boolean isSelected, boolean isChoosable, boolean isPlayable, boolean canAttack) {
this.width = width;
this.height = height;
this.cardWidth = cardWidth;
this.cardHeight = cardHeight;
this.cardXOffset = cardXOffset;
this.cardYOffset = cardYOffset;
this.hasImage = hasImage;
this.isSelected = isSelected;
this.isChoosable = isChoosable;
this.isPlayable = isPlayable;
this.canAttack = canAttack;
}
@Override
public int hashCode() {
int hash = 3;
hash = 19 * hash + this.width;
hash = 19 * hash + this.height;
hash = 19 * hash + this.cardWidth;
hash = 19 * hash + this.cardHeight;
hash = 19 * hash + this.cardXOffset;
hash = 19 * hash + this.cardYOffset;
hash = 19 * hash + (this.hasImage ? 1 : 0);
hash = 19 * hash + (this.isSelected ? 1 : 0);
hash = 19 * hash + (this.isChoosable ? 1 : 0);
hash = 19 * hash + (this.isPlayable ? 1 : 0);
hash = 19 * hash + (this.canAttack ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
if (this.cardWidth != other.cardWidth) {
return false;
}
if (this.cardHeight != other.cardHeight) {
return false;
}
if (this.cardXOffset != other.cardXOffset) {
return false;
}
if (this.cardYOffset != other.cardYOffset) {
return false;
}
if (this.hasImage != other.hasImage) {
return false;
}
if (this.isSelected != other.isSelected) {
return false;
}
if (this.isChoosable != other.isChoosable) {
return false;
}
if (this.isPlayable != other.isPlayable) {
return false;
}
if (this.canAttack != other.canAttack) {
return false;
}
return true;
}
}
static {
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, BufferedImage>() {
@Override
public BufferedImage apply(Key key) {
return createImage(key);
}
}));
}
public CardPanel(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) {
this.gameCard = newGameCard;
this.callback = callback;
@ -304,44 +412,23 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
imagePanel = new ScaledImagePanel();
imagePanel.setBorder(BorderFactory.createLineBorder(Color.white));
add(imagePanel);
imagePanel.setScaleLarger(true);
imagePanel.setScalingType(ScalingType.nearestNeighbor);
imagePanel.setScalingMultiPassType(MultipassType.none);
String cardType = getType(newGameCard);
tooltipText.setText(getText(cardType, newGameCard));
Util.threadPool.submit(new Runnable() {
@Override
public void run() {
try {
tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0;
if (!loadImage) {
return;
}
BufferedImage srcImage;
if (gameCard.isFaceDown()) {
srcImage = getFaceDownImage();
} else {
srcImage = ImageCache.getImage(gameCard, getCardWidth(), getCardHeight());
}
if (srcImage != null) {
hasImage = true;
setText(gameCard);
setImage(srcImage);
}
if (gameCard.isTransformed()) {
toggleTransformed();
}
setText(gameCard);
} catch (Exception e) {
LOGGER.fatal("Problem during image animation", e);
} catch (Error err) {
LOGGER.error("Problem during image animation", err);
}
}
});
tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0;
if (!loadImage) {
return;
}
if (gameCard.isTransformed()) {
// this calls updateImage
toggleTransformed();
} else {
updateImage();
}
}
private void setTypeIcon(BufferedImage bufferedImage, String toolTipText) {
@ -387,9 +474,12 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getName());
}
private void setImage(Image srcImage) {
private void setImage(BufferedImage srcImage) {
synchronized (imagePanel) {
imagePanel.setImage(srcImage);
if(srcImage != null)
imagePanel.setImage(srcImage);
else
imagePanel.clearImage();
repaint();
}
doLayout();
@ -413,10 +503,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
return zone;
}
public void setScalingType(ScalingType scalingType) {
imagePanel.setScalingType(scalingType);
}
public void setDisplayEnabled(boolean displayEnabled) {
this.displayEnabled = displayEnabled;
}
@ -484,15 +570,28 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Graphics2D g2d = (Graphics2D)(g.create());
if (alpha != 1.0f) {
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
g2d.setComposite(composite);
}
if (!hasImage) {
g2d.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), cardWidth, cardHeight, cardXOffset, cardYOffset, hasImage, isSelected, isChoosable, isPlayable, canAttack)), 0, 0, null);
g2d.dispose();
}
private static BufferedImage createImage(Key key) {
int cardWidth = key.cardWidth;
int cardHeight = key.cardHeight;
int cardXOffset = key.cardXOffset;
int cardYOffset = key.cardYOffset;
BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height);
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (!key.hasImage) {
g2d.setColor(new Color(30, 200, 200, 120));
} else {
g2d.setColor(new Color(0, 0, 0, 0));
@ -501,19 +600,19 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE));
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
if (isSelected) {
if (key.isSelected) {
g2d.setColor(Color.green);
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
} else if (isChoosable) {
} else if (key.isChoosable) {
g2d.setColor(new Color(250, 250, 0, 230));
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
} else if (isPlayable) {
} else if (key.isPlayable) {
g2d.setColor(new Color(153, 102, 204, 200));
//g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
}
if (canAttack) {
if (key.canAttack) {
g2d.setColor(new Color(0, 0, 255, 230));
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
}
@ -524,6 +623,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
g2d.setColor(new Color(200,10,10,200));
g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize);
}*/
g2d.dispose();
return image;
}
@Override
@ -619,12 +721,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2);
}
if (isAnimationPanel || cardWidth < 200) {
imagePanel.setScalingType(ScalingType.nearestNeighbor);
} else {
imagePanel.setScalingType(ScalingType.bilinear);
}
}
@Override
@ -634,6 +730,11 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public final void setCardBounds(int x, int y, int cardWidth, int cardHeight) {
if(cardWidth == this.cardWidth && cardHeight == this.cardHeight) {
setBounds(x - cardXOffset, y - cardYOffset, getWidth(), getHeight());
return;
}
this.cardWidth = cardWidth;
this.symbolWidth = cardWidth / 7;
this.cardHeight = cardHeight;
@ -656,6 +757,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
int height = cardYOffset * 2 + cardHeight;
setBounds(x - cardXOffset, y - cardYOffset, width, height);
}
if(imagePanel != null && imagePanel.getSrcImage() != null)
updateImage();
}
public int getXOffset(int cardWidth) {
@ -734,15 +837,21 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
return cardYOffset;
}
private int updateImageStamp;
@Override
public void updateImage() {
tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0;
final CardView gameCard = this.gameCard;
final int stamp = ++updateImageStamp;
Util.threadPool.submit(new Runnable() {
@Override
public void run() {
try {
tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
flippedAngle = isFlipped() ? CardPanel.FLIPPED_ANGLE : 0;
BufferedImage srcImage;
final BufferedImage srcImage;
if (gameCard.isFaceDown()) {
srcImage = getFaceDownImage();
} else if (cardWidth > THUMBNAIL_SIZE_FULL.width) {
@ -750,11 +859,16 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
} else {
srcImage = ImageCache.getThumbnail(gameCard);
}
if (srcImage != null) {
hasImage = true;
setText(gameCard);
setImage(srcImage);
}
UI.invokeLater(new Runnable() {
@Override
public void run () {
if(stamp == updateImageStamp) {
hasImage = srcImage != null;
setText(gameCard);
setImage(srcImage);
}
}
});
} catch (Exception e) {
e.printStackTrace();
} catch (Error err) {
@ -1056,7 +1170,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
if (gameCard.hideInfo()) {
return;
}
if (getMousePosition(true) != null) {
if (this.contains(e.getPoint())) {
return;
}
if (tooltipShowing) {

View file

@ -1,15 +1,30 @@
package org.mage.card.arcane;
import com.google.common.base.Function;
import com.google.common.collect.MapMaker;
import javax.swing.*;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import mage.client.util.ImageCaches;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
public class GlowText extends JLabel {
private static final long serialVersionUID = 1827677946939348001L;
@ -19,6 +34,109 @@ public class GlowText extends JLabel {
private Color glowColor;
private boolean wrap;
private int lineCount = 0;
private static Map<Key, BufferedImage> IMAGE_CACHE;
private final static class Key
{
final int width;
final int height;
final String text;
final Map<TextAttribute,?> fontAttributes;
final Color color;
final int glowSize;
final float glowIntensity;
final Color glowColor;
final boolean wrap;
// used to pass the native font to the create function so we don't waste performance recreating it, but without holding onto the native object
final transient WeakReference<Font> originalFont;
Font getFont() {
Font res = this.originalFont.get();
if(res == null)
res = Font.getFont(this.fontAttributes);
return res;
}
public Key(int width, int height, String text, Font font, Color color, int glowSize, float glowIntensity, Color glowColor, boolean wrap) {
this.width = width;
this.height = height;
this.text = text;
this.originalFont = new WeakReference<>(font);
this.fontAttributes = font.getAttributes();
this.color = color;
this.glowSize = glowSize;
this.glowIntensity = glowIntensity;
this.glowColor = glowColor;
this.wrap = wrap;
}
@Override
public int hashCode() {
int hash = 3;
hash = 23 * hash + this.width;
hash = 23 * hash + this.height;
hash = 23 * hash + Objects.hashCode(this.text);
hash = 23 * hash + Objects.hashCode(this.fontAttributes);
hash = 23 * hash + Objects.hashCode(this.color);
hash = 23 * hash + this.glowSize;
hash = 23 * hash + Float.floatToIntBits(this.glowIntensity);
hash = 23 * hash + Objects.hashCode(this.glowColor);
hash = 23 * hash + (this.wrap ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Key other = (Key) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
if (this.glowSize != other.glowSize) {
return false;
}
if (Float.floatToIntBits(this.glowIntensity) != Float.floatToIntBits(other.glowIntensity)) {
return false;
}
if (this.wrap != other.wrap) {
return false;
}
if (!Objects.equals(this.text, other.text)) {
return false;
}
if (!Objects.equals(this.fontAttributes, other.fontAttributes)) {
return false;
}
if (!Objects.equals(this.color, other.color)) {
return false;
}
if (!Objects.equals(this.glowColor, other.glowColor)) {
return false;
}
return true;
}
}
static {
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap(new Function<Key, BufferedImage>() {
@Override
public BufferedImage apply(Key key) {
return createImage(key);
}
}));
}
public void setGlow (Color glowColor, int size, float intensity) {
this.glowColor = glowColor;
@ -38,32 +156,32 @@ public class GlowText extends JLabel {
return size;
}
@Override
public void setText (String text) {
super.setText(text);
}
@Override
public void paint (Graphics g) {
if (getText().length() == 0) {
return;
}
Graphics2D g2d = (Graphics2D)g;
g.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), getText(), getFont(), getForeground(), glowSize, glowIntensity, glowColor, wrap)), 0, 0, null);
}
private static BufferedImage createImage (Key key) {
Dimension size = new Dimension(key.width, key.height);
BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(size.width, size.height);
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Dimension size = getSize();
int textX = 0, textY = 0;
int wrapWidth = Math.max(0, wrap ? size.width - glowSize : Integer.MAX_VALUE);
int wrapWidth = Math.max(0, key.wrap ? size.width - key.glowSize : Integer.MAX_VALUE);
AttributedString attributedString = new AttributedString(getText());
attributedString.addAttribute(TextAttribute.FONT, getFont());
AttributedString attributedString = new AttributedString(key.text);
attributedString.addAttribute(TextAttribute.FONT, key.getFont());
AttributedCharacterIterator charIterator = attributedString.getIterator();
FontRenderContext fontContext = g2d.getFontRenderContext();
LineBreakMeasurer measurer = new LineBreakMeasurer(charIterator, BreakIterator.getWordInstance(Locale.ENGLISH), fontContext);
lineCount = 0;
int lineCount = 0;
while (measurer.getPosition() < charIterator.getEndIndex()) {
//TextLayout textLayout = measurer.nextLayout(wrapWidth);
lineCount++;
@ -83,23 +201,21 @@ public class GlowText extends JLabel {
float ascent = textLayout.getAscent();
textY += ascent; // Move down to baseline.
g2d.setColor(glowColor);
g2d.setColor(key.glowColor);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
int glowSize = key.glowSize;
textLayout.draw(g2d, textX + glowSize / 2 + 1, textY + glowSize / 2 - 1);
textLayout.draw(g2d, textX + glowSize / 2 + 1, textY + glowSize / 2 + 1);
textLayout.draw(g2d, textX + glowSize / 2 - 1, textY + glowSize / 2 - 1);
textLayout.draw(g2d, textX + glowSize / 2 - 1, textY + glowSize / 2 + 1);
g2d.setColor(getForeground());
g2d.setColor(key.color);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
textLayout.draw(g2d, textX + glowSize / 2, textY + glowSize / 2);
textY += textLayout.getDescent() + textLayout.getLeading(); // Move down to top of next line.
}
}
public int getLineCount() {
return this.lineCount;
return image;
}
public void setGlowColor(Color glowColor) {

View file

@ -1,194 +1,42 @@
package org.mage.card.arcane;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import mage.client.util.TransformedImageCache;
public class ScaledImagePanel extends JPanel {
private static final long serialVersionUID = -1523279873208605664L;
private volatile Image srcImage;
private ScalingType scalingType = ScalingType.bilinear;
private boolean scaleLarger;
private MultipassType multiPassType = MultipassType.bilinear;
private volatile BufferedImage srcImage;
public ScaledImagePanel () {
super(false);
setOpaque(false);
}
public void setImage(Image srcImage) {
this.srcImage = srcImage;
}
public void clearImage () {
srcImage = null;
repaint();
}
public void setScalingMultiPassType (MultipassType multiPassType) {
this.multiPassType = multiPassType;
}
public void setScalingType (ScalingType scalingType) {
this.scalingType = scalingType;
}
public void setScaleLarger (boolean scaleLarger) {
this.scaleLarger = scaleLarger;
public void setImage(BufferedImage srcImage) {
this.srcImage = srcImage;
}
public boolean hasImage () {
return srcImage != null;
}
private ScalingInfo getScalingInfo () {
int panelWidth = getWidth();
int panelHeight = getHeight();
int srcWidth = srcImage.getWidth(null);
int srcHeight = srcImage.getHeight(null);
int targetWidth = srcWidth;
int targetHeight = srcHeight;
if (scaleLarger || srcWidth > panelWidth || srcHeight > panelHeight) {
targetWidth = Math.round(panelHeight * (srcWidth / (float)srcHeight));
if (targetWidth > panelWidth) {
targetHeight = Math.round(panelWidth * (srcHeight / (float)srcWidth));
targetWidth = panelWidth;
} else {
targetHeight = panelHeight;
}
}
ScalingInfo info = new ScalingInfo();
info.targetWidth = targetWidth;
info.targetHeight = targetHeight;
info.srcWidth = srcWidth;
info.srcHeight = srcHeight;
info.x = panelWidth / 2 - targetWidth / 2;
info.y = panelHeight / 2 - targetHeight / 2;
return info;
}
@Override
public void paint (Graphics g) {
if (srcImage == null) {
return;
}
Graphics2D g2 = (Graphics2D)g.create();
ScalingInfo info = getScalingInfo();
switch (scalingType) {
case nearestNeighbor:
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
break;
case bilinear:
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
break;
case bicubic:
scaleWithDrawImage(g2, info, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
break;
case areaAveraging:
scaleWithGetScaledInstance(g2, info, Image.SCALE_AREA_AVERAGING);
break;
case replicate:
scaleWithGetScaledInstance(g2, info, Image.SCALE_REPLICATE);
break;
}
g.drawImage(TransformedImageCache.getResizedImage(srcImage, getWidth(), getHeight()), 0, 0, null);
}
private void scaleWithGetScaledInstance (Graphics2D g2, ScalingInfo info, int hints) {
Image scaledImage = srcImage.getScaledInstance(info.targetWidth, info.targetHeight, hints);
g2.drawImage(scaledImage, info.x, info.y, null);
}
private void scaleWithDrawImage (Graphics2D g2, ScalingInfo info, Object hint) {
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
int tempDestWidth = info.srcWidth / 2, tempDestHeight = info.srcHeight / 2;
if (tempDestWidth < info.targetWidth) {
tempDestWidth = info.targetWidth;
}
if (tempDestHeight < info.targetHeight) {
tempDestHeight = info.targetHeight;
}
// If not doing multipass or multipass only needs a single pass, just scale it once directly to the panel surface.
if (multiPassType == MultipassType.none || (tempDestWidth == info.targetWidth && tempDestHeight == info.targetHeight)) {
g2.drawImage(srcImage, info.x, info.y, info.targetWidth, info.targetHeight, null);
return;
}
BufferedImage tempImage = new BufferedImage(tempDestWidth, tempDestHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2temp = tempImage.createGraphics();
switch (multiPassType) {
case nearestNeighbor:
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
break;
case bilinear:
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
break;
case bicubic:
g2temp.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
break;
}
// Render first pass from image to temp.
g2temp.drawImage(srcImage, 0, 0, tempDestWidth, tempDestHeight, null);
// Render passes between the first and last pass.
int tempSrcWidth = tempDestWidth;
int tempSrcHeight = tempDestHeight;
while (true) {
if (tempDestWidth > info.targetWidth) {
tempDestWidth = tempDestWidth / 2;
if (tempDestWidth < info.targetWidth) {
tempDestWidth = info.targetWidth;
}
}
if (tempDestHeight > info.targetHeight) {
tempDestHeight = tempDestHeight / 2;
if (tempDestHeight < info.targetHeight) {
tempDestHeight = info.targetHeight;
}
}
if (tempDestWidth == info.targetWidth && tempDestHeight == info.targetHeight) {
break;
}
g2temp.drawImage(tempImage, 0, 0, tempDestWidth, tempDestHeight, 0, 0, tempSrcWidth, tempSrcHeight, null);
tempSrcWidth = tempDestWidth;
tempSrcHeight = tempDestHeight;
}
g2temp.dispose();
// Render last pass from temp to panel surface.
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(tempImage, info.x, info.y, info.x + info.targetWidth, info.y + info.targetHeight, 0, 0, tempSrcWidth,
tempSrcHeight, null);
}
public Image getSrcImage() {
public BufferedImage getSrcImage() {
return srcImage;
}
private static class ScalingInfo {
public int targetWidth;
public int targetHeight;
public int srcWidth;
public int srcHeight;
public int x;
public int y;
}
public static enum MultipassType {
none, nearestNeighbor, bilinear, bicubic
}
public static enum ScalingType {
nearestNeighbor, replicate, bilinear, bicubic, areaAveraging
}
}

View file

@ -284,6 +284,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
if (card.getCardNumber() > 0 && !card.getSetCode().isEmpty()
&& !ignoreUrls.contains(card.getSetCode())) {
String cardName = card.getName();
boolean isType2 = type2SetsFilter.contains(card.getSetCode());
CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", false, card.isDoubleFaced(), card.isNightCard());
if (url.getUsesVariousArt()) {
url.setDownloadName(createDownloadName(card));
@ -291,10 +292,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
url.setFlipCard(card.isFlipCard());
url.setSplitCard(card.isSplitCard());
if (type2SetsFilter.contains(card.getSetCode())) {
url.setType2(true);
}
url.setType2(isType2);
allCardsUrls.add(url);
if (card.isDoubleFaced()) {
@ -302,6 +300,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
throw new IllegalStateException("Second side card can't have empty name.");
}
url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", false, card.isDoubleFaced(), true);
url.setType2(isType2);
allCardsUrls.add(url);
}
if (card.isFlipCard()) {
@ -311,6 +310,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
url = new CardDownloadData(card.getFlipCardName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", false, card.isDoubleFaced(), card.isNightCard());
url.setFlipCard(true);
url.setFlippedSide(true);
url.setType2(isType2);
allCardsUrls.add(url);
}
} else if (card.getCardNumber() < 1) {

View file

@ -1,5 +1,6 @@
package org.mage.plugins.card.images;
import mage.client.util.TransformedImageCache;
import com.google.common.base.Function;
import com.google.common.collect.ComputationException;
import com.google.common.collect.MapMaker;
@ -274,7 +275,7 @@ public class ImageCache {
}
public static BufferedImage makeThumbnail(BufferedImage original, String path) {
BufferedImage image = getResizedImage(original, Constants.THUMBNAIL_SIZE_FULL);
BufferedImage image = TransformedImageCache.getResizedImage(original, Constants.THUMBNAIL_SIZE_FULL.width, Constants.THUMBNAIL_SIZE_FULL.height);
TFile imageFile = getTFile(path);
if (imageFile == null) {
return null;
@ -312,36 +313,7 @@ public class ImageCache {
return original;
}
ResampleOp resampleOp = new ResampleOp(tgtWidth, tgtHeight);
BufferedImage image = resampleOp.filter(original, null);
return image;
}
/**
* Returns an image scaled to the size appropriate for the card picture
* panel For future use.
*/
private static BufferedImage getFullSizeImage(BufferedImage original, double scale) {
if (scale == 1) {
return original;
}
ResampleOp resampleOp = new ResampleOp((int) (original.getWidth() * scale), (int) (original.getHeight() * scale));
BufferedImage image = resampleOp.filter(original, null);
return image;
}
/**
* Returns an image scaled to the size appropriate for the card picture
* panel
*
* @param original
* @param sizeNeed
* @return
*/
public static BufferedImage getResizedImage(BufferedImage original, Rectangle sizeNeed) {
ResampleOp resampleOp = new ResampleOp(sizeNeed.width, sizeNeed.height);
BufferedImage image = resampleOp.filter(original, null);
return image;
return TransformedImageCache.getResizedImage(original, tgtWidth, tgtHeight);
}
/**
@ -364,11 +336,11 @@ public class ImageCache {
}
double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight());
if (scale > 1) {
scale = 1;
if (scale >= 1) {
return original;
}
return getFullSizeImage(original, scale);
return TransformedImageCache.getResizedImage(original, (int)(original.getWidth() * scale), (int)(original.getHeight() * scale));
}
public static TFile getTFile(String path) {

View file

@ -39,6 +39,8 @@ package mage.cards;
* @author BetaSteward_at_googlemail.com
*/
public class TextPopup extends javax.swing.JPanel {
private String text;
private boolean needsUpdate;
/** Creates new form TextPopup */
public TextPopup() {
@ -46,7 +48,17 @@ public class TextPopup extends javax.swing.JPanel {
}
public void setText(String text) {
popupText.setText(text);
if(!text.equals(this.text)) {
this.text = text;
this.needsUpdate = true;
}
}
public void updateText() {
if(this.needsUpdate) {
popupText.setText(this.text);
this.needsUpdate = false;
}
}
/** This method is called from within the constructor to

View file

@ -65,6 +65,7 @@ public class TableView implements Serializable {
private final String quitRatio;
private final boolean limited;
private final boolean rated;
private final boolean passworded;
public TableView(Table table) {
this.tableId = table.getId();
@ -94,8 +95,7 @@ public class TableView implements Serializable {
if (!table.isTournament()) {
// MATCH
if (table.getState().equals(TableState.WAITING) || table.getState().equals(TableState.READY_TO_START)) {
tableStateText = table.getState().toString() + " (" + table.getMatch().getPlayers().size() + "/"+ table.getSeats().length + ")" +
(table.getMatch().getOptions().getPassword().isEmpty() ? "":" PW");
tableStateText = table.getState().toString() + " (" + table.getMatch().getPlayers().size() + "/"+ table.getSeats().length + ")";
} else {
tableStateText = table.getState().toString();
}
@ -136,6 +136,7 @@ public class TableView implements Serializable {
this.quitRatio = Integer.toString(table.getMatch().getOptions().getQuitRatio());
this.limited = table.getMatch().getOptions().isLimited();
this.rated = table.getMatch().getOptions().isRated();
this.passworded = !table.getMatch().getOptions().getPassword().isEmpty();
} else {
// TOURNAMENT
if (table.getTournament().getOptions().getNumberRounds() > 0) {
@ -155,9 +156,6 @@ public class TableView implements Serializable {
switch (table.getState()) {
case WAITING:
stateText.append(" (").append(table.getTournament().getPlayers().size()).append("/").append(table.getNumberOfSeats()).append(")");
if (!table.getTournament().getOptions().getPassword().isEmpty()) {
stateText.append(" PW");
}
case READY_TO_START:
case STARTING:
infoText.append(" Time: ").append(table.getTournament().getOptions().getMatchOptions().getMatchTimeLimit().toString());
@ -185,6 +183,7 @@ public class TableView implements Serializable {
this.quitRatio = Integer.toString(table.getTournament().getOptions().getQuitRatio());
this.limited = table.getTournament().getOptions().getMatchOptions().isLimited();
this.rated = table.getTournament().getOptions().getMatchOptions().isRated();
this.passworded = !table.getTournament().getOptions().getPassword().isEmpty();
}
}
@ -250,4 +249,8 @@ public class TableView implements Serializable {
public boolean isRated() {
return rated;
}
public boolean isPassworded() {
return passworded;
}
}

View file

@ -577,7 +577,8 @@ public class HumanPlayer extends PlayerImpl {
return false;
}
}
if (passedAllTurns) {
if (passedAllTurns || passedTurnSkipStack) {
if (passWithManaPoolCheck(game)) {
return false;
}
@ -600,7 +601,7 @@ public class HumanPlayer extends PlayerImpl {
if (game.getStack().isEmpty()) {
passedUntilStackResolved = false;
boolean dontCheckPassStep = false;
if (passedTurn) {
if (passedTurn || passedTurnSkipStack) {
if (passWithManaPoolCheck(game)) {
return false;
}
@ -689,7 +690,7 @@ public class HumanPlayer extends PlayerImpl {
result = true;
} else {
Player actingPlayer = null;
if (game.getPriorityPlayerId().equals(playerId)) {
if (playerId.equals(game.getPriorityPlayerId())) {
actingPlayer = this;
} else if (getPlayersUnderYourControl().contains(game.getPriorityPlayerId())) {
actingPlayer = game.getPlayer(game.getPriorityPlayerId());
@ -714,7 +715,7 @@ public class HumanPlayer extends PlayerImpl {
}
private boolean checkPassStep(Game game) {
if (game.getActivePlayerId().equals(playerId)) {
if (playerId.equals(game.getActivePlayerId())) {
return !this.getUserData().getUserSkipPrioritySteps().getYourTurn().isPhaseStepSet(game.getStep().getType());
} else {
return !this.getUserData().getUserSkipPrioritySteps().getOpponentTurn().isPhaseStepSet(game.getStep().getType());
@ -887,7 +888,7 @@ public class HumanPlayer extends PlayerImpl {
filter.add(new ControllerIdPredicate(attackingPlayerId));
while (!abort) {
if (passedAllTurns || passedUntilEndStepBeforeMyTurn
|| (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedUntilEndOfTurn || passedUntilNextMain))) {
|| (!getUserData().getUserSkipPrioritySteps().isStopOnDeclareAttackersDuringSkipAction() && (passedTurn || passedTurnSkipStack || passedUntilEndOfTurn || passedUntilNextMain))) {
return;
}
Map<String, Serializable> options = new HashMap<>();
@ -1241,16 +1242,16 @@ public class HumanPlayer extends PlayerImpl {
return;
}
}
if (userData.isUseFirstManaAbility() && object instanceof Permanent && object.getCardType().contains(CardType.LAND)){
if (userData.isUseFirstManaAbility() && object instanceof Permanent && object.getCardType().contains(CardType.LAND)) {
ActivatedAbility ability = abilities.values().iterator().next();
if (ability instanceof ManaAbility) {
activateAbility(ability, game);
return;
}
}
}
game.fireGetChoiceEvent(playerId, name, object, new ArrayList<>(abilities.values()));
waitForResponse(game);
if (response.getUUID() != null && isInGame()) {
if (abilities.containsKey(response.getUUID())) {

View file

@ -0,0 +1,89 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.tournament;
import mage.constants.TournamentPlayerState;
import mage.game.draft.DraftOptions;
import mage.game.draft.RichManCubeBoosterDraft;
import mage.game.events.TableEvent.EventType;
import mage.game.tournament.TournamentOptions;
import mage.game.tournament.TournamentPlayer;
import mage.game.tournament.TournamentSingleElimination;
/**
*
* @author spjspj
*/
public class RichManCubeDraftEliminationTournament extends TournamentSingleElimination {
protected enum TournamentStep {
START, DRAFT, CONSTRUCT, COMPETE, WINNERS
}
protected TournamentStep currentStep;
public RichManCubeDraftEliminationTournament(TournamentOptions options) {
super(options);
currentStep = TournamentStep.START;
}
protected void draft() {
draft = new RichManCubeBoosterDraft((DraftOptions) options.getLimitedOptions(), getSets());
for (TournamentPlayer player : players.values()) {
draft.addPlayer(player.getPlayer());
player.setState(TournamentPlayerState.DRAFTING);
}
tableEventSource.fireTableEvent(EventType.START_DRAFT, null, draft);
}
@Override
public void nextStep() {
if (isAbort()) {
currentStep = TournamentStep.COMPETE;
}
switch (currentStep) {
case START:
currentStep = TournamentStep.DRAFT;
draft();
break;
case DRAFT:
currentStep = TournamentStep.CONSTRUCT;
construct();
break;
case CONSTRUCT:
currentStep = TournamentStep.COMPETE;
runTournament();
break;
case COMPETE:
currentStep = TournamentStep.WINNERS;
winners();
end();
break;
}
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.tournament;
import mage.game.tournament.TournamentType;
/**
*
* @author spjspj
*/
public class RichManCubeDraftEliminationTournamentType extends TournamentType {
public RichManCubeDraftEliminationTournamentType() {
this.name = "Booster Draft Elimination (Rich Man Cube)";
this.maxPlayers = 16;
this.minPlayers = 2;
this.numBoosters = 1;
this.draft = true;
this.limited = true;
this.cubeBooster = true;
this.elimination = true;
}
}

View file

@ -34,7 +34,7 @@ import mage.game.draft.DraftCube;
* @author fireshoes
*/
public class AdamStyborskisPauperCube extends DraftCube {
public AdamStyborskisPauperCube() {
super("Adam Styborkski's Cube (411 cards)"); // https://docs.google.com/spreadsheets/d/12iQhC4bHqFW7hEWxPBjyC8yBDehFZ0_4DkqzyA8EL3o/edit#gid=0
@ -44,6 +44,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("AEther Adept", ""));
cubeCards.add(new CardIdentity("AEthersnipe", ""));
cubeCards.add(new CardIdentity("Agony Warp", ""));
cubeCards.add(new CardIdentity("Aim High", ""));
cubeCards.add(new CardIdentity("Ambush Viper", ""));
cubeCards.add(new CardIdentity("Apex Hawks", ""));
cubeCards.add(new CardIdentity("Arachnus Web", ""));
@ -67,7 +68,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Beetleback Chief", ""));
cubeCards.add(new CardIdentity("Beetleform Mage", ""));
cubeCards.add(new CardIdentity("Benthic Infiltrator", ""));
cubeCards.add(new CardIdentity("Blade of the Sixth Pride", ""));
cubeCards.add(new CardIdentity("Blastoderm", ""));
cubeCards.add(new CardIdentity("Blazing Torch", ""));
cubeCards.add(new CardIdentity("Blightning", ""));
@ -81,10 +81,9 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Boros Guildgate", ""));
cubeCards.add(new CardIdentity("Branching Bolt", ""));
cubeCards.add(new CardIdentity("Brute Force", ""));
cubeCards.add(new CardIdentity("Brute Strength", ""));
cubeCards.add(new CardIdentity("Burst Lightning", ""));
cubeCards.add(new CardIdentity("Butcher Ghoul", ""));
cubeCards.add(new CardIdentity("Cadaver Imp", ""));
cubeCards.add(new CardIdentity("Byway Courier", ""));
cubeCards.add(new CardIdentity("Cage of Hands", ""));
cubeCards.add(new CardIdentity("Calcite Snapper", ""));
cubeCards.add(new CardIdentity("Capsize", ""));
@ -93,6 +92,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Cavern Harpy", ""));
cubeCards.add(new CardIdentity("Centaur Healer", ""));
cubeCards.add(new CardIdentity("Center Soul", ""));
cubeCards.add(new CardIdentity("Cephalid Sage", ""));
cubeCards.add(new CardIdentity("Chain Lightning", ""));
cubeCards.add(new CardIdentity("Chainer's Edict", ""));
cubeCards.add(new CardIdentity("Citanul Woodreaders", ""));
@ -105,14 +105,13 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Coalition Honor Guard", ""));
cubeCards.add(new CardIdentity("Cogwork Librarian", ""));
cubeCards.add(new CardIdentity("Colossal Might", ""));
cubeCards.add(new CardIdentity("Comparative Analysis", ""));
cubeCards.add(new CardIdentity("Compulsive Research", ""));
cubeCards.add(new CardIdentity("Consume Strength", ""));
cubeCards.add(new CardIdentity("Corpse Churn", ""));
cubeCards.add(new CardIdentity("Corrupted Zendikon", ""));
cubeCards.add(new CardIdentity("Counterspell", ""));
cubeCards.add(new CardIdentity("Crippling Fatigue", ""));
cubeCards.add(new CardIdentity("Crocanura", ""));
cubeCards.add(new CardIdentity("Crow of Dark Tidings", ""));
cubeCards.add(new CardIdentity("Crypt Rats", ""));
cubeCards.add(new CardIdentity("Crystallization", ""));
cubeCards.add(new CardIdentity("Cultivate", ""));
@ -120,8 +119,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Curse of Chains", ""));
cubeCards.add(new CardIdentity("Custodi Squire", ""));
cubeCards.add(new CardIdentity("Daring Skyjek", ""));
cubeCards.add(new CardIdentity("Daru Lancer", ""));
cubeCards.add(new CardIdentity("Dauthi Slayer", ""));
cubeCards.add(new CardIdentity("Dauntless Cathar", ""));
cubeCards.add(new CardIdentity("Dead Reveler", ""));
cubeCards.add(new CardIdentity("Dead Weight", ""));
cubeCards.add(new CardIdentity("Death Denied", ""));
@ -145,18 +143,20 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Eldrazi Skyspawner", ""));
cubeCards.add(new CardIdentity("Elephant Ambush", ""));
cubeCards.add(new CardIdentity("Elephant Guide", ""));
cubeCards.add(new CardIdentity("Elite Vanguard", ""));
cubeCards.add(new CardIdentity("Emperor Crocodile", ""));
cubeCards.add(new CardIdentity("Epic Confrontation", ""));
cubeCards.add(new CardIdentity("Errant Ephemeron", ""));
cubeCards.add(new CardIdentity("Esper Cormorants", ""));
cubeCards.add(new CardIdentity("Essence Scatter", ""));
cubeCards.add(new CardIdentity("Evincar's Justice", ""));
cubeCards.add(new CardIdentity("Evolution Charm", ""));
cubeCards.add(new CardIdentity("Evolving Wilds", ""));
cubeCards.add(new CardIdentity("Faceless Butcher", ""));
cubeCards.add(new CardIdentity("Faith's Fetters", ""));
cubeCards.add(new CardIdentity("Fall of the Hammer", ""));
cubeCards.add(new CardIdentity("Feeling of Dread", ""));
cubeCards.add(new CardIdentity("Fellwar Stone", ""));
cubeCards.add(new CardIdentity("Fertile Thicket", ""));
cubeCards.add(new CardIdentity("Fervent Cathar", ""));
cubeCards.add(new CardIdentity("Firebolt", ""));
cubeCards.add(new CardIdentity("Firefiend Elemental", ""));
@ -165,7 +165,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Flayer Husk", ""));
cubeCards.add(new CardIdentity("Flurry of Horns", ""));
cubeCards.add(new CardIdentity("Fortify", ""));
cubeCards.add(new CardIdentity("Foul Spirit", ""));
cubeCards.add(new CardIdentity("Frilled Oculus", ""));
cubeCards.add(new CardIdentity("Frostburn Weird", ""));
cubeCards.add(new CardIdentity("Fyndhorn Elves", ""));
@ -175,9 +174,9 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Ghastly Demise", ""));
cubeCards.add(new CardIdentity("Ghirapur Gearcrafter", ""));
cubeCards.add(new CardIdentity("Ghitu Slinger", ""));
cubeCards.add(new CardIdentity("Ghoulcaller's Accomplice", ""));
cubeCards.add(new CardIdentity("Giant Growth", ""));
cubeCards.add(new CardIdentity("Gideon's Lawkeeper", ""));
cubeCards.add(new CardIdentity("Gideon's Reproach", ""));
cubeCards.add(new CardIdentity("Goblin Freerunner", ""));
cubeCards.add(new CardIdentity("Goblin Heelcutter", ""));
cubeCards.add(new CardIdentity("Gods Willing", ""));
@ -195,15 +194,16 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Gurmag Angler", ""));
cubeCards.add(new CardIdentity("Halimar Depths", ""));
cubeCards.add(new CardIdentity("Halimar Wavewatch", ""));
cubeCards.add(new CardIdentity("Hand of Silumgar", ""));
cubeCards.add(new CardIdentity("Harrow", ""));
cubeCards.add(new CardIdentity("Harsh Sustenance", ""));
cubeCards.add(new CardIdentity("Hissing Iguanar", ""));
cubeCards.add(new CardIdentity("Hooting Mandrills", ""));
cubeCards.add(new CardIdentity("Humble", ""));
cubeCards.add(new CardIdentity("Hymn to Tourach", ""));
cubeCards.add(new CardIdentity("Imperiosaur", ""));
cubeCards.add(new CardIdentity("Incinerate", ""));
cubeCards.add(new CardIdentity("Inner-Flame Acolyte", ""));
cubeCards.add(new CardIdentity("Insolent Neonate", ""));
cubeCards.add(new CardIdentity("Into the Roil", ""));
cubeCards.add(new CardIdentity("Isolation Zone", ""));
cubeCards.add(new CardIdentity("Izzet Chronarch", ""));
@ -211,7 +211,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Jilt", ""));
cubeCards.add(new CardIdentity("Journey to Nowhere", ""));
cubeCards.add(new CardIdentity("Jungle Hollow", ""));
cubeCards.add(new CardIdentity("Jwar Isle Avenger", ""));
cubeCards.add(new CardIdentity("Kabuto Moth", ""));
cubeCards.add(new CardIdentity("Keldon Marauders", ""));
cubeCards.add(new CardIdentity("Khalni Garden", ""));
@ -231,6 +230,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Liliana's Specter", ""));
cubeCards.add(new CardIdentity("Llanowar Elves", ""));
cubeCards.add(new CardIdentity("Lone Missionary", ""));
cubeCards.add(new CardIdentity("Looming Spires", ""));
cubeCards.add(new CardIdentity("Lotus Path Djinn", ""));
cubeCards.add(new CardIdentity("Loyal Cathar", ""));
cubeCards.add(new CardIdentity("Loyal Pegasus", ""));
@ -239,9 +239,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Mana Leak", ""));
cubeCards.add(new CardIdentity("Man-o'-War", ""));
cubeCards.add(new CardIdentity("Mardu Hordechief", ""));
cubeCards.add(new CardIdentity("Mardu Scout", ""));
cubeCards.add(new CardIdentity("Mardu Skullhunter", ""));
cubeCards.add(new CardIdentity("Martial Glory", ""));
cubeCards.add(new CardIdentity("Maul Splicer", ""));
cubeCards.add(new CardIdentity("Maze of Ith", ""));
cubeCards.add(new CardIdentity("Mind Stone", ""));
@ -250,30 +248,34 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Miscalculation", ""));
cubeCards.add(new CardIdentity("Mishra's Factory", ""));
cubeCards.add(new CardIdentity("Mist Raven", ""));
cubeCards.add(new CardIdentity("Misthoof Kirin", ""));
cubeCards.add(new CardIdentity("Mistral Charger", ""));
cubeCards.add(new CardIdentity("Mogg Fanatic", ""));
cubeCards.add(new CardIdentity("Mogg Flunkies", ""));
cubeCards.add(new CardIdentity("Mogg War Marshal", ""));
cubeCards.add(new CardIdentity("Moldervine Cloak", ""));
cubeCards.add(new CardIdentity("Momentary Blink", ""));
cubeCards.add(new CardIdentity("Morgue Theft", ""));
cubeCards.add(new CardIdentity("Mortuary Mire", ""));
cubeCards.add(new CardIdentity("Mulldrifter", ""));
cubeCards.add(new CardIdentity("Nameless Inversion", ""));
cubeCards.add(new CardIdentity("Narcolepsy", ""));
cubeCards.add(new CardIdentity("Natural Connection", ""));
cubeCards.add(new CardIdentity("Necromancer's Assistant", ""));
cubeCards.add(new CardIdentity("Nessian Asp", ""));
cubeCards.add(new CardIdentity("Nest Invader", ""));
cubeCards.add(new CardIdentity("Nezumi Cutthroat", ""));
cubeCards.add(new CardIdentity("Night's Whisper", ""));
cubeCards.add(new CardIdentity("Nightscape Familiar", ""));
cubeCards.add(new CardIdentity("Ninja of the Deep Hours", ""));
cubeCards.add(new CardIdentity("Oblivion Ring", ""));
cubeCards.add(new CardIdentity("Okiba-Gang Shinobi", ""));
cubeCards.add(new CardIdentity("Oona's Grace", ""));
cubeCards.add(new CardIdentity("Orcish Oriflamme", ""));
cubeCards.add(new CardIdentity("Orzhov Guildgate", ""));
cubeCards.add(new CardIdentity("Otherworldly Journey", ""));
cubeCards.add(new CardIdentity("Pacifism", ""));
cubeCards.add(new CardIdentity("Path of Anger's Flame", ""));
cubeCards.add(new CardIdentity("Penumbra Spider", ""));
cubeCards.add(new CardIdentity("Peregrine Drake", ""));
cubeCards.add(new CardIdentity("Perilous Myr", ""));
cubeCards.add(new CardIdentity("Pestermite", ""));
cubeCards.add(new CardIdentity("Pestilence", ""));
@ -303,7 +305,9 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Raise the Alarm", ""));
cubeCards.add(new CardIdentity("Rakdos Guildgate", ""));
cubeCards.add(new CardIdentity("Rakdos Shred-Freak", ""));
cubeCards.add(new CardIdentity("Rally the Peasants", ""));
cubeCards.add(new CardIdentity("Rampant Growth", ""));
cubeCards.add(new CardIdentity("Rancid Rats", ""));
cubeCards.add(new CardIdentity("Rancor", ""));
cubeCards.add(new CardIdentity("Ranger's Guile", ""));
cubeCards.add(new CardIdentity("Ray of Command", ""));
@ -318,11 +322,12 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Ronin Houndmaster", ""));
cubeCards.add(new CardIdentity("Rugged Highlands", ""));
cubeCards.add(new CardIdentity("Runed Servitor", ""));
cubeCards.add(new CardIdentity("Rush of Adrenaline", ""));
cubeCards.add(new CardIdentity("Rushing River", ""));
cubeCards.add(new CardIdentity("Saddleback Lagac", ""));
cubeCards.add(new CardIdentity("Safehold Elite", ""));
cubeCards.add(new CardIdentity("Sakura-Tribe Elder", ""));
cubeCards.add(new CardIdentity("Sandsteppe Outcast", ""));
cubeCards.add(new CardIdentity("Sandstone Bridge", ""));
cubeCards.add(new CardIdentity("Sangrite Backlash", ""));
cubeCards.add(new CardIdentity("Sarkhan's Rage", ""));
cubeCards.add(new CardIdentity("Savage Punch", ""));
@ -340,7 +345,6 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Separatist Voidmage", ""));
cubeCards.add(new CardIdentity("Seraph of Dawn", ""));
cubeCards.add(new CardIdentity("Serrated Arrows", ""));
cubeCards.add(new CardIdentity("Shadow Glider", ""));
cubeCards.add(new CardIdentity("Shaper Parasite", ""));
cubeCards.add(new CardIdentity("Sheer Drop", ""));
cubeCards.add(new CardIdentity("Shelter", ""));
@ -351,6 +355,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Skinthinner", ""));
cubeCards.add(new CardIdentity("Skirk Marauder", ""));
cubeCards.add(new CardIdentity("Skyknight Legionnaire", ""));
cubeCards.add(new CardIdentity("Skyline Cascade", ""));
cubeCards.add(new CardIdentity("Slash Panther", ""));
cubeCards.add(new CardIdentity("Slippery Bogle", ""));
cubeCards.add(new CardIdentity("Snakeform", ""));
@ -367,14 +372,13 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Stormscape Apprentice", ""));
cubeCards.add(new CardIdentity("Strider Harness", ""));
cubeCards.add(new CardIdentity("Strip Mine", ""));
cubeCards.add(new CardIdentity("Sultai Emissary", ""));
cubeCards.add(new CardIdentity("Sultai Scavenger", ""));
cubeCards.add(new CardIdentity("Suppression Bonds", ""));
cubeCards.add(new CardIdentity("Suq'Ata Lancer", ""));
cubeCards.add(new CardIdentity("Sweep Away", ""));
cubeCards.add(new CardIdentity("Swiftwater Cliffs", ""));
cubeCards.add(new CardIdentity("Sylvan Might", ""));
cubeCards.add(new CardIdentity("Sylvok Lifestaff", ""));
cubeCards.add(new CardIdentity("Tail Slash", ""));
cubeCards.add(new CardIdentity("Tajuru Pathwarden", ""));
cubeCards.add(new CardIdentity("Teetering Peaks", ""));
cubeCards.add(new CardIdentity("Temporal Isolation", ""));
@ -384,6 +388,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Test of Faith", ""));
cubeCards.add(new CardIdentity("Thornweald Archer", ""));
cubeCards.add(new CardIdentity("Thornwood Falls", ""));
cubeCards.add(new CardIdentity("Thraben Inspector", ""));
cubeCards.add(new CardIdentity("Thundering Giant", ""));
cubeCards.add(new CardIdentity("Thundering Tanadon", ""));
cubeCards.add(new CardIdentity("Time to Feed", ""));
@ -394,13 +399,11 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Travel Preparations", ""));
cubeCards.add(new CardIdentity("Treasure Cruise", ""));
cubeCards.add(new CardIdentity("Triplicate Spirits", ""));
cubeCards.add(new CardIdentity("Trumpet Blast", ""));
cubeCards.add(new CardIdentity("Tumble Magnet", ""));
cubeCards.add(new CardIdentity("Twin Bolt", ""));
cubeCards.add(new CardIdentity("Typhoid Rats", ""));
cubeCards.add(new CardIdentity("Ulamog's Crusher", ""));
cubeCards.add(new CardIdentity("Umara Entangler", ""));
cubeCards.add(new CardIdentity("Undying Evil", ""));
cubeCards.add(new CardIdentity("Undying Rage", ""));
cubeCards.add(new CardIdentity("Unearth", ""));
cubeCards.add(new CardIdentity("Unmake", ""));
cubeCards.add(new CardIdentity("Unnatural Aggression", ""));
@ -410,6 +413,7 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Viashino Firstblade", ""));
cubeCards.add(new CardIdentity("Vines of Vastwood", ""));
cubeCards.add(new CardIdentity("Voidwielder", ""));
cubeCards.add(new CardIdentity("Voldaren Duelist", ""));
cubeCards.add(new CardIdentity("Vulshok Morningstar", ""));
cubeCards.add(new CardIdentity("Vulshok Sorcerer", ""));
cubeCards.add(new CardIdentity("Vulturous Aven", ""));
@ -417,8 +421,9 @@ public AdamStyborskisPauperCube() {
cubeCards.add(new CardIdentity("Walker of the Grove", ""));
cubeCards.add(new CardIdentity("Wall of Roots", ""));
cubeCards.add(new CardIdentity("War Flare", ""));
cubeCards.add(new CardIdentity("Warden of Evos Isle", ""));
cubeCards.add(new CardIdentity("Warped Landscape", ""));
cubeCards.add(new CardIdentity("Warren Pilferers", ""));
cubeCards.add(new CardIdentity("Waterfront Bouncer", ""));
cubeCards.add(new CardIdentity("Wayfarer's Bauble", ""));
cubeCards.add(new CardIdentity("Whirlpool Whelm", ""));
cubeCards.add(new CardIdentity("Whispers of the Muse", ""));

View file

@ -49,7 +49,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Ajani Vengeant", ""));
cubeCards.add(new CardIdentity("Ancient Den", ""));
cubeCards.add(new CardIdentity("Ancient Tomb", ""));
cubeCards.add(new CardIdentity("Angel of Serenity", ""));
cubeCards.add(new CardIdentity("Animate Dead", ""));
cubeCards.add(new CardIdentity("Ankh of Mishra", ""));
cubeCards.add(new CardIdentity("Arcbound Ravager", ""));
@ -85,6 +84,7 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Bonesplitter", ""));
cubeCards.add(new CardIdentity("Boros Charm", ""));
cubeCards.add(new CardIdentity("Boros Reckoner", ""));
cubeCards.add(new CardIdentity("Bounding Krasis", ""));
cubeCards.add(new CardIdentity("Braids, Cabal Minion", ""));
cubeCards.add(new CardIdentity("Brain Freeze", ""));
cubeCards.add(new CardIdentity("Brainstorm", ""));
@ -100,6 +100,7 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Chained to the Rocks", ""));
cubeCards.add(new CardIdentity("Chain Lightning", ""));
cubeCards.add(new CardIdentity("Champion of the Parish", ""));
cubeCards.add(new CardIdentity("Chandra, Flamecaller", ""));
cubeCards.add(new CardIdentity("Chandra's Phoenix", ""));
cubeCards.add(new CardIdentity("Chromatic Sphere", ""));
cubeCards.add(new CardIdentity("Chromatic Star", ""));
@ -115,7 +116,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Copperline Gorge", ""));
cubeCards.add(new CardIdentity("Council's Judgment", ""));
cubeCards.add(new CardIdentity("Counterspell", ""));
cubeCards.add(new CardIdentity("Court Hussar", ""));
cubeCards.add(new CardIdentity("Cranial Plating", ""));
cubeCards.add(new CardIdentity("Creeping Tar Pit", ""));
cubeCards.add(new CardIdentity("Crop Rotation", ""));
@ -132,9 +132,9 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Daze", ""));
cubeCards.add(new CardIdentity("Deal Broker", ""));
cubeCards.add(new CardIdentity("Deathrite Shaman", ""));
cubeCards.add(new CardIdentity("Declaration in Stone", ""));
cubeCards.add(new CardIdentity("Delver of Secrets", ""));
cubeCards.add(new CardIdentity("Demonic Tutor", ""));
cubeCards.add(new CardIdentity("Deranged Hermit", ""));
cubeCards.add(new CardIdentity("Detention Sphere", ""));
cubeCards.add(new CardIdentity("Dig Through Time", ""));
cubeCards.add(new CardIdentity("Dimir Signet", ""));
@ -166,6 +166,7 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Fact or Fiction", ""));
cubeCards.add(new CardIdentity("Faithless Looting", ""));
cubeCards.add(new CardIdentity("Falkenrath Aristocrat", ""));
cubeCards.add(new CardIdentity("Falkenrath Gorger", ""));
cubeCards.add(new CardIdentity("Far // Away", ""));
cubeCards.add(new CardIdentity("Fastbond", ""));
cubeCards.add(new CardIdentity("Fauna Shaman", ""));
@ -173,7 +174,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Fire // Ice", ""));
cubeCards.add(new CardIdentity("Fireblast", ""));
cubeCards.add(new CardIdentity("Firebolt", ""));
cubeCards.add(new CardIdentity("Firedrinker Satyr", ""));
cubeCards.add(new CardIdentity("Firestorm", ""));
cubeCards.add(new CardIdentity("Flagstones of Trokair", ""));
cubeCards.add(new CardIdentity("Flametongue Kavu", ""));
@ -192,17 +192,15 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Garruk Wildspeaker", ""));
cubeCards.add(new CardIdentity("Geist of Saint Traft", ""));
cubeCards.add(new CardIdentity("Gemstone Mine", ""));
cubeCards.add(new CardIdentity("Genesis Hydra", ""));
cubeCards.add(new CardIdentity("Ghitu Encampment", ""));
cubeCards.add(new CardIdentity("Ghor-Clan Rampager", ""));
cubeCards.add(new CardIdentity("Gideon, Ally of Zendikar", ""));
cubeCards.add(new CardIdentity("Gifts Ungiven", ""));
cubeCards.add(new CardIdentity("Gilded Lotus", ""));
cubeCards.add(new CardIdentity("Gitaxian Probe", ""));
cubeCards.add(new CardIdentity("Glint Hawk Idol", ""));
cubeCards.add(new CardIdentity("Gnarled Scarhide", ""));
cubeCards.add(new CardIdentity("Go for the Throat", ""));
cubeCards.add(new CardIdentity("Goblin Electromancer", ""));
cubeCards.add(new CardIdentity("Goblin Dark-Dwellers", ""));
cubeCards.add(new CardIdentity("Goblin Guide", ""));
cubeCards.add(new CardIdentity("Goblin Rabblemaster", ""));
cubeCards.add(new CardIdentity("Goblin Welder", ""));
@ -244,7 +242,7 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Jace, Vryn's Prodigy", ""));
cubeCards.add(new CardIdentity("Jeskai Ascendancy", ""));
cubeCards.add(new CardIdentity("Joraga Treespeaker", ""));
cubeCards.add(new CardIdentity("Kami of Ancient Law", ""));
cubeCards.add(new CardIdentity("Jori En, Ruin Diver", ""));
cubeCards.add(new CardIdentity("Karakas", ""));
cubeCards.add(new CardIdentity("Karn Liberated", ""));
cubeCards.add(new CardIdentity("Keranos, God of Storms", ""));
@ -339,7 +337,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Preordain", ""));
cubeCards.add(new CardIdentity("Primeval Titan", ""));
cubeCards.add(new CardIdentity("Prismatic Lens", ""));
cubeCards.add(new CardIdentity("Prophetic Bolt", ""));
cubeCards.add(new CardIdentity("Putrid Imp", ""));
cubeCards.add(new CardIdentity("Qasali Pridemage", ""));
cubeCards.add(new CardIdentity("Rakdos Cackler", ""));
@ -350,9 +347,9 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Razorverge Thicket", ""));
cubeCards.add(new CardIdentity("Reanimate", ""));
cubeCards.add(new CardIdentity("Reckless Charge", ""));
cubeCards.add(new CardIdentity("Reckless Waif", ""));
cubeCards.add(new CardIdentity("Reclamation Sage", ""));
cubeCards.add(new CardIdentity("Recurring Nightmare", ""));
cubeCards.add(new CardIdentity("Reflector Mage", ""));
cubeCards.add(new CardIdentity("Regrowth", ""));
cubeCards.add(new CardIdentity("Relic Seeker", ""));
cubeCards.add(new CardIdentity("Remand", ""));
@ -363,7 +360,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Rude Awakening", ""));
cubeCards.add(new CardIdentity("Sacred Foundry", ""));
cubeCards.add(new CardIdentity("Sakura-Tribe Elder", ""));
cubeCards.add(new CardIdentity("Sarkhan, the Dragonspeaker", ""));
cubeCards.add(new CardIdentity("Savannah", ""));
cubeCards.add(new CardIdentity("Scalding Tarn", ""));
cubeCards.add(new CardIdentity("Scavenging Ooze", ""));
@ -374,7 +370,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Searing Blaze", ""));
cubeCards.add(new CardIdentity("Seat of the Synod", ""));
cubeCards.add(new CardIdentity("Seeker of the Way", ""));
cubeCards.add(new CardIdentity("Seething Song", ""));
cubeCards.add(new CardIdentity("Sensei's Divining Top", ""));
cubeCards.add(new CardIdentity("Shadowmage Infiltrator", ""));
cubeCards.add(new CardIdentity("Shambling Vent", ""));
@ -386,7 +381,6 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Signal Pest", ""));
cubeCards.add(new CardIdentity("Simic Growth Chamber", ""));
cubeCards.add(new CardIdentity("Simic Signet", ""));
cubeCards.add(new CardIdentity("Simic Sky Swallower", ""));
cubeCards.add(new CardIdentity("Sinkhole", ""));
cubeCards.add(new CardIdentity("Skullclamp", ""));
cubeCards.add(new CardIdentity("Skyshroud Elite", ""));
@ -410,11 +404,10 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Stoke the Flames", ""));
cubeCards.add(new CardIdentity("Stomping Ground", ""));
cubeCards.add(new CardIdentity("Stoneforge Mystic", ""));
cubeCards.add(new CardIdentity("Stormchaser Mage", ""));
cubeCards.add(new CardIdentity("Strangleroot Geist", ""));
cubeCards.add(new CardIdentity("Stratus Dancer", ""));
cubeCards.add(new CardIdentity("Strip Mine", ""));
cubeCards.add(new CardIdentity("Stromkirk Noble", ""));
cubeCards.add(new CardIdentity("Student of Warfare", ""));
cubeCards.add(new CardIdentity("Sudden Demise", ""));
cubeCards.add(new CardIdentity("Sudden Shock", ""));
cubeCards.add(new CardIdentity("Sulfur Falls", ""));
@ -439,12 +432,15 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Terminate", ""));
cubeCards.add(new CardIdentity("Tezzeret, Agent of Bolas", ""));
cubeCards.add(new CardIdentity("Thalia, Guardian of Thraben", ""));
cubeCards.add(new CardIdentity("Thalia's Lieutenant", ""));
cubeCards.add(new CardIdentity("The Abyss", ""));
cubeCards.add(new CardIdentity("The Tabernacle at Pendrell Vale", ""));
cubeCards.add(new CardIdentity("Thing in the Ice", ""));
cubeCards.add(new CardIdentity("Thirst for Knowledge", ""));
cubeCards.add(new CardIdentity("Thopter Engineer", ""));
cubeCards.add(new CardIdentity("Thopter Spy Network", ""));
cubeCards.add(new CardIdentity("Thoughtseize", ""));
cubeCards.add(new CardIdentity("Thraben Inspector", ""));
cubeCards.add(new CardIdentity("Thragtusk", ""));
cubeCards.add(new CardIdentity("Thran Dynamo", ""));
cubeCards.add(new CardIdentity("Tidehollow Sculler", ""));
@ -452,10 +448,13 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Timetwister", ""));
cubeCards.add(new CardIdentity("Tin Street Hooligan", ""));
cubeCards.add(new CardIdentity("Tinker", ""));
cubeCards.add(new CardIdentity("Tireless Tracker", ""));
cubeCards.add(new CardIdentity("Tolarian Academy", ""));
cubeCards.add(new CardIdentity("Tooth and Nail", ""));
cubeCards.add(new CardIdentity("Topplegeist", ""));
cubeCards.add(new CardIdentity("Tormented Hero", ""));
cubeCards.add(new CardIdentity("Tranquil Thicket", ""));
cubeCards.add(new CardIdentity("Traverse the Ulvenwald", ""));
cubeCards.add(new CardIdentity("Treachery", ""));
cubeCards.add(new CardIdentity("Treasure Cruise", ""));
cubeCards.add(new CardIdentity("Tree of Tales", ""));
@ -480,6 +479,7 @@ public class JimDavisCube extends DraftCube {
cubeCards.add(new CardIdentity("Vengevine", ""));
cubeCards.add(new CardIdentity("Venser, Shaper Savant", ""));
cubeCards.add(new CardIdentity("Verdant Catacombs", ""));
cubeCards.add(new CardIdentity("Village Messenger", ""));
cubeCards.add(new CardIdentity("Vindicate", ""));
cubeCards.add(new CardIdentity("Volcanic Island", ""));
cubeCards.add(new CardIdentity("Volrath's Stronghold", ""));

View file

@ -0,0 +1,583 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.tournament.cubes;
import mage.game.draft.DraftCube;
/**
*
* @author fireshoes
*/
public class VintageCubeJune2016 extends DraftCube {
public VintageCubeJune2016() {
super("MTGO Vintage Cube June 2016");
cubeCards.add(new DraftCube.CardIdentity("Abbot of Keral Keep", ""));
cubeCards.add(new DraftCube.CardIdentity("Abrupt Decay", ""));
cubeCards.add(new DraftCube.CardIdentity("Academy Rector", ""));
cubeCards.add(new DraftCube.CardIdentity("Academy Ruins", ""));
cubeCards.add(new DraftCube.CardIdentity("Acidic Slime", ""));
cubeCards.add(new DraftCube.CardIdentity("Ajani Vengeant", ""));
cubeCards.add(new DraftCube.CardIdentity("Ancestral Recall", ""));
cubeCards.add(new DraftCube.CardIdentity("Ancestral Vision", ""));
cubeCards.add(new DraftCube.CardIdentity("Ancient Grudge", ""));
cubeCards.add(new DraftCube.CardIdentity("Ancient Tomb", ""));
cubeCards.add(new DraftCube.CardIdentity("Angel of Serenity", ""));
cubeCards.add(new DraftCube.CardIdentity("Anguished Unmaking", ""));
cubeCards.add(new DraftCube.CardIdentity("Animate Dead", ""));
cubeCards.add(new DraftCube.CardIdentity("Anticipate", ""));
cubeCards.add(new DraftCube.CardIdentity("Arbor Elf", ""));
cubeCards.add(new DraftCube.CardIdentity("Archangel of Thune", ""));
cubeCards.add(new DraftCube.CardIdentity("Arid Mesa", ""));
cubeCards.add(new DraftCube.CardIdentity("Armageddon", ""));
cubeCards.add(new DraftCube.CardIdentity("Ashiok, Nightmare Weaver", ""));
cubeCards.add(new DraftCube.CardIdentity("Avacyn's Pilgrim", ""));
cubeCards.add(new DraftCube.CardIdentity("Avalanche Riders", ""));
cubeCards.add(new DraftCube.CardIdentity("Avenger of Zendikar", ""));
cubeCards.add(new DraftCube.CardIdentity("Awakening Zone", ""));
cubeCards.add(new DraftCube.CardIdentity("Azorius Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Badlands", ""));
cubeCards.add(new DraftCube.CardIdentity("Balance", ""));
cubeCards.add(new DraftCube.CardIdentity("Baleful Strix", ""));
cubeCards.add(new DraftCube.CardIdentity("Baneslayer Angel", ""));
cubeCards.add(new DraftCube.CardIdentity("Banisher Priest", ""));
cubeCards.add(new DraftCube.CardIdentity("Banishing Light", ""));
cubeCards.add(new DraftCube.CardIdentity("Basalt Monolith", ""));
cubeCards.add(new DraftCube.CardIdentity("Batterskull", ""));
cubeCards.add(new DraftCube.CardIdentity("Bayou", ""));
cubeCards.add(new DraftCube.CardIdentity("Bazaar of Baghdad", ""));
cubeCards.add(new DraftCube.CardIdentity("Beast Within", ""));
cubeCards.add(new DraftCube.CardIdentity("Birds of Paradise", ""));
cubeCards.add(new DraftCube.CardIdentity("Birthing Pod", ""));
cubeCards.add(new DraftCube.CardIdentity("Bitterblossom", ""));
cubeCards.add(new DraftCube.CardIdentity("Black Lotus", ""));
cubeCards.add(new DraftCube.CardIdentity("Blade Splicer", ""));
cubeCards.add(new DraftCube.CardIdentity("Blightsteel Colossus", ""));
cubeCards.add(new DraftCube.CardIdentity("Blood Crypt", ""));
cubeCards.add(new DraftCube.CardIdentity("Bloodbraid Elf", ""));
cubeCards.add(new DraftCube.CardIdentity("Bloodstained Mire", ""));
cubeCards.add(new DraftCube.CardIdentity("Bone Shredder", ""));
cubeCards.add(new DraftCube.CardIdentity("Bonfire of the Damned", ""));
cubeCards.add(new DraftCube.CardIdentity("Boros Charm", ""));
cubeCards.add(new DraftCube.CardIdentity("Boros Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Braids, Cabal Minion", ""));
cubeCards.add(new DraftCube.CardIdentity("Brain Freeze", ""));
cubeCards.add(new DraftCube.CardIdentity("Brain Maggot", ""));
cubeCards.add(new DraftCube.CardIdentity("Brainstorm", ""));
cubeCards.add(new DraftCube.CardIdentity("Breeding Pool", ""));
cubeCards.add(new DraftCube.CardIdentity("Bribery", ""));
cubeCards.add(new DraftCube.CardIdentity("Brimaz, King of Oreskos", ""));
cubeCards.add(new DraftCube.CardIdentity("Brimstone Volley", ""));
cubeCards.add(new DraftCube.CardIdentity("Bring to Light", ""));
cubeCards.add(new DraftCube.CardIdentity("Buried Alive", ""));
cubeCards.add(new DraftCube.CardIdentity("Burning of Xinye", ""));
cubeCards.add(new DraftCube.CardIdentity("Burst Lightning", ""));
cubeCards.add(new DraftCube.CardIdentity("Cabal Ritual", ""));
cubeCards.add(new DraftCube.CardIdentity("Careful Study", ""));
cubeCards.add(new DraftCube.CardIdentity("Celestial Colonnade", ""));
cubeCards.add(new DraftCube.CardIdentity("Chain Lightning", ""));
cubeCards.add(new DraftCube.CardIdentity("Chandra, Flamecaller", ""));
cubeCards.add(new DraftCube.CardIdentity("Chandra, Pyromaster", ""));
cubeCards.add(new DraftCube.CardIdentity("Char", ""));
cubeCards.add(new DraftCube.CardIdentity("Channel", ""));
cubeCards.add(new DraftCube.CardIdentity("Chrome Mox", ""));
cubeCards.add(new DraftCube.CardIdentity("Coalition Relic", ""));
cubeCards.add(new DraftCube.CardIdentity("Coercive Portal", ""));
cubeCards.add(new DraftCube.CardIdentity("Compulsive Research", ""));
cubeCards.add(new DraftCube.CardIdentity("Conclave Naturalists", ""));
cubeCards.add(new DraftCube.CardIdentity("Consecrated Sphinx", ""));
cubeCards.add(new DraftCube.CardIdentity("Control Magic", ""));
cubeCards.add(new DraftCube.CardIdentity("Corpse Dance", ""));
cubeCards.add(new DraftCube.CardIdentity("Council's Judgment", ""));
cubeCards.add(new DraftCube.CardIdentity("Counterspell", ""));
cubeCards.add(new DraftCube.CardIdentity("Courser of Kruphix", ""));
cubeCards.add(new DraftCube.CardIdentity("Crater's Claws", ""));
cubeCards.add(new DraftCube.CardIdentity("Craterhoof Behemoth", ""));
cubeCards.add(new DraftCube.CardIdentity("Creeping Tar Pit", ""));
cubeCards.add(new DraftCube.CardIdentity("Crucible of Worlds", ""));
cubeCards.add(new DraftCube.CardIdentity("Cryptic Command", ""));
cubeCards.add(new DraftCube.CardIdentity("Dack Fayden", ""));
cubeCards.add(new DraftCube.CardIdentity("Damnation", ""));
cubeCards.add(new DraftCube.CardIdentity("Daretti, Scrap Savant", ""));
cubeCards.add(new DraftCube.CardIdentity("Dark Confidant", ""));
cubeCards.add(new DraftCube.CardIdentity("Dark Petition", ""));
cubeCards.add(new DraftCube.CardIdentity("Dark Ritual", ""));
cubeCards.add(new DraftCube.CardIdentity("Day of Judgment", ""));
cubeCards.add(new DraftCube.CardIdentity("Daze", ""));
cubeCards.add(new DraftCube.CardIdentity("Deathrite Shaman", ""));
cubeCards.add(new DraftCube.CardIdentity("Deceiver Exarch", ""));
cubeCards.add(new DraftCube.CardIdentity("Declaration in Stone", ""));
cubeCards.add(new DraftCube.CardIdentity("Delver of Secrets", ""));
cubeCards.add(new DraftCube.CardIdentity("Demonic Tutor", ""));
cubeCards.add(new DraftCube.CardIdentity("Den Protector", ""));
cubeCards.add(new DraftCube.CardIdentity("Deranged Hermit", ""));
cubeCards.add(new DraftCube.CardIdentity("Desecration Demon", ""));
cubeCards.add(new DraftCube.CardIdentity("Diabolic Edict", ""));
cubeCards.add(new DraftCube.CardIdentity("Dig Through Time", ""));
cubeCards.add(new DraftCube.CardIdentity("Dimir Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Disenchant", ""));
cubeCards.add(new DraftCube.CardIdentity("Disfigure", ""));
cubeCards.add(new DraftCube.CardIdentity("Dismember", ""));
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Atarka", ""));
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Dromoka", ""));
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Ojutai", ""));
cubeCards.add(new DraftCube.CardIdentity("Dragonlord Silumgar", ""));
cubeCards.add(new DraftCube.CardIdentity("Dreadbore", ""));
cubeCards.add(new DraftCube.CardIdentity("Dromoka's Command", ""));
cubeCards.add(new DraftCube.CardIdentity("Dualcaster Mage", ""));
cubeCards.add(new DraftCube.CardIdentity("Duplicant", ""));
cubeCards.add(new DraftCube.CardIdentity("Duress", ""));
cubeCards.add(new DraftCube.CardIdentity("Edric, Spymaster of Trest", ""));
cubeCards.add(new DraftCube.CardIdentity("Eidolon of the Great Revel", ""));
cubeCards.add(new DraftCube.CardIdentity("Electrolyze", ""));
cubeCards.add(new DraftCube.CardIdentity("Elesh Norn, Grand Cenobite", ""));
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Knight-Errant", ""));
cubeCards.add(new DraftCube.CardIdentity("Elspeth, Sun's Champion", ""));
cubeCards.add(new DraftCube.CardIdentity("Elves of Deep Shadow", ""));
cubeCards.add(new DraftCube.CardIdentity("Elvish Mystic", ""));
cubeCards.add(new DraftCube.CardIdentity("Emeria Angel", ""));
cubeCards.add(new DraftCube.CardIdentity("Empty the Warrens", ""));
cubeCards.add(new DraftCube.CardIdentity("Emrakul, the Aeons Torn", ""));
cubeCards.add(new DraftCube.CardIdentity("Enlightened Tutor", ""));
cubeCards.add(new DraftCube.CardIdentity("Entomb", ""));
cubeCards.add(new DraftCube.CardIdentity("Eternal Witness", ""));
cubeCards.add(new DraftCube.CardIdentity("Eureka", ""));
cubeCards.add(new DraftCube.CardIdentity("Everflowing Chalice", ""));
cubeCards.add(new DraftCube.CardIdentity("Exalted Angel", ""));
cubeCards.add(new DraftCube.CardIdentity("Exquisite Firecraft", ""));
cubeCards.add(new DraftCube.CardIdentity("Exhume", ""));
cubeCards.add(new DraftCube.CardIdentity("Fact or Fiction", ""));
cubeCards.add(new DraftCube.CardIdentity("Faith's Fetters", ""));
cubeCards.add(new DraftCube.CardIdentity("Faithless Looting", ""));
cubeCards.add(new DraftCube.CardIdentity("Falkenrath Gorger", ""));
cubeCards.add(new DraftCube.CardIdentity("Fastbond", ""));
cubeCards.add(new DraftCube.CardIdentity("Fauna Shaman", ""));
cubeCards.add(new DraftCube.CardIdentity("Fiend Hunter", ""));
cubeCards.add(new DraftCube.CardIdentity("Fiery Confluence", ""));
cubeCards.add(new DraftCube.CardIdentity("Figure of Destiny", ""));
cubeCards.add(new DraftCube.CardIdentity("Fire // Ice", ""));
cubeCards.add(new DraftCube.CardIdentity("Fireblast", ""));
cubeCards.add(new DraftCube.CardIdentity("Firebolt", ""));
cubeCards.add(new DraftCube.CardIdentity("Firedrinker Satyr", ""));
cubeCards.add(new DraftCube.CardIdentity("Flametongue Kavu", ""));
cubeCards.add(new DraftCube.CardIdentity("Flickerwisp", ""));
cubeCards.add(new DraftCube.CardIdentity("Flooded Strand", ""));
cubeCards.add(new DraftCube.CardIdentity("Force of Will", ""));
cubeCards.add(new DraftCube.CardIdentity("Force Spike", ""));
cubeCards.add(new DraftCube.CardIdentity("Frantic Search", ""));
cubeCards.add(new DraftCube.CardIdentity("Freyalise, Llanowar's Fury", ""));
cubeCards.add(new DraftCube.CardIdentity("Frost Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Fyndhorn Elves", ""));
cubeCards.add(new DraftCube.CardIdentity("Gaea's Cradle", ""));
cubeCards.add(new DraftCube.CardIdentity("Garruk Relentless", ""));
cubeCards.add(new DraftCube.CardIdentity("Garruk Wildspeaker", ""));
cubeCards.add(new DraftCube.CardIdentity("Garruk, Apex Predator", ""));
cubeCards.add(new DraftCube.CardIdentity("Garruk, Primal Hunter", ""));
cubeCards.add(new DraftCube.CardIdentity("Geist of Saint Traft", ""));
cubeCards.add(new DraftCube.CardIdentity("Genesis Wave", ""));
cubeCards.add(new DraftCube.CardIdentity("Gideon Jura", ""));
cubeCards.add(new DraftCube.CardIdentity("Gideon, Ally of Zendikar", ""));
cubeCards.add(new DraftCube.CardIdentity("Gifts Ungiven", ""));
cubeCards.add(new DraftCube.CardIdentity("Gilded Lotus", ""));
cubeCards.add(new DraftCube.CardIdentity("Gitaxian Probe", ""));
cubeCards.add(new DraftCube.CardIdentity("Glen Elendra Archmage", ""));
cubeCards.add(new DraftCube.CardIdentity("Go for the Throat", ""));
cubeCards.add(new DraftCube.CardIdentity("Goblin Dark-Dwellers", ""));
cubeCards.add(new DraftCube.CardIdentity("Goblin Guide", ""));
cubeCards.add(new DraftCube.CardIdentity("Goblin Welder", ""));
cubeCards.add(new DraftCube.CardIdentity("Godless Shrine", ""));
cubeCards.add(new DraftCube.CardIdentity("Golgari Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Grave Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Green Sun's Zenith", ""));
cubeCards.add(new DraftCube.CardIdentity("Grim Lavamancer", ""));
cubeCards.add(new DraftCube.CardIdentity("Grim Monolith", ""));
cubeCards.add(new DraftCube.CardIdentity("Grim Tutor", ""));
cubeCards.add(new DraftCube.CardIdentity("Griselbrand", ""));
cubeCards.add(new DraftCube.CardIdentity("Gruul Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Gurmag Angler", ""));
cubeCards.add(new DraftCube.CardIdentity("Gush", ""));
cubeCards.add(new DraftCube.CardIdentity("Guttersnipe", ""));
cubeCards.add(new DraftCube.CardIdentity("Hallowed Fountain", ""));
cubeCards.add(new DraftCube.CardIdentity("Hangarback Walker", ""));
cubeCards.add(new DraftCube.CardIdentity("Harmonize", ""));
cubeCards.add(new DraftCube.CardIdentity("Heartbeat of Spring", ""));
cubeCards.add(new DraftCube.CardIdentity("Hedron Archive", ""));
cubeCards.add(new DraftCube.CardIdentity("Heir of Falkenrath", ""));
cubeCards.add(new DraftCube.CardIdentity("Hellrider", ""));
cubeCards.add(new DraftCube.CardIdentity("Hero of Bladehold", ""));
cubeCards.add(new DraftCube.CardIdentity("Hero's Downfall", ""));
cubeCards.add(new DraftCube.CardIdentity("High Tide", ""));
cubeCards.add(new DraftCube.CardIdentity("Hissing Quagmire", ""));
cubeCards.add(new DraftCube.CardIdentity("Honor of the Pure", ""));
cubeCards.add(new DraftCube.CardIdentity("Huntmaster of the Fells", ""));
cubeCards.add(new DraftCube.CardIdentity("Hymn to Tourach", ""));
cubeCards.add(new DraftCube.CardIdentity("Hypnotic Specter", ""));
cubeCards.add(new DraftCube.CardIdentity("Imperial Recruiter", ""));
cubeCards.add(new DraftCube.CardIdentity("Imperial Seal", ""));
cubeCards.add(new DraftCube.CardIdentity("Impulse", ""));
cubeCards.add(new DraftCube.CardIdentity("Incinerate", ""));
cubeCards.add(new DraftCube.CardIdentity("Inferno Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Inkwell Leviathan", ""));
cubeCards.add(new DraftCube.CardIdentity("Inquisition of Kozilek", ""));
cubeCards.add(new DraftCube.CardIdentity("Iona, Shield of Emeria", ""));
cubeCards.add(new DraftCube.CardIdentity("Isamaru, Hound of Konda", ""));
cubeCards.add(new DraftCube.CardIdentity("Isochron Scepter", ""));
cubeCards.add(new DraftCube.CardIdentity("Izzet Charm", ""));
cubeCards.add(new DraftCube.CardIdentity("Izzet Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Jace Beleren", ""));
cubeCards.add(new DraftCube.CardIdentity("Jace, Architect of Thought", ""));
cubeCards.add(new DraftCube.CardIdentity("Jace, the Mind Sculptor", ""));
cubeCards.add(new DraftCube.CardIdentity("Jace, Vryn's Prodigy", ""));
cubeCards.add(new DraftCube.CardIdentity("Jackal Pup", ""));
cubeCards.add(new DraftCube.CardIdentity("Joraga Treespeaker", ""));
cubeCards.add(new DraftCube.CardIdentity("Kalitas, Traitor of Ghet", ""));
cubeCards.add(new DraftCube.CardIdentity("Karakas", ""));
cubeCards.add(new DraftCube.CardIdentity("Kargan Dragonlord", ""));
cubeCards.add(new DraftCube.CardIdentity("Karn Liberated", ""));
cubeCards.add(new DraftCube.CardIdentity("Kiki-Jiki, Mirror Breaker", ""));
cubeCards.add(new DraftCube.CardIdentity("Kitchen Finks", ""));
cubeCards.add(new DraftCube.CardIdentity("Knight of the White Orchid", ""));
cubeCards.add(new DraftCube.CardIdentity("Kolaghan's Command", ""));
cubeCards.add(new DraftCube.CardIdentity("Koth of the Hammer", ""));
cubeCards.add(new DraftCube.CardIdentity("Kozilek, Butcher of Truth", ""));
cubeCards.add(new DraftCube.CardIdentity("Kozilek, the Great Distortion", ""));
cubeCards.add(new DraftCube.CardIdentity("Kuldotha Forgemaster", ""));
cubeCards.add(new DraftCube.CardIdentity("Kytheon, Hero of Akros", ""));
cubeCards.add(new DraftCube.CardIdentity("Land Tax", ""));
cubeCards.add(new DraftCube.CardIdentity("Lavaclaw Reaches", ""));
cubeCards.add(new DraftCube.CardIdentity("Leonin Relic-Warder", ""));
cubeCards.add(new DraftCube.CardIdentity("Leyline of Sanctity", ""));
cubeCards.add(new DraftCube.CardIdentity("Library of Alexandria", ""));
cubeCards.add(new DraftCube.CardIdentity("Lifebane Zombie", ""));
cubeCards.add(new DraftCube.CardIdentity("Lightning Bolt", ""));
cubeCards.add(new DraftCube.CardIdentity("Lightning Greaves", ""));
cubeCards.add(new DraftCube.CardIdentity("Lightning Helix", ""));
cubeCards.add(new DraftCube.CardIdentity("Lightning Mauler", ""));
cubeCards.add(new DraftCube.CardIdentity("Lightning Strike", ""));
cubeCards.add(new DraftCube.CardIdentity("Liliana of the Veil", ""));
cubeCards.add(new DraftCube.CardIdentity("Lingering Souls", ""));
cubeCards.add(new DraftCube.CardIdentity("Linvala, Keeper of Silence", ""));
cubeCards.add(new DraftCube.CardIdentity("Linvala, the Preserver", ""));
cubeCards.add(new DraftCube.CardIdentity("Lion's Eye Diamond", ""));
cubeCards.add(new DraftCube.CardIdentity("Living Death", ""));
cubeCards.add(new DraftCube.CardIdentity("Llanowar Elves", ""));
cubeCards.add(new DraftCube.CardIdentity("Lodestone Golem", ""));
cubeCards.add(new DraftCube.CardIdentity("Looter il-Kor", ""));
cubeCards.add(new DraftCube.CardIdentity("Lotus Bloom", ""));
cubeCards.add(new DraftCube.CardIdentity("Lotus Cobra", ""));
cubeCards.add(new DraftCube.CardIdentity("Lumbering Falls", ""));
cubeCards.add(new DraftCube.CardIdentity("Maelstrom Pulse", ""));
cubeCards.add(new DraftCube.CardIdentity("Magma Jet", ""));
cubeCards.add(new DraftCube.CardIdentity("Magus of the Moon", ""));
cubeCards.add(new DraftCube.CardIdentity("Magus of the Wheel", ""));
cubeCards.add(new DraftCube.CardIdentity("Makeshift Mannequin", ""));
cubeCards.add(new DraftCube.CardIdentity("Managorger Hydra", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Confluence", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Crypt", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Drain", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Leak", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Tithe", ""));
cubeCards.add(new DraftCube.CardIdentity("Mana Vault", ""));
cubeCards.add(new DraftCube.CardIdentity("Manic Vandal", ""));
cubeCards.add(new DraftCube.CardIdentity("Mardu Woe-Reaper", ""));
cubeCards.add(new DraftCube.CardIdentity("Marsh Flats", ""));
cubeCards.add(new DraftCube.CardIdentity("Massacre Wurm", ""));
cubeCards.add(new DraftCube.CardIdentity("Master of the Wild Hunt", ""));
cubeCards.add(new DraftCube.CardIdentity("Maze of Ith", ""));
cubeCards.add(new DraftCube.CardIdentity("Meloku the Clouded Mirror", ""));
cubeCards.add(new DraftCube.CardIdentity("Mental Misstep", ""));
cubeCards.add(new DraftCube.CardIdentity("Memory Jar", ""));
cubeCards.add(new DraftCube.CardIdentity("Mesmeric Fiend", ""));
cubeCards.add(new DraftCube.CardIdentity("Metalworker", ""));
cubeCards.add(new DraftCube.CardIdentity("Mind Twist", ""));
cubeCards.add(new DraftCube.CardIdentity("Mindslaver", ""));
cubeCards.add(new DraftCube.CardIdentity("Mind's Desire", ""));
cubeCards.add(new DraftCube.CardIdentity("Mirari's Wake", ""));
cubeCards.add(new DraftCube.CardIdentity("Mirran Crusader", ""));
cubeCards.add(new DraftCube.CardIdentity("Mishra's Factory", ""));
cubeCards.add(new DraftCube.CardIdentity("Mishra's Workshop", ""));
cubeCards.add(new DraftCube.CardIdentity("Misty Rainforest", ""));
cubeCards.add(new DraftCube.CardIdentity("Mizzium Mortars", ""));
cubeCards.add(new DraftCube.CardIdentity("Moat", ""));
cubeCards.add(new DraftCube.CardIdentity("Monastery Mentor", ""));
cubeCards.add(new DraftCube.CardIdentity("Monastery Swiftspear", ""));
cubeCards.add(new DraftCube.CardIdentity("Mother of Runes", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Diamond", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Emerald", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Jet", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Pearl", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Ruby", ""));
cubeCards.add(new DraftCube.CardIdentity("Mox Sapphire", ""));
cubeCards.add(new DraftCube.CardIdentity("Mulldrifter", ""));
cubeCards.add(new DraftCube.CardIdentity("Murderous Cut", ""));
cubeCards.add(new DraftCube.CardIdentity("Mutavault", ""));
cubeCards.add(new DraftCube.CardIdentity("Myr Battlesphere", ""));
cubeCards.add(new DraftCube.CardIdentity("Mystical Tutor", ""));
cubeCards.add(new DraftCube.CardIdentity("Mystic Confluence", ""));
cubeCards.add(new DraftCube.CardIdentity("Mystic Snake", ""));
cubeCards.add(new DraftCube.CardIdentity("Nahiri, the Harbinger", ""));
cubeCards.add(new DraftCube.CardIdentity("Natural Order", ""));
cubeCards.add(new DraftCube.CardIdentity("Nature's Claim", ""));
cubeCards.add(new DraftCube.CardIdentity("Necromancy", ""));
cubeCards.add(new DraftCube.CardIdentity("Necropotence", ""));
cubeCards.add(new DraftCube.CardIdentity("Needle Spires", ""));
cubeCards.add(new DraftCube.CardIdentity("Nekrataal", ""));
cubeCards.add(new DraftCube.CardIdentity("Nevinyrral's Disk", ""));
cubeCards.add(new DraftCube.CardIdentity("Nezumi Graverobber", ""));
cubeCards.add(new DraftCube.CardIdentity("Nezumi Shortfang", ""));
cubeCards.add(new DraftCube.CardIdentity("Nicol Bolas, Planeswalker", ""));
cubeCards.add(new DraftCube.CardIdentity("Nissa, Worldwaker", ""));
cubeCards.add(new DraftCube.CardIdentity("Noble Hierarch", ""));
cubeCards.add(new DraftCube.CardIdentity("Nykthos, Shrine to Nyx", ""));
cubeCards.add(new DraftCube.CardIdentity("Oath of Druids", ""));
cubeCards.add(new DraftCube.CardIdentity("Oath of Nissa", ""));
cubeCards.add(new DraftCube.CardIdentity("Oblivion Ring", ""));
cubeCards.add(new DraftCube.CardIdentity("Olivia Voldaren", ""));
cubeCards.add(new DraftCube.CardIdentity("Oona's Prowler", ""));
cubeCards.add(new DraftCube.CardIdentity("Ophiomancer", ""));
cubeCards.add(new DraftCube.CardIdentity("Opposition", ""));
cubeCards.add(new DraftCube.CardIdentity("Oracle of Mul Daya", ""));
cubeCards.add(new DraftCube.CardIdentity("Orzhov Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Outpost Siege", ""));
cubeCards.add(new DraftCube.CardIdentity("Overgrown Tomb", ""));
cubeCards.add(new DraftCube.CardIdentity("Pack Rat", ""));
cubeCards.add(new DraftCube.CardIdentity("Painful Truths", ""));
cubeCards.add(new DraftCube.CardIdentity("Palinchron", ""));
cubeCards.add(new DraftCube.CardIdentity("Parallax Wave", ""));
cubeCards.add(new DraftCube.CardIdentity("Path to Exile", ""));
cubeCards.add(new DraftCube.CardIdentity("Pentad Prism", ""));
cubeCards.add(new DraftCube.CardIdentity("Pernicious Deed", ""));
cubeCards.add(new DraftCube.CardIdentity("Pestermite", ""));
cubeCards.add(new DraftCube.CardIdentity("Phantasmal Image", ""));
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Metamorph", ""));
cubeCards.add(new DraftCube.CardIdentity("Phyrexian Revoker", ""));
cubeCards.add(new DraftCube.CardIdentity("Pithing Needle", ""));
cubeCards.add(new DraftCube.CardIdentity("Plateau", ""));
cubeCards.add(new DraftCube.CardIdentity("Polluted Delta", ""));
cubeCards.add(new DraftCube.CardIdentity("Polukranos, World Eater", ""));
cubeCards.add(new DraftCube.CardIdentity("Ponder", ""));
cubeCards.add(new DraftCube.CardIdentity("Porcelain Legionnaire", ""));
cubeCards.add(new DraftCube.CardIdentity("Preordain", ""));
cubeCards.add(new DraftCube.CardIdentity("Primal Command", ""));
cubeCards.add(new DraftCube.CardIdentity("Primeval Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Progenitus", ""));
cubeCards.add(new DraftCube.CardIdentity("Puppeteer Clique", ""));
cubeCards.add(new DraftCube.CardIdentity("Putrid Imp", ""));
cubeCards.add(new DraftCube.CardIdentity("Qasali Pridemage", ""));
cubeCards.add(new DraftCube.CardIdentity("Quicken", ""));
cubeCards.add(new DraftCube.CardIdentity("Raging Ravine", ""));
cubeCards.add(new DraftCube.CardIdentity("Rakdos Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Rakdos's Return", ""));
cubeCards.add(new DraftCube.CardIdentity("Ral Zarek", ""));
cubeCards.add(new DraftCube.CardIdentity("Ravages of War", ""));
cubeCards.add(new DraftCube.CardIdentity("Reanimate", ""));
cubeCards.add(new DraftCube.CardIdentity("Reckless Bushwhacker", ""));
cubeCards.add(new DraftCube.CardIdentity("Reclamation Sage", ""));
cubeCards.add(new DraftCube.CardIdentity("Recurring Nightmare", ""));
cubeCards.add(new DraftCube.CardIdentity("Reflector Mage", ""));
cubeCards.add(new DraftCube.CardIdentity("Regrowth", ""));
cubeCards.add(new DraftCube.CardIdentity("Remand", ""));
cubeCards.add(new DraftCube.CardIdentity("Repeal", ""));
cubeCards.add(new DraftCube.CardIdentity("Restoration Angel", ""));
cubeCards.add(new DraftCube.CardIdentity("Reveillark", ""));
cubeCards.add(new DraftCube.CardIdentity("Rift Bolt", ""));
cubeCards.add(new DraftCube.CardIdentity("Riftwing Cloudskate", ""));
cubeCards.add(new DraftCube.CardIdentity("Rishadan Port", ""));
cubeCards.add(new DraftCube.CardIdentity("Roast", ""));
cubeCards.add(new DraftCube.CardIdentity("Rofellos, Llanowar Emissary", ""));
cubeCards.add(new DraftCube.CardIdentity("Sacred Foundry", ""));
cubeCards.add(new DraftCube.CardIdentity("Sakura-Tribe Elder", ""));
cubeCards.add(new DraftCube.CardIdentity("Savannah", ""));
cubeCards.add(new DraftCube.CardIdentity("Scalding Tarn", ""));
cubeCards.add(new DraftCube.CardIdentity("Scavenging Ooze", ""));
cubeCards.add(new DraftCube.CardIdentity("Scroll Rack", ""));
cubeCards.add(new DraftCube.CardIdentity("Scrubland", ""));
cubeCards.add(new DraftCube.CardIdentity("Search for Tomorrow", ""));
cubeCards.add(new DraftCube.CardIdentity("Searing Blaze", ""));
cubeCards.add(new DraftCube.CardIdentity("Searing Spear", ""));
cubeCards.add(new DraftCube.CardIdentity("Seasons Past", ""));
cubeCards.add(new DraftCube.CardIdentity("Secure the Wastes", ""));
cubeCards.add(new DraftCube.CardIdentity("Seeker of the Way", ""));
cubeCards.add(new DraftCube.CardIdentity("Seething Song", ""));
cubeCards.add(new DraftCube.CardIdentity("Selesnya Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Sensei's Divining Top", ""));
cubeCards.add(new DraftCube.CardIdentity("Shadowmage Infiltrator", ""));
cubeCards.add(new DraftCube.CardIdentity("Shallow Grave", ""));
cubeCards.add(new DraftCube.CardIdentity("Shambling Vent", ""));
cubeCards.add(new DraftCube.CardIdentity("Shardless Agent", ""));
cubeCards.add(new DraftCube.CardIdentity("Shelldock Isle", ""));
cubeCards.add(new DraftCube.CardIdentity("Sheoldred, Whispering One", ""));
cubeCards.add(new DraftCube.CardIdentity("Show and Tell", ""));
cubeCards.add(new DraftCube.CardIdentity("Shriekmaw", ""));
cubeCards.add(new DraftCube.CardIdentity("Shrine of Burning Rage", ""));
cubeCards.add(new DraftCube.CardIdentity("Sidisi, Undead Vizier", ""));
cubeCards.add(new DraftCube.CardIdentity("Siege-Gang Commander", ""));
cubeCards.add(new DraftCube.CardIdentity("Silverblade Paladin", ""));
cubeCards.add(new DraftCube.CardIdentity("Simic Signet", ""));
cubeCards.add(new DraftCube.CardIdentity("Skinrender", ""));
cubeCards.add(new DraftCube.CardIdentity("Skullclamp", ""));
cubeCards.add(new DraftCube.CardIdentity("Smash to Smithereens", ""));
cubeCards.add(new DraftCube.CardIdentity("Smokestack", ""));
cubeCards.add(new DraftCube.CardIdentity("Snapcaster Mage", ""));
cubeCards.add(new DraftCube.CardIdentity("Sneak Attack", ""));
cubeCards.add(new DraftCube.CardIdentity("Sol Ring", ""));
cubeCards.add(new DraftCube.CardIdentity("Soldier of the Pantheon", ""));
cubeCards.add(new DraftCube.CardIdentity("Solemn Simulacrum", ""));
cubeCards.add(new DraftCube.CardIdentity("Song of the Dryads", ""));
cubeCards.add(new DraftCube.CardIdentity("Soulfire Grand Master", ""));
cubeCards.add(new DraftCube.CardIdentity("Sower of Temptation", ""));
cubeCards.add(new DraftCube.CardIdentity("Spear of Heliod", ""));
cubeCards.add(new DraftCube.CardIdentity("Spectral Procession", ""));
cubeCards.add(new DraftCube.CardIdentity("Spell Pierce", ""));
cubeCards.add(new DraftCube.CardIdentity("Spellskite", ""));
cubeCards.add(new DraftCube.CardIdentity("Sphinx of the Steel Wind", ""));
cubeCards.add(new DraftCube.CardIdentity("Sphinx's Revelation", ""));
cubeCards.add(new DraftCube.CardIdentity("Spirit of the Labyrinth", ""));
cubeCards.add(new DraftCube.CardIdentity("Splinter Twin", ""));
cubeCards.add(new DraftCube.CardIdentity("Staff of Domination", ""));
cubeCards.add(new DraftCube.CardIdentity("Steam Vents", ""));
cubeCards.add(new DraftCube.CardIdentity("Stirring Wildwood", ""));
cubeCards.add(new DraftCube.CardIdentity("Stomping Ground", ""));
cubeCards.add(new DraftCube.CardIdentity("Stoneforge Mystic", ""));
cubeCards.add(new DraftCube.CardIdentity("Stormbreath Dragon", ""));
cubeCards.add(new DraftCube.CardIdentity("Strip Mine", ""));
cubeCards.add(new DraftCube.CardIdentity("Student of Warfare", ""));
cubeCards.add(new DraftCube.CardIdentity("Sulfuric Vortex", ""));
cubeCards.add(new DraftCube.CardIdentity("Sun Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Sundering Titan", ""));
cubeCards.add(new DraftCube.CardIdentity("Supreme Verdict", ""));
cubeCards.add(new DraftCube.CardIdentity("Survival of the Fittest", ""));
cubeCards.add(new DraftCube.CardIdentity("Sword of Body and Mind", ""));
cubeCards.add(new DraftCube.CardIdentity("Sword of Feast and Famine", ""));
cubeCards.add(new DraftCube.CardIdentity("Sword of Fire and Ice", ""));
cubeCards.add(new DraftCube.CardIdentity("Sword of Light and Shadow", ""));
cubeCards.add(new DraftCube.CardIdentity("Sword of War and Peace", ""));
cubeCards.add(new DraftCube.CardIdentity("Swords to Plowshares", ""));
cubeCards.add(new DraftCube.CardIdentity("Sylvan Caryatid", ""));
cubeCards.add(new DraftCube.CardIdentity("Sylvan Library", ""));
cubeCards.add(new DraftCube.CardIdentity("Taiga", ""));
cubeCards.add(new DraftCube.CardIdentity("Tamiyo, the Moon Sage", ""));
cubeCards.add(new DraftCube.CardIdentity("Tangle Wire", ""));
cubeCards.add(new DraftCube.CardIdentity("Tarmogoyf", ""));
cubeCards.add(new DraftCube.CardIdentity("Tasigur, the Golden Fang", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple Garden", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Abandon", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Deceit", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Enlightenment", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Epiphany", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Malady", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Malice", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Mystery", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Plenty", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Silence", ""));
cubeCards.add(new DraftCube.CardIdentity("Temple of Triumph", ""));
cubeCards.add(new DraftCube.CardIdentity("Tendrils of Agony", ""));
cubeCards.add(new DraftCube.CardIdentity("Terastodon", ""));
cubeCards.add(new DraftCube.CardIdentity("Terminate", ""));
cubeCards.add(new DraftCube.CardIdentity("Tezzeret the Seeker", ""));
cubeCards.add(new DraftCube.CardIdentity("Tezzeret, Agent of Bolas", ""));
cubeCards.add(new DraftCube.CardIdentity("Thada Adel, Acquisitor", ""));
cubeCards.add(new DraftCube.CardIdentity("Thalia, Guardian of Thraben", ""));
cubeCards.add(new DraftCube.CardIdentity("The Abyss", ""));
cubeCards.add(new DraftCube.CardIdentity("Thing in the Ice", ""));
cubeCards.add(new DraftCube.CardIdentity("Thirst for Knowledge", ""));
cubeCards.add(new DraftCube.CardIdentity("Thoughtseize", ""));
cubeCards.add(new DraftCube.CardIdentity("Thragtusk", ""));
cubeCards.add(new DraftCube.CardIdentity("Thran Dynamo", ""));
cubeCards.add(new DraftCube.CardIdentity("Through the Breach", ""));
cubeCards.add(new DraftCube.CardIdentity("Thrun, the Last Troll", ""));
cubeCards.add(new DraftCube.CardIdentity("Thundermaw Hellkite", ""));
cubeCards.add(new DraftCube.CardIdentity("Tidehollow Sculler", ""));
cubeCards.add(new DraftCube.CardIdentity("Time Spiral", ""));
cubeCards.add(new DraftCube.CardIdentity("Time Walk", ""));
cubeCards.add(new DraftCube.CardIdentity("Timely Reinforcements", ""));
cubeCards.add(new DraftCube.CardIdentity("Timetwister", ""));
cubeCards.add(new DraftCube.CardIdentity("Tinker", ""));
cubeCards.add(new DraftCube.CardIdentity("Tolarian Academy", ""));
cubeCards.add(new DraftCube.CardIdentity("Tooth and Nail", ""));
cubeCards.add(new DraftCube.CardIdentity("Torch Fiend", ""));
cubeCards.add(new DraftCube.CardIdentity("Toxic Deluge", ""));
cubeCards.add(new DraftCube.CardIdentity("Traverse the Ulvenwald", ""));
cubeCards.add(new DraftCube.CardIdentity("Treachery", ""));
cubeCards.add(new DraftCube.CardIdentity("Treasure Cruise", ""));
cubeCards.add(new DraftCube.CardIdentity("Trinket Mage", ""));
cubeCards.add(new DraftCube.CardIdentity("Tropical Island", ""));
cubeCards.add(new DraftCube.CardIdentity("True-Name Nemesis", ""));
cubeCards.add(new DraftCube.CardIdentity("Trygon Predator", ""));
cubeCards.add(new DraftCube.CardIdentity("Tundra", ""));
cubeCards.add(new DraftCube.CardIdentity("Turnabout", ""));
cubeCards.add(new DraftCube.CardIdentity("Ugin, the Spirit Dragon", ""));
cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Ceaseless Hunger", ""));
cubeCards.add(new DraftCube.CardIdentity("Ulamog, the Infinite Gyre", ""));
cubeCards.add(new DraftCube.CardIdentity("Ultimate Price", ""));
cubeCards.add(new DraftCube.CardIdentity("Umezawa's Jitte", ""));
cubeCards.add(new DraftCube.CardIdentity("Unburial Rites", ""));
cubeCards.add(new DraftCube.CardIdentity("Underground Sea", ""));
cubeCards.add(new DraftCube.CardIdentity("Unexpectedly Absent", ""));
cubeCards.add(new DraftCube.CardIdentity("Upheaval", ""));
cubeCards.add(new DraftCube.CardIdentity("Urborg, Tomb of Yawgmoth", ""));
cubeCards.add(new DraftCube.CardIdentity("Vampire Nighthawk", ""));
cubeCards.add(new DraftCube.CardIdentity("Vampiric Tutor", ""));
cubeCards.add(new DraftCube.CardIdentity("Vedalken Shackles", ""));
cubeCards.add(new DraftCube.CardIdentity("Vendilion Clique", ""));
cubeCards.add(new DraftCube.CardIdentity("Venser, Shaper Savant", ""));
cubeCards.add(new DraftCube.CardIdentity("Verdant Catacombs", ""));
cubeCards.add(new DraftCube.CardIdentity("Villainous Wealth", ""));
cubeCards.add(new DraftCube.CardIdentity("Vindicate", ""));
cubeCards.add(new DraftCube.CardIdentity("Voice of Resurgence", ""));
cubeCards.add(new DraftCube.CardIdentity("Volcanic Island", ""));
cubeCards.add(new DraftCube.CardIdentity("Vryn Wingmare", ""));
cubeCards.add(new DraftCube.CardIdentity("Wall of Blossoms", ""));
cubeCards.add(new DraftCube.CardIdentity("Wall of Omens", ""));
cubeCards.add(new DraftCube.CardIdentity("Wall of Roots", ""));
cubeCards.add(new DraftCube.CardIdentity("Wandering Fumarole", ""));
cubeCards.add(new DraftCube.CardIdentity("War Priest of Thune", ""));
cubeCards.add(new DraftCube.CardIdentity("Wasteland", ""));
cubeCards.add(new DraftCube.CardIdentity("Watery Grave", ""));
cubeCards.add(new DraftCube.CardIdentity("Westvale Abbey", ""));
cubeCards.add(new DraftCube.CardIdentity("Wheel of Fortune", ""));
cubeCards.add(new DraftCube.CardIdentity("Whisperwood Elemental", ""));
cubeCards.add(new DraftCube.CardIdentity("Wildfire", ""));
cubeCards.add(new DraftCube.CardIdentity("Windswept Heath", ""));
cubeCards.add(new DraftCube.CardIdentity("Winter Orb", ""));
cubeCards.add(new DraftCube.CardIdentity("Wolfir Silverheart", ""));
cubeCards.add(new DraftCube.CardIdentity("Wooded Foothills", ""));
cubeCards.add(new DraftCube.CardIdentity("Woodfall Primus", ""));
cubeCards.add(new DraftCube.CardIdentity("Worn Powerstone", ""));
cubeCards.add(new DraftCube.CardIdentity("Wrath of God", ""));
cubeCards.add(new DraftCube.CardIdentity("Wurmcoil Engine", ""));
cubeCards.add(new DraftCube.CardIdentity("Xenagos, the Reveler", ""));
cubeCards.add(new DraftCube.CardIdentity("Yavimaya Elder", ""));
cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Bargain", ""));
cubeCards.add(new DraftCube.CardIdentity("Yawgmoth's Will", ""));
cubeCards.add(new DraftCube.CardIdentity("Young Pyromancer", ""));
cubeCards.add(new DraftCube.CardIdentity("Zealous Conscripts", ""));
cubeCards.add(new DraftCube.CardIdentity("Zurgo Bellstriker", ""));
}
}

View file

@ -81,6 +81,7 @@
<tournamentType name="Booster Draft Elimination (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftEliminationTournament" typeName="mage.tournament.BoosterDraftEliminationCubeTournamentType"/>
<tournamentType name="Booster Draft Elimination (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftEliminationTournament" typeName="mage.tournament.RandomBoosterDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManDraftEliminationTournament" typeName="mage.tournament.RichManDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Elimination (Rich Man Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RichManCubeDraftEliminationTournament" typeName="mage.tournament.RichManCubeDraftEliminationTournamentType"/>
<tournamentType name="Booster Draft Swiss" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissTournamentType"/>
<tournamentType name="Booster Draft Swiss (Cube)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.BoosterDraftSwissTournament" typeName="mage.tournament.BoosterDraftSwissCubeTournamentType"/>
<tournamentType name="Booster Draft Swiss (Random)" jar="mage-tournament-booster-draft.jar" className="mage.tournament.RandomBoosterDraftSwissTournament" typeName="mage.tournament.RandomBoosterDraftSwissTournamentType"/>

View file

@ -251,20 +251,28 @@ class TableListSorter implements Comparator<Table> {
} else {
return two.getEndTime().compareTo(one.getEndTime());
}
} else if (one.getEndTime() != null) {
return -1;
}
if (two.getStartTime() != null) {
if (one.getStartTime() == null) {
return 1;
} else {
return two.getStartTime().compareTo(one.getStartTime());
}
} else if (one.getStartTime() != null) {
return -1;
}
if (two.getCreateTime() != null) {
if (one.getCreateTime() == null) {
return 1;
} else {
return two.getCreateTime().compareTo(one.getCreateTime());
}
} else if (one.getCreateTime() != null) {
return -1;
}
return 0;
}

View file

@ -56,9 +56,6 @@ public class ThoughtHemorrhage extends CardImpl {
super(ownerId, 47, "Thought Hemorrhage", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{R}");
this.expansionSetCode = "ARB";
// Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME));
@ -93,7 +90,7 @@ class ThoughtHemorrhageEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY);
if (sourceObject != null && controller != null && cardName != null && !cardName.isEmpty()) {
if (sourceObject != null && controller != null && cardName != null && !cardName.isEmpty()) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
targetPlayer.revealCards("hand of " + targetPlayer.getName(), targetPlayer.getHand(), game);
@ -123,7 +120,7 @@ class ThoughtHemorrhageEffect extends OneShotEffect {
// search cards in hand
TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards);
controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game);
for(UUID cardId: targetCardsHand.getTargets()) {
for (UUID cardId : targetCardsHand.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND, true);
@ -134,14 +131,14 @@ class ThoughtHemorrhageEffect extends OneShotEffect {
// If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it.
TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards);
controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId());
for(UUID cardId: targetCardsLibrary.getTargets()) {
for (UUID cardId : targetCardsLibrary.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true);
}
}
targetPlayer.shuffleLibrary(source, game);
return true;
return true;
}
}
return false;

View file

@ -218,7 +218,9 @@ class TawnossCoffinReturnEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
ExileZone exileZone = game.getExile().getExileZone(source.getSourceId());
if (exileZone == null) {
return true;
}
FilterCard filter = new FilterCard();
filter.add(new CardTypePredicate(CardType.CREATURE));
//There should be only 1 there, but the for each loop seems the most practical to get to it

View file

@ -74,7 +74,6 @@ public class TundraKavu extends CardImpl {
}
}
class TundraKavuEffect extends BecomesBasicLandTargetEffect {
public TundraKavuEffect() {
@ -86,6 +85,7 @@ class TundraKavuEffect extends BecomesBasicLandTargetEffect {
super(effect);
}
@Override
public TundraKavuEffect copy() {
return new TundraKavuEffect(this);
}
@ -94,14 +94,18 @@ class TundraKavuEffect extends BecomesBasicLandTargetEffect {
public void init(Ability source, Game game) {
landTypes.clear();
Player controller = game.getPlayer(source.getControllerId());
if(controller != null) {
if (controller != null) {
Set<String> choiceSet = new LinkedHashSet<>();
choiceSet.add("Island");
choiceSet.add("Plains");
ChoiceImpl choice = new ChoiceImpl(true);
choice.setChoices(choiceSet);
choice.setMessage("Choose a basic land type");
controller.choose(outcome, choice, game);
while (!controller.choose(outcome, choice, game)) {
if (!controller.canRespond()) {
return;
}
}
landTypes.add(choice.getChoice());
} else {
this.discard();

View file

@ -0,0 +1,171 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.archenemy;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.util.CardUtil;
/**
*
* @author spjspj
*/
public class SynodSanctum extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanent you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
}
public SynodSanctum(UUID ownerId) {
super(ownerId, 120, "Synod Sanctum", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}");
this.expansionSetCode = "ARC";
// {2}, {tap}: Exile target permanent you control.
SynodSanctumEffect effect = new SynodSanctumEffect();
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}"));
ability.addCost(new TapSourceCost());
Target target = new TargetPermanent(filter);
ability.addTarget(target);
this.addAbility(ability);
// {2}, Sacrifice Synod Sanctum: Return all cards exiled with Synod Sanctum to the battlefield under your control.
SynodSanctumEffect2 effect2 = new SynodSanctumEffect2();
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect2, new ManaCostsImpl("{2}"));
ability2.addCost(new SacrificeSourceCost());
this.addAbility(ability2);
}
public SynodSanctum(final SynodSanctum card) {
super(card);
}
@Override
public SynodSanctum copy() {
return new SynodSanctum(this);
}
}
class SynodSanctumEffect extends OneShotEffect {
SynodSanctumEffect() {
super(Outcome.Benefit);
staticText = "Exile target permanent you control";
}
SynodSanctumEffect(SynodSanctumEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
if (getTargetPointer().getFirst(game, source) != null) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exileZone != null && controller.moveCardToExileWithInfo(permanent, exileZone, sourceObject.getIdName(), source.getId(), game, Zone.BATTLEFIELD, true)) {
return true;
}
}
}
}
return false;
}
@Override
public SynodSanctumEffect copy() {
return new SynodSanctumEffect(this);
}
}
class SynodSanctumEffect2 extends OneShotEffect {
SynodSanctumEffect2() {
super(Outcome.Benefit);
staticText = "Return all cards exiled with {this} to the battlefield under your control";
}
SynodSanctumEffect2(SynodSanctumEffect2 effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exileId == null) {
return false;
}
ExileZone exile = game.getExile().getExileZone(exileId);
if (exile == null) {
return false;
}
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
boolean allReturned = true;
if (controller != null && sourceObject != null) {
for (Card card : exile.getCards(game)) {
if (!card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), controller.getId())) {
allReturned = false;
}
}
return allReturned;
}
return false;
}
@Override
public SynodSanctumEffect2 copy() {
return new SynodSanctumEffect2(this);
}
}

View file

@ -58,7 +58,7 @@ public class AdverseConditions extends CardImpl {
// Tap up to two target creatures. Those creatures don't untap during their controller's next untap step.
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect());
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
// Put a 1/1 colorless Eldrazi Scion creature token onto the battlefield. It has "Sacrifice this creature: Add {C} to your mana pool."
Effect effect = new CreateTokenEffect(new EldraziScionToken());
effect.setText("put a 1/1 colorless Eldrazi Scion creature token onto the battlefield. It has \"Sacrifice this creature: Add {C} to your mana pool.\"");

View file

@ -28,9 +28,9 @@
package mage.sets.bornofthegods;
import java.util.UUID;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
@ -50,7 +50,7 @@ public class SuddenStorm extends CardImpl {
// Tap up to two target creatures. Those creatures don't untap during their controllers' next untap steps. Scry 1.
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect());
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
this.getSpellAbility().addEffect(new ScryEffect(1));
}

View file

@ -1,16 +1,16 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,7 +20,7 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
@ -52,11 +52,10 @@ public class CranialExtraction extends CardImpl {
public CranialExtraction(UUID ownerId) {
super(ownerId, 105, "Cranial Extraction", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{B}");
this.expansionSetCode = "CHK";
this.subtype.add("Arcane");
this.subtype.add("Arcane");
/* Name a nonland card. Search target player's graveyard, hand, and library for
* all cards with that name and exile them. Then that player shuffles his or her library. */
/* Name a nonland card. Search target player's graveyard, hand, and library for
* all cards with that name and exile them. Then that player shuffles his or her library. */
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new CranialExtractionEffect());
}

View file

@ -25,17 +25,16 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.championsofkamigawa;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.keyword.BushidoAbility;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
* @author Loki
@ -51,9 +50,11 @@ public class KondaLordOfEiganjo extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.addAbility(VigilanceAbility.getInstance());
this.addAbility(new BushidoAbility(5));
this.addAbility(IndestructibleAbility.getInstance());
this.addAbility(new BushidoAbility(5));
}
public KondaLordOfEiganjo(final KondaLordOfEiganjo card) {

View file

@ -244,8 +244,8 @@ class JestersScepterCounterEffect extends OneShotEffect {
String nameOfExiledCardPayment = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment");
String nameOfExiledCardPayment2 = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment2");
if (nameOfExiledCardPayment != null) {
if (nameOfExiledCardPayment.matches(spell.getName())
|| nameOfExiledCardPayment2.matches(spell.getName())) {
if (nameOfExiledCardPayment.equals(spell.getCard().getName())
|| (nameOfExiledCardPayment2 != null) && nameOfExiledCardPayment2.equals(spell.getCard().getName())) {
return game.getStack().counter(targetPointer.getFirst(game, source), source.getSourceId(), game);
}
}

View file

@ -69,7 +69,7 @@ public class Everglades extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(1, 1, filter, true)))));
// {tap}: Add {C}{B} to your mana pool.
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 0, 0, 1, 0, 1), new TapSourceCost()));
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 0, 1, 0, 0, 1), new TapSourceCost()));
}

View file

@ -43,7 +43,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
*/
public class MasterworkOfIngenuity extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact");
private static final FilterPermanent filter = new FilterPermanent("equipment");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));

View file

@ -0,0 +1,130 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.conspiracy;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.permanent.token.Token;
import mage.target.common.TargetLandPermanent;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class IgnitionTeam extends CardImpl {
public IgnitionTeam(UUID ownerId) {
super(ownerId, 34, "Ignition Team", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}{R}");
this.expansionSetCode = "CNS";
this.subtype.add("Goblin");
this.subtype.add("Warrior");
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Ignition Team enters the battlefield with X +1/+1 counters on it, where X is the number of tapped lands on the battlefield.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(0),
new TappedLandsCount(), true),
"with X +1/+1 counters on it, where X is the number of tapped lands on the battlefield."));
// {2}{R}, Remove a +1/+1 counter from Ignition Team: Target land becomes a 4/4 red Elemental creature until end of turn. It's still a land.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(new IgnitionTeamToken(), false, true, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}"));
ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1)));
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
}
public IgnitionTeam(final IgnitionTeam card) {
super(card);
}
@Override
public IgnitionTeam copy() {
return new IgnitionTeam(this);
}
}
class TappedLandsCount implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
if (sourceAbility != null) {
FilterLandPermanent filter = new FilterLandPermanent("tapped lands on the battlefield");
filter.add(new TappedPredicate());
return game.getBattlefield().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
}
return 0;
}
@Override
public DynamicValue copy() {
return new TappedLandsCount();
}
@Override
public String toString() {
return "1";
}
@Override
public String getMessage() {
return "tapped lands on the battlefield";
}
}
class IgnitionTeamToken extends Token {
public IgnitionTeamToken() {
super("", "4/4 red Elemental creature");
this.cardType.add(CardType.CREATURE);
this.getSubtype().add("Elemental");
this.color.setRed(true);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
}
}

View file

@ -28,14 +28,13 @@
package mage.sets.darkascension;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.TargetPlayer;
@ -51,7 +50,6 @@ public class ChaliceOfDeath extends CardImpl {
// this card is the second face of double-faced card
this.nightCard = true;
this.canTransform = true;
// {tap}: Target player loses 5 life.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(5), new TapSourceCost());

View file

@ -167,8 +167,9 @@ class CurseOfEchoesEffect extends OneShotEffect {
@Override
public String getText(Mode mode) {
StringBuilder sb = new StringBuilder();
sb.append("Copy target ").append(mode.getTargets().get(0).getTargetName()).append(". You may choose new targets for the copy");
return sb.toString();
if (mode.getTargets().size() > 0) {
return "Copy target " + mode.getTargets().get(0).getTargetName() + ". You may choose new targets for the copy";
}
return "No target";
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.dissension;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.NameACardEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author Styxo
*/
public class BrainPry extends CardImpl {
public BrainPry(UUID ownerId) {
super(ownerId, 39, "Brain Pry", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{1}{B}");
this.expansionSetCode = "DIS";
//Name a nonland card. Target player reveals his or her hand. That player discards a card with that name. If he or she can't, you draw a card.
this.getSpellAbility().addEffect((new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME)));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new BrainPryEffect());
}
public BrainPry(final BrainPry card) {
super(card);
}
@Override
public BrainPry copy() {
return new BrainPry(this);
}
}
class BrainPryEffect extends OneShotEffect {
public BrainPryEffect() {
super(Outcome.Discard);
staticText = "Target player reveals his or her hand. That player discards a card with that name. If he or she can't, you draw a card";
}
public BrainPryEffect(final BrainPryEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY);
if (targetPlayer != null && controller != null && sourceObject != null && cardName != null) {
Boolean hasDiscarded = false;
for (Card card : targetPlayer.getHand().getCards(game)) {
if (card.getName().equals(cardName)) {
targetPlayer.discard(card, source, game);
hasDiscarded = true;
break;
}
}
if (!hasDiscarded) {
controller.drawCards(1, game);
}
controller.lookAtCards(sourceObject.getName() + " Hand", targetPlayer.getHand(), game);
}
return true;
}
@Override
public BrainPryEffect copy() {
return new BrainPryEffect(this);
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.dissension;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.HellbentCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalAsThoughEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.CanAttackAsThoughItDidntHaveDefenderSourceEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
* @author Styxo
*/
public class SlitheringShade extends CardImpl {
public SlitheringShade(UUID ownerId) {
super(ownerId, 55, "Slithering Shade", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{B}");
this.expansionSetCode = "DIS";
this.subtype.add("Shade");
this.power = new MageInt(0);
this.toughness = new MageInt(1);
//Defender
this.addAbility(DefenderAbility.getInstance());
//{B}: Slithering Shade gets +1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{B}")));
// Hellbent Slithering Shade can attack as though it didn't have defender as long as you have no cards in hand.
Effect effect = new ConditionalAsThoughEffect(
new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield),
HellbentCondition.getInstance());
effect.setText("<i>Hellbent</i> - {this} can attack as though it didn't have defender as long as you have no cards in hand");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
public SlitheringShade(final SlitheringShade card) {
super(card);
}
@Override
public SlitheringShade copy() {
return new SlitheringShade(this);
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class AssembledAlphas extends CardImpl {
public AssembledAlphas(UUID ownerId) {
super(ownerId, 117, "Assembled Alphas", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.expansionSetCode = "EMN";
this.subtype.add("Wolf");
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Whenever Assembled Alphas blocks or becomes blocked by a creature, Assembled Alphas deals 3 damage to that creature and 3 damage to that creature's controller.
Ability ability = new BlocksOrBecomesBlockedByCreatureTriggeredAbility(new DamageTargetEffect(3, true, "that creature"), false);
Effect effect = new DamageTargetControllerEffect(2);
effect.setText("and 3 damage to that creature's controller");
ability.addEffect(effect);
this.addAbility(ability);
}
public AssembledAlphas(final AssembledAlphas card) {
super(card);
}
@Override
public AssembledAlphas copy() {
return new AssembledAlphas(this);
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class AuroraOfEmrakul extends CardImpl {
public AuroraOfEmrakul(UUID ownerId) {
super(ownerId, 193, "Aurora of Emrakul", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Reflection");
this.power = new MageInt(1);
this.toughness = new MageInt(4);
// this card is the second face of double-faced card
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// Whenever Aurora of Emrakul attacks, each opponent loses 3 life.
this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(3),false));
}
public AuroraOfEmrakul(final AuroraOfEmrakul card) {
super(card);
}
@Override
public AuroraOfEmrakul copy() {
return new AuroraOfEmrakul(this);
}
}

View file

@ -0,0 +1,91 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author fireshoes
*/
public class BrunaTheFadingLight extends CardImpl {
private static final FilterCard filter = new FilterCard("Angel or Human creature card");
static {
filter.add(Predicates.and(new CardTypePredicate(CardType.CREATURE),
(Predicates.or(new SubtypePredicate("Human"),
(new SubtypePredicate("Angel"))))));
}
public BrunaTheFadingLight(UUID ownerId) {
super(ownerId, 15, "Bruna, the Fading Light", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{W}{W}");
this.expansionSetCode = "EMN";
this.supertype.add("Legendary");
this.subtype.add("Angel");
this.subtype.add("Horror");
this.power = new MageInt(5);
this.toughness = new MageInt(7);
// When you cast Bruna, the Fading Light, you may return target Angel or Human creature card from your graveyard to the battlefield.
Ability ability = new CastSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// <i>(Melds with Gisela, the Broken Blade.)</i>
}
public BrunaTheFadingLight(final BrunaTheFadingLight card) {
super(card);
}
@Override
public BrunaTheFadingLight copy() {
return new BrunaTheFadingLight(this);
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author fireshoes
*/
public class CemeteryRecruitment extends CardImpl {
public CemeteryRecruitment(UUID ownerId) {
super(ownerId, 83, "Cemetery Recruitment", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}");
this.expansionSetCode = "EMN";
// Return target creature card from your graveyard to your hand. If it's a Zombie card, draw a card.
this.getSpellAbility().addEffect(new CemeteryRecruitmentEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 1, new FilterCreatureCard("creature card from your graveyard")));
}
public CemeteryRecruitment(final CemeteryRecruitment card) {
super(card);
}
@Override
public CemeteryRecruitment copy() {
return new CemeteryRecruitment(this);
}
}
class CemeteryRecruitmentEffect extends OneShotEffect {
public CemeteryRecruitmentEffect() {
super(Outcome.Benefit);
staticText = "Return target creature card from your graveyard to your hand. If it's a Zombie card, draw a card";
}
public CemeteryRecruitmentEffect(final CemeteryRecruitmentEffect effect) {
super(effect);
}
@Override
public CemeteryRecruitmentEffect copy() {
return new CemeteryRecruitmentEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(targetPointer.getFirst(game, source));
if (card != null) {
if (controller.moveCards(card, Zone.HAND, source, game)
&& card.getSubtype().contains("Zombie")) {
controller.drawCards(1, game);
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.MadnessAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class ChillingGrasp extends CardImpl {
public ChillingGrasp(UUID ownerId) {
super(ownerId, 50, "Chilling Grasp", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{U}");
this.expansionSetCode = "EMN";
// Tap up to two target creatures. Those creatures don't untap during their controller's next uptap step.
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
// Madness {3}{U}
this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{3}{U}")));
}
public ChillingGrasp(final ChillingGrasp card) {
super(card);
}
@Override
public ChillingGrasp copy() {
return new ChillingGrasp(this);
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.condition.common.TenOrLessLifeCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.LoseLifeAllPlayersEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
/**
*
* @author fireshoes
*/
public class CryptolithFragment extends CardImpl {
public CryptolithFragment(UUID ownerId) {
super(ownerId, 193, "Cryptolith Fragment", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}");
this.expansionSetCode = "EMN";
this.canTransform = true;
this.secondSideCard = new AuroraOfEmrakul(ownerId);
// Cryptolith Fragment enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {T}: Add one mana of any color to your mana pool. Each player loses 1 life.
Ability AnyColorManaAbility = new AnyColorManaAbility();
AnyColorManaAbility.addEffect(new LoseLifeAllPlayersEffect(1));
this.addAbility(AnyColorManaAbility);
// At the beginning of your upkeep, if each player has 10 or less life, transform Cryptolith Fragment.
this.addAbility(new TransformAbility());
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false),
new TenOrLessLifeCondition(TenOrLessLifeCondition.CheckType.EACH_PLAYER),
"At the beginning of your upkeep, if each player has 10 or less life, transform Cryptolith Fragment."));
}
public CryptolithFragment(final CryptolithFragment card) {
super(card);
}
@Override
public CryptolithFragment copy() {
return new CryptolithFragment(this);
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class DawnGryff extends CardImpl {
public DawnGryff(UUID ownerId) {
super(ownerId, 19, "Dawn Gryff", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.expansionSetCode = "EMN";
this.subtype.add("Hippogriff");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
}
public DawnGryff(final DawnGryff card) {
super(card);
}
@Override
public DawnGryff copy() {
return new DawnGryff(this);
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.token.Token;
import mage.players.Player;
/**
*
* @author fireshoes
*/
public class DocentOfPerfection extends CardImpl {
private static final FilterSpell filterSpell = new FilterSpell("instant or sorcery spell");
static {
filterSpell.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
}
public DocentOfPerfection(UUID ownerId) {
super(ownerId, 56, "Docent of Perfection", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.expansionSetCode = "EMN";
this.subtype.add("Insect");
this.subtype.add("Horror");
this.power = new MageInt(5);
this.toughness = new MageInt(4);
this.canTransform = true;
this.secondSideCard = new FinalIteration(ownerId);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast an instant or sorcery spell, put a 1/1 blue Human Wizard creature token onto the battlefield.
// Then if you control three or more Wizards, transform Docent of Perfection.
this.addAbility(new TransformAbility());
Effect effect = new DocentOfPerfectionEffect();
Ability ability = new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new HumanWizardToken()), filterSpell, false);
ability.addEffect(effect);
this.addAbility(ability);
}
public DocentOfPerfection(final DocentOfPerfection card) {
super(card);
}
@Override
public DocentOfPerfection copy() {
return new DocentOfPerfection(this);
}
}
class DocentOfPerfectionEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterPermanent("Wizards");
static {
filter.add(new SubtypePredicate("Wizards"));
filter.add(new ControllerPredicate(TargetController.YOU));
}
public DocentOfPerfectionEffect() {
super(Outcome.Benefit);
staticText = "Then if you control three or more Wizards, transform {this}";
}
public DocentOfPerfectionEffect(final DocentOfPerfectionEffect effect) {
super(effect);
}
@Override
public DocentOfPerfectionEffect copy() {
return new DocentOfPerfectionEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) >= 3) {
return new TransformSourceEffect(true).apply(game, source);
}
}
return false;
}
}
class HumanWizardToken extends Token {
public HumanWizardToken() {
super("Human Wizard", "1/1 blue Human Wizard creature token");
cardType.add(CardType.CREATURE);
subtype.add("Human");
subtype.add("Wizard");
color.setBlue(true);
power = new MageInt(1);
toughness = new MageInt(1);
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.CostModificationType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.turn.TurnMod;
import mage.players.Player;
import mage.target.common.TargetOpponent;
import mage.util.CardUtil;
/**
*
* @author emerald000
*/
public class EmrakulThePromisedEnd extends CardImpl {
private static final FilterCard filter = new FilterCard("instants");
static {
filter.add(new CardTypePredicate(CardType.INSTANT));
}
public EmrakulThePromisedEnd(UUID ownerId) {
super(ownerId, 6, "Emrakul, the Promised End", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{13}");
this.expansionSetCode = "EMN";
this.supertype.add("Legendary");
this.subtype.add("Eldrazi");
this.power = new MageInt(13);
this.toughness = new MageInt(13);
// Emrakul, the Promised End costs {1} less to cast for each card type among cards in your graveyard.
Ability ability = new SimpleStaticAbility(Zone.ALL, new EmrakulThePromisedEndCostReductionEffect());
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// When you cast Emrakul, you gain control of target opponent during that player's next turn. After that turn, that player takes an extra turn.
ability = new CastSourceTriggeredAbility(new EmrakulThePromisedEndGainControlEffect());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Protection from instants
this.addAbility(new ProtectionAbility(filter));
}
public EmrakulThePromisedEnd(final EmrakulThePromisedEnd card) {
super(card);
}
@Override
public EmrakulThePromisedEnd copy() {
return new EmrakulThePromisedEnd(this);
}
}
class EmrakulThePromisedEndCostReductionEffect extends CostModificationEffectImpl {
EmrakulThePromisedEndCostReductionEffect() {
super(Duration.WhileOnStack, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "{this} costs {1} less to cast for each card type among cards in your graveyard";
}
EmrakulThePromisedEndCostReductionEffect(EmrakulThePromisedEndCostReductionEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Set<CardType> foundCardTypes = new HashSet<>(8);
for (Card card : controller.getGraveyard().getCards(game)) {
foundCardTypes.addAll(card.getCardType());
}
CardUtil.reduceCost(abilityToModify, foundCardTypes.size());
return true;
}
return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify instanceof SpellAbility
&& abilityToModify.getSourceId().equals(source.getSourceId())
&& game.getCard(abilityToModify.getSourceId()) != null;
}
@Override
public EmrakulThePromisedEndCostReductionEffect copy() {
return new EmrakulThePromisedEndCostReductionEffect(this);
}
}
class EmrakulThePromisedEndGainControlEffect extends OneShotEffect {
EmrakulThePromisedEndGainControlEffect() {
super(Outcome.GainControl);
this.staticText = "you gain control of target opponent during that player's next turn. After that turn, that player takes an extra turn";
}
EmrakulThePromisedEndGainControlEffect(final EmrakulThePromisedEndGainControlEffect effect) {
super(effect);
}
@Override
public EmrakulThePromisedEndGainControlEffect copy() {
return new EmrakulThePromisedEndGainControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (controller != null && targetPlayer != null) {
game.getState().getTurnMods().add(new TurnMod(targetPlayer.getId(), false));
game.getState().getTurnMods().add(new TurnMod(targetPlayer.getId(), controller.getId()));
return true;
}
return false;
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.Filter;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author fireshoes
*/
public class EmrakulsInfluence extends CardImpl {
private static final FilterSpell filterSpell = new FilterSpell("Eldrazi creature spell with converted mana cost 7 or greater");
static {
filterSpell.add(new SubtypePredicate("Eldrazi"));
filterSpell.add(new ConvertedManaCostPredicate(Filter.ComparisonType.GreaterThan, 6));
}
public EmrakulsInfluence(UUID ownerId) {
super(ownerId, 157, "Emrakul's Influence", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
this.expansionSetCode = "EMN";
// Whenever you cast an Eldrazi creature spell with converted mana cost 7 or greater, draw two cards.
this.addAbility(new SpellCastControllerTriggeredAbility(new DrawCardSourceControllerEffect(2), filterSpell, false));
}
public EmrakulsInfluence(final EmrakulsInfluence card) {
super(card);
}
@Override
public EmrakulsInfluence copy() {
return new EmrakulsInfluence(this);
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
/**
*
* @author fireshoes
*/
public class FinalIteration extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wizards");
private static final FilterSpell filterSpell = new FilterSpell("instant or sorcery spell");
static {
filter.add(new SubtypePredicate("Wizard"));
filter.add(new ControllerPredicate(TargetController.YOU));
filterSpell.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
}
public FinalIteration(UUID ownerId) {
super(ownerId, 56, "Final Iteration", Rarity.RARE, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Insect");
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// this card is the second face of double-faced card
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Wizards you control get +2/+1 and have flying.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(2, 1, Duration.WhileOnBattlefield, filter, true));
Effect effect = new GainAbilityAllEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter, false);
effect.setText("and have flying");
ability.addEffect(effect);
this.addAbility(ability);
// Whenever you cast an instant or sorcery spell, put a 1/1 blue Human Wizard creature token onto the battlefield.
this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new HumanWizardToken()), filterSpell, false));
}
public FinalIteration(final FinalIteration card) {
super(card);
}
@Override
public FinalIteration copy() {
return new FinalIteration(this);
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class GalvanicBombardment extends CardImpl {
private static final FilterCard filter = new FilterCard("2 plus the number of cards named Galvanic Bombardment");
static {
filter.add(new NamePredicate("Galvanic Bombardment"));
}
public GalvanicBombardment(UUID ownerId) {
super(ownerId, 129, "Galvanic Bombardment", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}");
this.expansionSetCode = "EMN";
// Galvanic Bombardment deals X damage to target creature, where X is 2 plus the number of cards named Galvanic Bombardment in your graveyard.
Effect effect = new DamageTargetEffect(new GalvanicBombardmentCardsInControllerGraveyardCount(filter));
effect.setText("{this} deals X damage to target creature, where X is 2 plus the number of cards named {source} in your graveyard");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public GalvanicBombardment(final GalvanicBombardment card) {
super(card);
}
@Override
public GalvanicBombardment copy() {
return new GalvanicBombardment(this);
}
}
class GalvanicBombardmentCardsInControllerGraveyardCount implements DynamicValue {
private final FilterCard filter;
public GalvanicBombardmentCardsInControllerGraveyardCount(FilterCard filter) {
this.filter = filter;
}
private GalvanicBombardmentCardsInControllerGraveyardCount(GalvanicBombardmentCardsInControllerGraveyardCount dynamicValue) {
this.filter = dynamicValue.filter;
}
@Override
public int calculate(Game game, Ability source, Effect effect) {
int amount = 0;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
amount += controller.getGraveyard().count(filter, source.getSourceId(), source.getControllerId(), game);
}
return amount + 2;
}
@Override
public GalvanicBombardmentCardsInControllerGraveyardCount copy() {
return new GalvanicBombardmentCardsInControllerGraveyardCount(this);
}
@Override
public String toString() {
return "1";
}
@Override
public String getMessage() {
return filter.getMessage() + " in your graveyard";
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.DeliriumCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
* @author fireshoes
*/
public class GnarlwoodDryad extends CardImpl {
public GnarlwoodDryad(UUID ownerId) {
super(ownerId, 159, "Gnarlwood Dryad", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{G}");
this.expansionSetCode = "EMN";
this.subtype.add("Dryad");
this.subtype.add("Horror");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// <i>Delirium</i> &mdash Gnarlwood Dryad gets +2/+2 as long as there are four or more card types among cards in your graveyard.
ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), DeliriumCondition.getInstance(),
"<i>Delirium</i> &mdash; {this} gets +2/+2 as long as there are four or more card types among cards in your graveyard.");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
this.addAbility(ability);
}
public GnarlwoodDryad(final GnarlwoodDryad card) {
super(card);
}
@Override
public GnarlwoodDryad copy() {
return new GnarlwoodDryad(this);
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.RequirementEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author fireshoes
*/
public class GrislyAnglerfish extends CardImpl {
public GrislyAnglerfish(UUID ownerId) {
super(ownerId, 63, "Grisly Anglerfish", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Fish");
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// this card is the second face of double-faced card
this.nightCard = true;
// {6}: Creatures your opponents control attack this turn if able.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GrislyAnglerfishMustAttackEffect(), new ManaCostsImpl("{6}")));
}
public GrislyAnglerfish(final GrislyAnglerfish card) {
super(card);
}
@Override
public GrislyAnglerfish copy() {
return new GrislyAnglerfish(this);
}
}
class GrislyAnglerfishMustAttackEffect extends RequirementEffect {
public GrislyAnglerfishMustAttackEffect() {
super(Duration.EndOfTurn);
staticText = "Creatures your opponents control attack this turn if able";
}
public GrislyAnglerfishMustAttackEffect(final GrislyAnglerfishMustAttackEffect effect) {
super(effect);
}
@Override
public GrislyAnglerfishMustAttackEffect copy() {
return new GrislyAnglerfishMustAttackEffect(this);
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) {
return true;
}
return false;
}
@Override
public boolean mustAttack(Game game) {
return true;
}
@Override
public boolean mustBlock(Game game) {
return false;
}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author fireshoes
*/
public class GrizzledAngler extends CardImpl {
public GrizzledAngler(UUID ownerId) {
super(ownerId, 63, "Grizzled Angler", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.canTransform = true;
this.secondSideCard = new GrislyAnglerfish(ownerId);
// {T}: Put the top two cards of your library into your graveyard. Then if there is a colorless creature card in your graveyard, transform Grizzled Angler.
this.addAbility(new TransformAbility());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GrizzledAnglerEffect(), new TapSourceCost()));
}
public GrizzledAngler(final GrizzledAngler card) {
super(card);
}
@Override
public GrizzledAngler copy() {
return new GrizzledAngler(this);
}
}
class GrizzledAnglerEffect extends OneShotEffect {
private static final FilterCreatureCard filter = new FilterCreatureCard("a colorless creature card in your graveyard");
static {
filter.add(new ColorlessPredicate());
}
public GrizzledAnglerEffect() {
super(Outcome.Benefit);
staticText = "Put the top two cards of your library into your graveyard. Then if there is a colorless creature card in your graveyard, transform {this}";
}
public GrizzledAnglerEffect(final GrizzledAnglerEffect effect) {
super(effect);
}
@Override
public GrizzledAnglerEffect copy() {
return new GrizzledAnglerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.moveCards(controller.getLibrary().getTopCards(game, 2), Zone.GRAVEYARD, source, game);
if (controller.getGraveyard().count(filter, source.getSourceId(), source.getControllerId(), game) >= 1) {
return new TransformSourceEffect(true).apply(game, source);
}
}
return false;
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.game.permanent.token.Token;
/**
*
* @author fireshoes
*/
public class HanweirGarrison extends CardImpl {
public HanweirGarrison(UUID ownerId) {
super(ownerId, 130, "Hanweir Garrison", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever Hanweir Garrison attacks, put two 1/1 red Human creature tokens onto the battlefield tapped and attacking.
this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new RedHumanToken(), 2, true, true), false));
// <i>(Melds with Hanweir Battlements.)</i>
}
public HanweirGarrison(final HanweirGarrison card) {
super(card);
}
@Override
public HanweirGarrison copy() {
return new HanweirGarrison(this);
}
}
class RedHumanToken extends Token {
public RedHumanToken() {
super("Human", "1/1 red Human creature token");
this.cardType.add(CardType.CREATURE);
this.subtype.add("Human");
this.color = ObjectColor.RED;
this.power = new MageInt(1);
this.toughness = new MageInt(1);
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class ItThatRidesAsOne extends CardImpl {
public ItThatRidesAsOne(UUID ownerId) {
super(ownerId, 33, "It That Rides as One", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.subtype.add("Eldrazi");
this.subtype.add("Horror");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// this card is the second face of double-faced card
this.nightCard = true;
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
}
public ItThatRidesAsOne(final ItThatRidesAsOne card) {
super(card);
}
@Override
public ItThatRidesAsOne copy() {
return new ItThatRidesAsOne(this);
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.IntCompareCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.game.Game;
import mage.watchers.common.PlayerGainedLifeWatcher;
/**
*
* @author fireshoes
*/
public class LoneRider extends CardImpl {
public LoneRider(UUID ownerId) {
super(ownerId, 33, "Lone Rider", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.subtype.add("Knight");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
this.canTransform = true;
this.secondSideCard = new ItThatRidesAsOne(ownerId);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// At the beginning of the end step, if you gained 3 or more life this turn, transform Lone Rider.
this.addAbility(new TransformAbility());
TriggeredAbility ability = new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
this.addAbility(new ConditionalTriggeredAbility(ability, new YouGainedLifeCondition(Condition.ComparisonType.GreaterThan, 2),
"At the beginning of the end step, if you gained 3 or more life this turn, transform {this}"));
}
public LoneRider(final LoneRider card) {
super(card);
}
@Override
public LoneRider copy() {
return new LoneRider(this);
}
}
class YouGainedLifeCondition extends IntCompareCondition {
public YouGainedLifeCondition(Condition.ComparisonType type, int value) {
super(type, value);
}
@Override
protected int getInputValue(Game game, Ability source) {
int gainedLife = 0;
PlayerGainedLifeWatcher watcher = (PlayerGainedLifeWatcher) game.getState().getWatchers().get("PlayerGainedLifeWatcher");
if (watcher != null) {
gainedLife = watcher.getLiveGained(source.getControllerId());
}
return gainedLife;
}
@Override
public String toString() {
return "if you gained 3 or more life this turn ";
}
}

View file

@ -0,0 +1,200 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class LongRoadHome extends CardImpl {
public LongRoadHome(UUID ownerId) {
super(ownerId, 34, "Long Road Home", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.expansionSetCode = "EMN";
// Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it.
this.getSpellAbility().addEffect(new LongRoadHomeEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public LongRoadHome(final LongRoadHome card) {
super(card);
}
@Override
public LongRoadHome copy() {
return new LongRoadHome(this);
}
}
class LongRoadHomeEffect extends OneShotEffect {
private static final String effectText = "Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it";
LongRoadHomeEffect() {
super(Outcome.Benefit);
staticText = effectText;
}
LongRoadHomeEffect(LongRoadHomeEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
if (permanent.moveToExile(source.getSourceId(), "Otherworldly Journey", source.getSourceId(), game)) {
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
// only if permanent is in exile (tokens would be stop to exist)
if (exile != null && !exile.isEmpty()) {
Card card = game.getCard(permanent.getId());
if (card != null) {
//create delayed triggered ability
DelayedTriggeredAbility delayedAbility
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new LongRoadHomeReturnFromExileEffect(new MageObjectReference(card, game)));
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
}
}
return true;
}
}
return false;
}
@Override
public LongRoadHomeEffect copy() {
return new LongRoadHomeEffect(this);
}
}
class LongRoadHomeReturnFromExileEffect extends OneShotEffect {
MageObjectReference objectToReturn;
public LongRoadHomeReturnFromExileEffect(MageObjectReference objectToReturn) {
super(Outcome.PutCardInPlay);
this.objectToReturn = objectToReturn;
staticText = "return that card to the battlefield under its owner's control with a +1/+1 counter on it";
}
public LongRoadHomeReturnFromExileEffect(final LongRoadHomeReturnFromExileEffect effect) {
super(effect);
this.objectToReturn = effect.objectToReturn;
}
@Override
public LongRoadHomeReturnFromExileEffect copy() {
return new LongRoadHomeReturnFromExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(objectToReturn.getSourceId());
if (card != null && objectToReturn.refersTo(card, game)) {
Player owner = game.getPlayer(card.getOwnerId());
if (owner != null) {
game.addEffect(new LongRoadHomeEntersBattlefieldEffect(objectToReturn), source);
owner.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
}
}
return true;
}
}
class LongRoadHomeEntersBattlefieldEffect extends ReplacementEffectImpl {
MageObjectReference objectToReturn;
public LongRoadHomeEntersBattlefieldEffect(MageObjectReference objectToReturn) {
super(Duration.Custom, Outcome.BoostCreature);
this.objectToReturn = objectToReturn;
staticText = "that card returns to the battlefield with a +1/+1 counter on it";
}
public LongRoadHomeEntersBattlefieldEffect(LongRoadHomeEntersBattlefieldEffect effect) {
super(effect);
this.objectToReturn = effect.objectToReturn;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return EventType.ENTERS_THE_BATTLEFIELD.equals(event.getType());
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) {
return event.getTargetId().equals(objectToReturn.getSourceId());
}
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
if (permanent != null) {
permanent.addCounters(CounterType.P1P1.createInstance(), game);
discard(); // use only once
}
return false;
}
@Override
public LongRoadHomeEntersBattlefieldEffect copy() {
return new LongRoadHomeEntersBattlefieldEffect(this);
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.Filter;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.target.Target;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author fireshoes
*/
public class MidnightScavengers extends CardImpl {
private static final FilterCreatureCard filter = new FilterCreatureCard("creature card with converted mana cost 3 or less from your graveyard");
static {
filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, 4));
}
public MidnightScavengers(UUID ownerId) {
super(ownerId, 96, "Midnight Scavengers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.subtype.add("Rogue");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When Midnight Scavengers enters the battlefield, you may return target creature card with converted mana cost 3 or less from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), true);
Target target = new TargetCardInYourGraveyard(filter);
ability.addTarget(target);
this.addAbility(ability);
// <i>(Melds with Graf Rats.)</i>
}
public MidnightScavengers(final MidnightScavengers card) {
super(card);
}
@Override
public MidnightScavengers copy() {
return new MidnightScavengers(this);
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ProwessAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class NiblisOfFrost extends CardImpl {
private static final FilterSpell filterSpell = new FilterSpell("instant or sorcery spell");
private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature an opponent controls");
static {
filterCreature.add(new ControllerPredicate(TargetController.OPPONENT));
filterSpell.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
}
public NiblisOfFrost(UUID ownerId) {
super(ownerId, 72, "Niblis of Frost", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
this.expansionSetCode = "EMN";
this.subtype.add("Spirit");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Prowess
this.addAbility(new ProwessAbility());
// Whenever you cast an instant or sorcery spell, tap target creature an opponent controls. That creature doesn't untap during its controller's next untap step.
Ability ability = new SpellCastControllerTriggeredAbility(new TapTargetEffect(), filterSpell, false);
ability.addTarget(new TargetCreaturePermanent(filterCreature));
ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("That creature"));
this.addAbility(ability);
}
public NiblisOfFrost(final NiblisOfFrost card) {
super(card);
}
@Override
public NiblisOfFrost copy() {
return new NiblisOfFrost(this);
}
}

View file

@ -0,0 +1,107 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SpellCastAllTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.ZombieToken;
import mage.players.Player;
/**
*
* @author fireshoes
*/
public class NoosegrafMob extends CardImpl {
public NoosegrafMob(UUID ownerId) {
super(ownerId, 98, "Noosegraf Mob", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.expansionSetCode = "EMN";
this.subtype.add("Zombie");
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Noosegraf Mob enters the battlefield with five +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)),
"{this} enters the battlefield with five +1/+1 counters on it"));
// Whenever a player casts a spell, remove a +1/+1 counter from Noosegraf Mob. If you do, put a 2/2 black Zombie creature token onto the battlefield.
this.addAbility(new SpellCastAllTriggeredAbility(new NoosegrafMobEffect(), false));
}
public NoosegrafMob(final NoosegrafMob card) {
super(card);
}
@Override
public NoosegrafMob copy() {
return new NoosegrafMob(this);
}
}
class NoosegrafMobEffect extends OneShotEffect {
public NoosegrafMobEffect() {
super(Outcome.Benefit);
staticText = "remove a +1/+1 counter from Noosegraf Mob. If you do, put a 2/2 black Zombie creature token onto the battlefield";
}
public NoosegrafMobEffect(final NoosegrafMobEffect effect) {
super(effect);
}
@Override
public NoosegrafMobEffect copy() {
return new NoosegrafMobEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && permanent != null && permanent.getCounters().getCount(CounterType.P1P1) > 0) {
permanent.removeCounters(CounterType.P1P1.createInstance(), game);
Effect effect = new CreateTokenEffect(new ZombieToken());
return effect.apply(game, source);
}
return false;
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.permanent.token.SpiritWhiteToken;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author fireshoes
*/
public class SanctifierOfSouls extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("another creature");
static {
filter.add(new AnotherPredicate());
}
public SanctifierOfSouls(UUID ownerId) {
super(ownerId, 39, "Sanctifier of Souls", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.subtype.add("Cleric");
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever another creature enters the battlefield under your control, Sanctifier of Souls gets +1/+1 until end of turn.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), filter));
// {2}{W}, Exile a creature card from your graveyard: Put a 1/1 white Spirit creature token with flying onto the battlefield.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new CreateTokenEffect(new SpiritWhiteToken()),
new ManaCostsImpl("{2}{W}"));
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(new FilterCreatureCard("a creature card from your graveyard"))));
this.addAbility(ability);
}
public SanctifierOfSouls(final SanctifierOfSouls card) {
super(card);
}
@Override
public SanctifierOfSouls copy() {
return new SanctifierOfSouls(this);
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.NamePredicate;
/**
*
* @author fireshoes
*/
public class TakeInventory extends CardImpl {
private static final FilterCard filter = new FilterCard("card named Take Inventory");
static {
filter.add(new NamePredicate("Take Inventory"));
}
public TakeInventory(UUID ownerId) {
super(ownerId, 76, "Take Inventory", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{U}");
this.expansionSetCode = "EMN";
// Draw a card, then draw cards equal to the number of cards named Take Inventory in your graveyard.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
Effect effect = new DrawCardSourceControllerEffect(new CardsInControllerGraveyardCount(filter));
effect.setText(", then draw cards equal to the number of cards named {source} in your graveyard");
this.getSpellAbility().addEffect(effect);
}
public TakeInventory(final TakeInventory card) {
super(card);
}
@Override
public TakeInventory copy() {
return new TakeInventory(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class ThaliaHereticCathar extends mage.sets.mediainserts.ThaliaHereticCathar {
public ThaliaHereticCathar(UUID ownerId) {
super(ownerId);
this.cardNumber = 46;
this.expansionSetCode = "EMN";
}
public ThaliaHereticCathar(final ThaliaHereticCathar card) {
super(card);
}
@Override
public ThaliaHereticCathar copy() {
return new ThaliaHereticCathar(this);
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author fireshoes
*/
public class ThaliasLancers extends CardImpl {
private static final FilterCard filter = new FilterCard("legendary card");
static {
filter.add(new SupertypePredicate("Legendary"));
}
public ThaliasLancers(UUID ownerId) {
super(ownerId, 47, "Thalia's Lancers", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.expansionSetCode = "EMN";
this.subtype.add("Human");
this.subtype.add("Knight");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// When Thalia's Lancers enters the battlefield, you may search your library for a legendary card, reveal it, put it into your hand, then shuffle your library.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, filter), true, true), true));
}
public ThaliasLancers(final ThaliasLancers card) {
super(card);
}
@Override
public ThaliasLancers copy() {
return new ThaliasLancers(this);
}
}

View file

@ -0,0 +1,128 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class UlrichOfTheKrallenhorde extends CardImpl {
public UlrichOfTheKrallenhorde(UUID ownerId) {
super(ownerId, 191, "Ulrich of the Krallenhorde", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{R}{G}");
this.expansionSetCode = "EMN";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Werewolf");
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.canTransform = true;
this.secondSideCard = new UlrichUncontestedAlpha(ownerId);
// Whenever this creature enters the battlefield or transforms into Ulrich of the Krallenhorde, target creature gets +4/+4 until end of turn.
this.addAbility(new UlrichOfTheKrallenhordeAbility());
// At the beginning of each upkeep, if no spells were cast last turn, transform Ulrich of the Krallenhorde.
this.addAbility(new TransformAbility());
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.NO_SPELLS_TRANSFORM_RULE));
}
public UlrichOfTheKrallenhorde(final UlrichOfTheKrallenhorde card) {
super(card);
}
@Override
public UlrichOfTheKrallenhorde copy() {
return new UlrichOfTheKrallenhorde(this);
}
}
class UlrichOfTheKrallenhordeAbility extends TriggeredAbilityImpl {
public UlrichOfTheKrallenhordeAbility() {
super(Zone.BATTLEFIELD, new BoostTargetEffect(4, 4, Duration.EndOfTurn), false);
this.addTarget(new TargetCreaturePermanent());
}
public UlrichOfTheKrallenhordeAbility(final UlrichOfTheKrallenhordeAbility ability) {
super(ability);
}
@Override
public UlrichOfTheKrallenhordeAbility copy() {
return new UlrichOfTheKrallenhordeAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TRANSFORMED && event.getTargetId().equals(this.getSourceId())) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && !permanent.isTransformed()) {
return true;
}
}
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId())) {
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature enters the battlefield or transforms into Ulrich of the Krallenhorde, target creature gets +4/+4 until end of turn.";
}
}

View file

@ -0,0 +1,135 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.FightTargetSourceEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author fireshoes
*/
public class UlrichUncontestedAlpha extends CardImpl {
public UlrichUncontestedAlpha(UUID ownerId) {
super(ownerId, 191, "Ulrich, Uncontested Alpha", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "EMN";
this.supertype.add("Legendary");
this.subtype.add("Werewolf");
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// this card is the second face of double-faced card
this.nightCard = true;
this.canTransform = true;
// Whenever this creature transforms into Ulrich, Uncontested Alpha, you may have it fight target non-Werewolf creature you don't control.
this.addAbility(new UlrichUncontestedAlphaAbility());
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ulrich, Uncontested Alpha.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false);
this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
}
public UlrichUncontestedAlpha(final UlrichUncontestedAlpha card) {
super(card);
}
@Override
public UlrichUncontestedAlpha copy() {
return new UlrichUncontestedAlpha(this);
}
}
class UlrichUncontestedAlphaAbility extends TriggeredAbilityImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Werewolf creature you don't control");
static {
filter.add(Predicates.not(new SubtypePredicate("Werewolf")));
filter.add(new ControllerPredicate(TargetController.NOT_YOU));
}
public UlrichUncontestedAlphaAbility() {
super(Zone.BATTLEFIELD, new FightTargetSourceEffect(), true);
Target target = new TargetCreaturePermanent(filter);
this.addTarget(target);
}
public UlrichUncontestedAlphaAbility(final UlrichUncontestedAlphaAbility ability) {
super(ability);
}
@Override
public UlrichUncontestedAlphaAbility copy() {
return new UlrichUncontestedAlphaAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Ulrich, Uncontested Alpha, you may have it fight target non-Werewolf creature you don't control.";
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.Filter;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ToughnessPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
/**
*
* @author fireshoes
*/
public class UlvenwaldObserver extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control with toughness 4 or greater");
static {
filter.add(new ToughnessPredicate(Filter.ComparisonType.GreaterThan, 3));
filter.add(new ControllerPredicate(TargetController.YOU));
}
public UlvenwaldObserver(UUID ownerId) {
super(ownerId, 176, "Ulvenwald Observer", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{G}{G}");
this.expansionSetCode = "EMN";
this.subtype.add("Treefolk");
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Whenever a creature you control with toughness 4 or greater dies, draw a card.
this.addAbility(new DiesCreatureTriggeredAbility(new DrawCardSourceControllerEffect(1), false, filter));
}
public UlvenwaldObserver(final UlvenwaldObserver card) {
super(card);
}
@Override
public UlvenwaldObserver copy() {
return new UlvenwaldObserver(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.eldritchmoon;
import java.util.UUID;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterSpellOrPermanent;
import mage.target.common.TargetSpellOrPermanent;
/**
*
* @author fireshoes
*/
public class Unsubstantiate extends CardImpl {
private static final FilterSpellOrPermanent filter = new FilterSpellOrPermanent("spell or creature");
static {
filter.setPermanentFilter(new FilterCreaturePermanent());
}
public Unsubstantiate(UUID ownerId) {
super(ownerId, 79, "Unsubstantiate", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{U}");
this.expansionSetCode = "EMN";
// Return target spell or creature to its owner's hand.
this.getSpellAbility().addTarget(new TargetSpellOrPermanent(1, 1, filter, false));
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
}
public Unsubstantiate(final Unsubstantiate card) {
super(card);
}
@Override
public Unsubstantiate copy() {
return new Unsubstantiate(this);
}
}

View file

@ -58,7 +58,7 @@ public class IcatianJavelineers1 extends CardImpl {
this.toughness = new MageInt(1);
// Icatian Javelineers enters the battlefield with a javelin counter on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.JAVELIN.createInstance())));
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.JAVELIN.createInstance()), "with a javelin counter on it"));
// {tap}, Remove a javelin counter from Icatian Javelineers: Icatian Javelineers deals 1 damage to target creature or player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost());

View file

@ -27,6 +27,8 @@
*/
package mage.sets.fatereforged;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@ -35,6 +37,7 @@ import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.constants.CardType;
@ -48,7 +51,6 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetCreatureOrPlayer;
@ -123,9 +125,9 @@ class UginTheSpiritDragonEffect2 extends OneShotEffect {
FilterPermanent filter = new FilterPermanent("permanent with converted mana cost X or less that's one or more colors");
filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, cmc + 1));
filter.add(Predicates.not(new ColorlessPredicate()));
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true);
}
Set<Card> permanentsToExile = new HashSet<>();
permanentsToExile.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game));
controller.moveCards(permanentsToExile, Zone.EXILED, source, game);
return true;
}
}

View file

@ -51,7 +51,7 @@ public class WillOfTheNaga extends CardImpl {
// Tap up to two target creatures. Those creatures don't untap during their controller's next untap step.
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect());
this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures"));
}
public WillOfTheNaga(final WillOfTheNaga card) {

View file

@ -85,6 +85,7 @@ public class AngelicSkirmisher extends CardImpl {
}
class AngelicSkirmisherEffect extends OneShotEffect {
AngelicSkirmisherEffect() {
super(Outcome.AddAbility);
staticText = "choose first strike, vigilance or lifelink. Creatures you control gain that ability until end of turn";
@ -96,7 +97,6 @@ class AngelicSkirmisherEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null && sourcePermanent != null) {
@ -107,29 +107,32 @@ class AngelicSkirmisherEffect extends OneShotEffect {
abilityChoices.add("Vigilance");
abilityChoices.add("Lifelink");
abilityChoice.setChoices(abilityChoices);
Ability ability = null;
switch (abilityChoice.getChoice()) {
case "First strike":
ability = FirstStrikeAbility.getInstance();
break;
case "Vigilance":
ability = VigilanceAbility.getInstance();
break;
case "Lifelink":
ability = LifelinkAbility.getInstance();
break;
default:
break;
while (!controller.choose(outcome, abilityChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
if (ability != null) {
GainAbilityControlledEffect effect = new GainAbilityControlledEffect(ability, Duration.EndOfTurn, new FilterControlledCreaturePermanent());
game.addEffect(effect, source);
game.informPlayers(new StringBuilder(sourcePermanent.getName())
.append(": ")
.append(controller.getLogName())
.append(" has chosen ")
.append(abilityChoice.getChoice().toLowerCase()).toString());
return true;
Ability ability = null;
if (abilityChoice.getChoice() != null) {
switch (abilityChoice.getChoice()) {
case "First strike":
ability = FirstStrikeAbility.getInstance();
break;
case "Vigilance":
ability = VigilanceAbility.getInstance();
break;
case "Lifelink":
ability = LifelinkAbility.getInstance();
break;
default:
break;
}
if (ability != null) {
GainAbilityControlledEffect effect = new GainAbilityControlledEffect(ability, Duration.EndOfTurn, new FilterControlledCreaturePermanent());
game.addEffect(effect, source);
game.informPlayers(sourcePermanent.getName() + ": " + controller.getLogName() + " has chosen " + abilityChoice.getChoice().toLowerCase());
return true;
}
}
}
return false;
@ -139,4 +142,4 @@ class AngelicSkirmisherEffect extends OneShotEffect {
public AngelicSkirmisherEffect copy() {
return new AngelicSkirmisherEffect(this);
}
}
}

View file

@ -28,6 +28,7 @@
*/
package mage.sets.gatecrash;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
@ -45,8 +46,6 @@ import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author Plopman
@ -65,7 +64,10 @@ public class PrimeSpeakerZegana extends CardImpl {
this.toughness = new MageInt(1);
//Prime Speaker Zegana enters the battlefield with X +1/+1 counters on it, where X is the greatest power among other creatures you control.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new greatestPowerCount(), true), "where X is the greatest power among other creatures you control"));
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(0),
new greatestPowerCount(), true),
"where X is the greatest power among other creatures you control"));
//When Prime Speaker Zegana enters the battlefield, draw cards equal to its power.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(new SourcePermanentPowerCount())));
}

View file

@ -0,0 +1,72 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.guildpact;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.watchers.common.ManaSpentToCastWatcher;
/**
*
* @author Styxo
*/
public class GruulScrapper extends CardImpl {
public GruulScrapper(UUID ownerId) {
super(ownerId, 89, "Gruul Scrapper", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.expansionSetCode = "GPT";
this.subtype.add("Human");
this.subtype.add("Berserker");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
//When Gruul Scrapper enters the battlefield, if Red was spent to cast Gruul Scrapper, it gains haste until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConditionalContinuousEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), new ManaWasSpentCondition(ColoredManaSymbol.R), " if {R} was spent to cast {this}, it gains haste until end of turn")), new ManaSpentToCastWatcher());
}
public GruulScrapper(final GruulScrapper card) {
super(card);
}
@Override
public GruulScrapper copy() {
return new GruulScrapper(this);
}
}

View file

@ -58,7 +58,6 @@ public class CurseOfThePiercedHeart extends CardImpl {
this.subtype.add("Aura");
this.subtype.add("Curse");
// Enchant player
TargetPlayer target = new TargetPlayer();
this.getSpellAbility().addTarget(target);
@ -97,7 +96,7 @@ class CurseOfThePiercedHeartAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DRAW_STEP_PRE;
return event.getType() == EventType.UPKEEP_STEP_PRE;
}
@Override
@ -118,4 +117,4 @@ class CurseOfThePiercedHeartAbility extends TriggeredAbilityImpl {
return "At the beginning of enchanted player's upkeep, Curse of the Pierced Heart deals 1 damage to that player.";
}
}
}

View file

@ -28,13 +28,13 @@
package mage.sets.innistrad;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
@ -44,7 +44,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
*/
public class HamletCaptain extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Human creatures");
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Humans");
static {
filter.add(new SubtypePredicate("Human"));

View file

@ -29,19 +29,17 @@ package mage.sets.judgment;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.NameACardEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TimingRule;
import mage.abilities.Ability;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.players.Player;
@ -59,12 +57,13 @@ public class CabalTherapy extends CardImpl {
this.expansionSetCode = "JUD";
// Name a nonland card. Target player reveals his or her hand and discards all cards with that name.
this.getSpellAbility().addEffect((new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME)));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new CabalTherapyEffect());
// Flashback-Sacrifice a creature.
this.addAbility(new FlashbackAbility(
new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,new FilterControlledCreaturePermanent("a creature"), true)),
new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature"), true)),
TimingRule.SORCERY));
}
@ -95,25 +94,12 @@ class CabalTherapyEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (targetPlayer != null && controller != null && sourceObject != null) {
Choice cardChoice = new ChoiceImpl(true);
cardChoice.setMessage("Name a nonland card.");
cardChoice.setChoices(CardRepository.instance.getNonLandNames());
cardChoice.clearChoice();
while (!controller.choose(Outcome.Discard, cardChoice, game)) {
if (!controller.canRespond()) {
return false;
}
}
String cardName = cardChoice.getChoice();
game.informPlayers(sourceObject.getLogName() + ", named card: [" + cardName + "]");
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY);
for (Card card : targetPlayer.getHand().getCards(game)) {
if (card.getName().equals(cardName)) {
targetPlayer.discard(card, source, game);
}
}
controller.lookAtCards(sourceObject.getName() + " Hand", targetPlayer.getHand(), game);
}
return true;

View file

@ -56,8 +56,9 @@ import mage.target.common.TargetControlledCreaturePermanent;
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class PrismaticStrands extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped white creature you control");
static {
filter.add(Predicates.not(new TappedPredicate()));
filter.add(new ColorPredicate(ObjectColor.WHITE));
@ -69,9 +70,9 @@ public class PrismaticStrands extends CardImpl {
// Prevent all damage that sources of the color of your choice would deal this turn.
this.getSpellAbility().addEffect(new PrismaticStrandsEffect());
// Flashback-Tap an untapped white creature you control.
this.addAbility(new FlashbackAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1,1,filter,false)), TimingRule.INSTANT));
this.addAbility(new FlashbackAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false)), TimingRule.INSTANT));
}
public PrismaticStrands(final PrismaticStrands card) {
@ -85,36 +86,42 @@ public class PrismaticStrands extends CardImpl {
}
class PrismaticStrandsEffect extends OneShotEffect {
PrismaticStrandsEffect() {
super(Outcome.PreventDamage);
this.staticText = "Prevent all damage that sources of the color of your choice would deal this turn";
}
PrismaticStrandsEffect(final PrismaticStrandsEffect effect) {
super(effect);
}
@Override
public PrismaticStrandsEffect copy() {
return new PrismaticStrandsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
ChoiceColor choice = new ChoiceColor();
controller.choose(Outcome.PreventDamage, choice, game);
game.addEffect(new PrismaticStrandsPreventionEffect(choice.getColor()), source);
return true;
if (choice.isChosen()) {
if (!game.isSimulation()) {
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " has chosen sources of the color " + choice.getChoice());
}
game.addEffect(new PrismaticStrandsPreventionEffect(choice.getColor()), source);
return true;
}
}
return false;
}
}
class PrismaticStrandsPreventionEffect extends PreventionEffectImpl {
private final ObjectColor color;
PrismaticStrandsPreventionEffect(ObjectColor color) {
@ -135,8 +142,8 @@ class PrismaticStrandsPreventionEffect extends PreventionEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (super.applies(event, source, game)) {
if (event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER)
|| event.getType().equals(GameEvent.EventType.DAMAGE_CREATURE)
if (event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER)
|| event.getType().equals(GameEvent.EventType.DAMAGE_CREATURE)
|| event.getType().equals(GameEvent.EventType.DAMAGE_PLANESWALKER)) {
MageObject sourceObject = game.getObject(event.getSourceId());
if (sourceObject != null && sourceObject.getColor(game).shares(this.color)) {

View file

@ -86,7 +86,7 @@ class CallerOfTheClawWatcher extends Watcher {
private int creaturesCount = 0;
public CallerOfTheClawWatcher() {
super("YourCreaturesDied", WatcherScope.PLAYER);
super(CallerOfTheClawWatcher.class.getName(), WatcherScope.PLAYER);
condition = true;
}
@ -107,7 +107,7 @@ class CallerOfTheClawWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) {
Permanent card = (Permanent)game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
Permanent card = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (card != null && card.getOwnerId().equals(this.controllerId) && card.getCardType().contains(CardType.CREATURE) && !(card instanceof PermanentToken)) {
creaturesCount++;
}
@ -123,7 +123,6 @@ class CallerOfTheClawWatcher extends Watcher {
class CallerOfTheClawDynamicValue implements DynamicValue {
@Override
public CallerOfTheClawDynamicValue copy() {
return new CallerOfTheClawDynamicValue();
@ -141,7 +140,7 @@ class CallerOfTheClawDynamicValue implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
CallerOfTheClawWatcher watcher = (CallerOfTheClawWatcher) game.getState().getWatchers().get("YourCreaturesDied", sourceAbility.getControllerId());
CallerOfTheClawWatcher watcher = (CallerOfTheClawWatcher) game.getState().getWatchers().get(CallerOfTheClawWatcher.class.getName(), sourceAbility.getControllerId());
if (watcher != null) {
return watcher.getCreaturesCount();
}

Some files were not shown because too many files have changed in this diff Show more