mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Merge branch 'master' into aether-web
This commit is contained in:
commit
d7af252d8b
670 changed files with 4770 additions and 1947 deletions
|
@ -1083,10 +1083,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
private void chooseMatching() {
|
||||
Collection<CardView> toMatch = dragCardList();
|
||||
|
||||
|
||||
for (DragCardGridListener l : listeners) {
|
||||
for (CardView card : allCards) {
|
||||
for (CardView aMatch : toMatch) {
|
||||
|
@ -1337,6 +1337,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
public void analyseDeck() {
|
||||
HashMap<String, Integer> qtys = new HashMap<>();
|
||||
HashMap<String, Integer> pips = new HashMap<>();
|
||||
HashMap<String, Integer> pips_at_cmcs = new HashMap<>();
|
||||
HashMap<String, Integer> sourcePips = new HashMap<>();
|
||||
HashMap<String, Integer> manaCounts = new HashMap<>();
|
||||
pips.put("#w}", 0);
|
||||
|
@ -1396,11 +1397,40 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
}
|
||||
mc = mc.replaceAll("\\{([WUBRG]).([WUBRG])\\}", "{$1}{$2}");
|
||||
mc = mc.replaceAll("\\{", "#");
|
||||
mc = mc.replaceAll("#2\\/", "#");
|
||||
mc = mc.replaceAll("p}", "}");
|
||||
mc = mc.toLowerCase(Locale.ENGLISH);
|
||||
int cmc = card.getConvertedManaCost();
|
||||
|
||||
// Do colorless mana pips
|
||||
Pattern regex = Pattern.compile("#([0-9]+)}");
|
||||
Matcher regexMatcher = regex.matcher(mc);
|
||||
while (regexMatcher.find()) {
|
||||
String val = regexMatcher.group(1);
|
||||
int colorless_val = Integer.parseInt(val);
|
||||
|
||||
int total_c_pip = 0;
|
||||
if (pips.get("#c}") != null) {
|
||||
total_c_pip = pips.get("#c}");
|
||||
}
|
||||
pips.put("#c}", colorless_val + total_c_pip);
|
||||
|
||||
int cmc_pip_value = 0;
|
||||
if (pips_at_cmcs.get(cmc + "##c}") != null) {
|
||||
cmc_pip_value = pips_at_cmcs.get(cmc + "##c}");
|
||||
}
|
||||
pips_at_cmcs.put(cmc + "##c}", colorless_val + cmc_pip_value);
|
||||
}
|
||||
|
||||
for (String pip : pips.keySet()) {
|
||||
int value = pips.get(pip);
|
||||
while (mc.toLowerCase(Locale.ENGLISH).contains(pip)) {
|
||||
pips.put(pip, ++value);
|
||||
int pip_value = 0;
|
||||
if (pips_at_cmcs.get(cmc + "#" + pip) != null) {
|
||||
pip_value = pips_at_cmcs.get(cmc + "#" + pip);
|
||||
}
|
||||
pips_at_cmcs.put(cmc + "#" + pip, ++pip_value);
|
||||
mc = mc.replaceFirst(pip, "");
|
||||
}
|
||||
}
|
||||
|
@ -1448,9 +1478,17 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
panel4.add(new JLabel("Mana sources found:"));
|
||||
panel4.add(chart3);
|
||||
|
||||
JPanel panel5 = new JPanel();
|
||||
panel5.setLayout(new BoxLayout(panel5, BoxLayout.Y_AXIS));
|
||||
ManaBarChart chart4 = new ManaBarChart(pips_at_cmcs);
|
||||
chart4.setMinimumSize(new Dimension(200, 200));
|
||||
panel5.add(new JLabel("Mana distribution:"));
|
||||
panel5.add(chart4);
|
||||
|
||||
panel.add(panel2);
|
||||
panel.add(panel3);
|
||||
panel.add(panel4);
|
||||
panel.add(panel5);
|
||||
|
||||
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
|
||||
JOptionPane.showMessageDialog(frame, panel, "This is the distribution of colors found", JOptionPane.INFORMATION_MESSAGE);
|
||||
|
@ -1719,7 +1757,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
|||
JMenuItem invertSelection = new JMenuItem("Invert Selection");
|
||||
invertSelection.addActionListener(e2 -> invertSelection());
|
||||
menu.add(invertSelection);
|
||||
|
||||
|
||||
JMenuItem chooseMatching = new JMenuItem("Choose Matching");
|
||||
chooseMatching.addActionListener(e2 -> chooseMatching());
|
||||
menu.add(chooseMatching);
|
||||
|
|
151
Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java
Normal file
151
Mage.Client/src/main/java/mage/client/cards/ManaBarChart.java
Normal file
|
@ -0,0 +1,151 @@
|
|||
package mage.client.cards;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
public class ManaBarChart extends JComponent {
|
||||
|
||||
HashMap<String, Integer> pips_at_cmcs = new HashMap<String, Integer>();
|
||||
|
||||
ManaBarChart() {
|
||||
}
|
||||
|
||||
ManaBarChart(HashMap<String, Integer> pips_at_cmcs) {
|
||||
this.pips_at_cmcs = pips_at_cmcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension preferred = super.getPreferredSize();
|
||||
Dimension minimum = getMinimumSize();
|
||||
Dimension maximum = getMaximumSize();
|
||||
preferred.width = Math.min(Math.max(preferred.width, minimum.width), maximum.width);
|
||||
preferred.height = Math.min(Math.max(preferred.height, minimum.height), maximum.height);
|
||||
return preferred;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
drawBar((Graphics2D) g, getBounds());
|
||||
}
|
||||
|
||||
void drawBar(Graphics2D g, Rectangle area) {
|
||||
Pattern regex = Pattern.compile("^([0-9]+)##(.)}");
|
||||
HashMap<Integer, Integer> totals_at_cmcs = new HashMap<Integer, Integer>();
|
||||
int max_num_pips = 0;
|
||||
int max_cmc = 0;
|
||||
|
||||
for (String key : pips_at_cmcs.keySet()) {
|
||||
Matcher regexMatcher = regex.matcher(key);
|
||||
int num_pips = pips_at_cmcs.get(key);
|
||||
while (regexMatcher.find()) {
|
||||
String cmc = regexMatcher.group(1);
|
||||
int cmc_num = Integer.parseInt(cmc);
|
||||
if (max_cmc < cmc_num) {
|
||||
max_cmc = cmc_num;
|
||||
}
|
||||
|
||||
int total_at_cmc = 0;
|
||||
if (totals_at_cmcs.get(cmc_num) != null) {
|
||||
total_at_cmc = totals_at_cmcs.get(cmc_num);
|
||||
}
|
||||
totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips);
|
||||
if (max_num_pips < total_at_cmc + num_pips) {
|
||||
max_num_pips = total_at_cmc + num_pips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (max_num_pips <= 0) {
|
||||
max_num_pips = 1;
|
||||
}
|
||||
int height_factor = 200 / max_num_pips;
|
||||
int width_factor = 200 / (max_cmc + 2);
|
||||
if (width_factor > 20) {
|
||||
width_factor = 20;
|
||||
}
|
||||
if (width_factor < 11) {
|
||||
width_factor = 11;
|
||||
}
|
||||
|
||||
g.setColor(new Color(130, 130, 130));
|
||||
for (int i = 0; i < max_num_pips; i++) {
|
||||
if (max_num_pips > 10) {
|
||||
if (i % 10 == 0) {
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
} else if (i % 10 == 5) {
|
||||
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0);
|
||||
Stroke oldstroke = g.getStroke();
|
||||
g.setStroke(dashed);
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
g.setStroke(oldstroke);
|
||||
}
|
||||
} else if (i % 2 == 0) {
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
} else if (i % 2 == 1) {
|
||||
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{5}, 0);
|
||||
Stroke oldstroke = g.getStroke();
|
||||
g.setStroke(dashed);
|
||||
g.drawLine(0, 200 - 1 - i * height_factor, 400, 200 - 1 - i * height_factor);
|
||||
g.setStroke(oldstroke);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 17; i++) {
|
||||
if (i % 5 == 0) {
|
||||
g.drawLine(width_factor * i, 200, width_factor * i, 190);
|
||||
} else {
|
||||
g.drawLine(width_factor * i, 200, width_factor * i, 195);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HashMap<Integer, Integer> running_totals_at_cmcs = new HashMap<Integer, Integer>();
|
||||
for (String key : pips_at_cmcs.keySet()) {
|
||||
Matcher regexMatcher = regex.matcher(key);
|
||||
int num_pips = pips_at_cmcs.get(key);
|
||||
while (regexMatcher.find()) {
|
||||
String cmc = regexMatcher.group(1);
|
||||
int cmc_num = Integer.parseInt(cmc);
|
||||
String color = regexMatcher.group(2);
|
||||
|
||||
int total_at_cmc = 0;
|
||||
if (running_totals_at_cmcs.get(cmc_num) != null) {
|
||||
total_at_cmc = running_totals_at_cmcs.get(cmc_num);
|
||||
}
|
||||
|
||||
if (color.equalsIgnoreCase("w")) {
|
||||
g.setColor(Color.WHITE);
|
||||
}
|
||||
if (color.equalsIgnoreCase("u")) {
|
||||
g.setColor(Color.BLUE);
|
||||
}
|
||||
if (color.equalsIgnoreCase("b")) {
|
||||
g.setColor(Color.BLACK);
|
||||
}
|
||||
if (color.equalsIgnoreCase("r")) {
|
||||
g.setColor(Color.RED);
|
||||
}
|
||||
if (color.equalsIgnoreCase("g")) {
|
||||
g.setColor(Color.GREEN);
|
||||
}
|
||||
if (color.equalsIgnoreCase("c")) {
|
||||
g.setColor(Color.DARK_GRAY);
|
||||
}
|
||||
g.fill(new Rectangle2D.Double(cmc_num * width_factor, 200 - 1 - total_at_cmc - num_pips * height_factor, 10, num_pips * height_factor));
|
||||
running_totals_at_cmcs.put(cmc_num, total_at_cmc + num_pips * height_factor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -158,6 +158,7 @@ public class DownloadGui extends JPanel {
|
|||
b.addActionListener(e -> {
|
||||
switch(this.job.getState()) {
|
||||
case NEW:
|
||||
case PREPARING:
|
||||
case WORKING:
|
||||
this.job.setState(State.ABORTED);
|
||||
}
|
||||
|
|
|
@ -23,16 +23,16 @@ import org.mage.plugins.card.utils.CardImageUtils;
|
|||
* The class DownloadJob.
|
||||
*
|
||||
* @version V0.0 25.08.2010
|
||||
* @author Clemens Koza
|
||||
* @author Clemens Koza, JayDi85
|
||||
*/
|
||||
public class DownloadJob extends AbstractLaternaBean {
|
||||
|
||||
public enum State {
|
||||
NEW, WORKING, FINISHED, ABORTED
|
||||
NEW, PREPARING, WORKING, FINISHED, ABORTED
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final Source source;
|
||||
private Source source;
|
||||
private final Destination destination;
|
||||
private final Property<State> state = properties.property("state", State.NEW);
|
||||
private final Property<String> message = properties.property("message");
|
||||
|
@ -98,6 +98,36 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
this.message.setValue(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner prepare cycle from new to working
|
||||
*/
|
||||
public void doPrepareAndStartWork() {
|
||||
if (this.state.getValue() != State.NEW) {
|
||||
setError("Can't call prepare at this point.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.state.setValue(State.PREPARING);
|
||||
|
||||
try {
|
||||
onPreparing();
|
||||
} catch (Exception e) {
|
||||
setError("Prepare error: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
// change to working state on good prepare call
|
||||
this.state.setValue(State.WORKING);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare code to override in custom download tasks (it's calls before work start)
|
||||
*/
|
||||
public void onPreparing() throws Exception {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the job's message.
|
||||
*
|
||||
|
@ -131,6 +161,10 @@ public class DownloadJob extends AbstractLaternaBean {
|
|||
return source;
|
||||
}
|
||||
|
||||
public void setSource(Source source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public Destination getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
for (DownloadJob j : jobs) {
|
||||
switch (j.getState()) {
|
||||
case NEW:
|
||||
case PREPARING:
|
||||
case WORKING:
|
||||
j.setState(State.ABORTED);
|
||||
}
|
||||
|
@ -82,8 +83,11 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
}
|
||||
|
||||
public void add(DownloadJob job) {
|
||||
if (job.getState() == State.PREPARING) {
|
||||
throw new IllegalArgumentException("Job already preparing");
|
||||
}
|
||||
if (job.getState() == State.WORKING) {
|
||||
throw new IllegalArgumentException("Job already running");
|
||||
throw new IllegalArgumentException("Job already working");
|
||||
}
|
||||
if (job.getState() == State.FINISHED) {
|
||||
throw new IllegalArgumentException("Job already finished");
|
||||
|
@ -106,13 +110,22 @@ public class Downloader extends AbstractLaternaBean implements Disposable {
|
|||
|
||||
@Override
|
||||
public void onMessage(DownloadJob job) {
|
||||
//the job won't be processed by multiple threads
|
||||
|
||||
// start to work
|
||||
// the job won't be processed by multiple threads
|
||||
synchronized (job) {
|
||||
if (job.getState() != State.NEW) {
|
||||
return;
|
||||
}
|
||||
job.setState(State.WORKING);
|
||||
|
||||
job.doPrepareAndStartWork();
|
||||
|
||||
if (job.getState() != State.WORKING) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// download and save data
|
||||
try {
|
||||
Source src = job.getSource();
|
||||
Destination dst = job.getDestination();
|
||||
|
|
|
@ -9,8 +9,13 @@ import java.util.*;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import mage.MageException;
|
||||
import mage.util.StreamUtils;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.mage.plugins.card.dl.DownloadJob;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
import javax.swing.text.Document;
|
||||
|
||||
import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG;
|
||||
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
||||
|
@ -18,14 +23,14 @@ import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
|
|||
// TODO: add force to download symbols (rewrite exist files)
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jaydi85@gmail.com
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
||||
|
||||
|
||||
static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // search css-file on https://scryfall.com/docs/api/colors
|
||||
//static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // old version with direct css-file on https://scryfall.com/docs/api/colors
|
||||
static final String CSS_SOURCE_URL = "https://scryfall.com/docs/api/colors";
|
||||
static final String CSS_SOURCE_SELECTOR = "link[rel=stylesheet]"; // <link rel="stylesheet" media="all" href="https://assets.scryfall.com/assets/scryfall-8cdaa786c4c86d5c49317e3e0fed72a0e409666753d3d3e8c906f33a188e19ed.css">
|
||||
static final String STATE_PROP_NAME = "state";
|
||||
static final String DOWNLOAD_TEMP_FILE = getImagesDir() + File.separator + "temp" + File.separator + "scryfall-symbols-source.txt";
|
||||
|
||||
|
@ -55,21 +60,21 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
return jobs.iterator();
|
||||
}
|
||||
|
||||
private void parseData(String sourcePath){
|
||||
private void parseData(String sourcePath) {
|
||||
|
||||
String sourceData = "";
|
||||
try {
|
||||
sourceData = new String(Files.readAllBytes(Paths.get(sourcePath)));
|
||||
}catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Can't open file to parse data: " + sourcePath + " , reason: " + e.getMessage());
|
||||
}
|
||||
|
||||
// gen symbols list
|
||||
ArrayList<String> allMageSymbols = new ArrayList<>();
|
||||
for(int i = 0; i < SYMBOLS_LIST.length; i++){
|
||||
for (int i = 0; i < SYMBOLS_LIST.length; i++) {
|
||||
allMageSymbols.add(SYMBOLS_LIST[i]);
|
||||
}
|
||||
for(Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++){
|
||||
for (Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++) {
|
||||
allMageSymbols.add(String.valueOf(SYMBOLS_NUMBER_START + i));
|
||||
}
|
||||
|
||||
|
@ -88,23 +93,22 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
|
||||
// dirs maker
|
||||
File dir = getSymbolFileNameAsSVG("W").getParentFile();
|
||||
if(!dir.exists()){
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// decode and save data (only if not exist)
|
||||
for(String needCode: allMageSymbols){
|
||||
for (String needCode : allMageSymbols) {
|
||||
|
||||
String searchCode = needCode.replace("/", "");
|
||||
|
||||
if(!foundedData.containsKey(searchCode))
|
||||
{
|
||||
if (!foundedData.containsKey(searchCode)) {
|
||||
LOGGER.warn("Can't found symbol code from scryfall: " + searchCode);
|
||||
continue;
|
||||
}
|
||||
|
||||
File destFile = getSymbolFileNameAsSVG(searchCode);
|
||||
if (destFile.exists() && (destFile.length() > 0)){
|
||||
if (destFile.exists() && (destFile.length() > 0)) {
|
||||
continue;
|
||||
}
|
||||
FileOutputStream stream = null;
|
||||
|
@ -118,7 +122,7 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
stream.write(fileData);
|
||||
|
||||
LOGGER.info("New svg symbol downloaded: " + needCode);
|
||||
} catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage());
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(stream);
|
||||
|
@ -127,23 +131,26 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
}
|
||||
|
||||
|
||||
private class ScryfallSymbolsDownloadJob extends DownloadJob{
|
||||
private class ScryfallSymbolsDownloadJob extends DownloadJob {
|
||||
|
||||
private String cssUrl = ""; // need to find url from colors page https://scryfall.com/docs/api/colors
|
||||
|
||||
// listener for data parse after download complete
|
||||
private class ScryDownloadOnFinishedListener implements PropertyChangeListener {
|
||||
private class ScryfallDownloadOnFinishedListener implements PropertyChangeListener {
|
||||
private String downloadedFile;
|
||||
|
||||
public ScryDownloadOnFinishedListener(String ADestFile){
|
||||
public ScryfallDownloadOnFinishedListener(String ADestFile) {
|
||||
this.downloadedFile = ADestFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (!evt.getPropertyName().equals(STATE_PROP_NAME)){
|
||||
|
||||
if (!evt.getPropertyName().equals(STATE_PROP_NAME)) {
|
||||
throw new IllegalArgumentException("Unknown download property " + evt.getPropertyName());
|
||||
}
|
||||
|
||||
if (evt.getNewValue() != State.FINISHED){
|
||||
if (evt.getNewValue() != State.FINISHED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -152,16 +159,34 @@ public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreparing() throws Exception {
|
||||
this.cssUrl = "";
|
||||
|
||||
org.jsoup.nodes.Document doc = CardImageUtils.downloadHtmlDocument(CSS_SOURCE_URL);
|
||||
org.jsoup.select.Elements cssList = doc.select(CSS_SOURCE_SELECTOR);
|
||||
if (cssList.size() == 1) {
|
||||
this.cssUrl = cssList.first().attr("href").toString();
|
||||
}
|
||||
|
||||
if (this.cssUrl.isEmpty()) {
|
||||
throw new IllegalStateException("Can't find stylesheet url from scryfall colors page.");
|
||||
} else {
|
||||
this.setSource(fromURL(this.cssUrl));
|
||||
}
|
||||
}
|
||||
|
||||
private String destFile = "";
|
||||
|
||||
public ScryfallSymbolsDownloadJob() {
|
||||
super("Scryfall symbols source", fromURL(SOURCE_URL), toFile(DOWNLOAD_TEMP_FILE));
|
||||
// download init
|
||||
super("Scryfall symbols source", fromURL(""), toFile(DOWNLOAD_TEMP_FILE)); // url setup on preparing stage
|
||||
this.destFile = DOWNLOAD_TEMP_FILE;
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryDownloadOnFinishedListener(this.destFile));
|
||||
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryfallDownloadOnFinishedListener(this.destFile));
|
||||
|
||||
// clear dest file (always download new data)
|
||||
File file = new File(this.destFile);
|
||||
if (file.exists()){
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.jsoup.nodes.Document;
|
|||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
import org.mage.plugins.card.utils.CardImageUtils;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
|
@ -535,7 +536,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
while (page < 999) {
|
||||
String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?sort=cn+&page=" + page + "&action=advanced&output=spoiler&method=visual&set=+%5B%22" + URLSetName + "%22%5D";
|
||||
logger.debug("URL: " + searchUrl);
|
||||
Document doc = getDocument(searchUrl);
|
||||
Document doc = CardImageUtils.downloadHtmlDocument(searchUrl);
|
||||
Elements cardsImages = doc.select("img[src^=../../Handlers/]");
|
||||
if (cardsImages.isEmpty()) {
|
||||
break;
|
||||
|
@ -587,33 +588,6 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
return setLinks;
|
||||
}
|
||||
|
||||
private Document getDocument(String urlString) throws NumberFormatException, IOException {
|
||||
Preferences prefs = MageFrame.getPreferences();
|
||||
Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None"));
|
||||
Document doc;
|
||||
if (proxyType == ProxyType.NONE) {
|
||||
doc = Jsoup.connect(urlString).timeout(60 * 1000).get();
|
||||
} else {
|
||||
String proxyServer = prefs.get("proxyAddress", "");
|
||||
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
|
||||
URL url = new URL(urlString);
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
|
||||
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
|
||||
uc.setConnectTimeout(10000);
|
||||
uc.setReadTimeout(60000);
|
||||
uc.connect();
|
||||
|
||||
String line;
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
|
||||
while ((line = in.readLine()) != null) {
|
||||
tmp.append(line);
|
||||
}
|
||||
doc = Jsoup.parse(String.valueOf(tmp));
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
private void getLandVariations(LinkedHashMap<String, String> setLinks, String cardSet, int multiverseId, String cardName) throws IOException, NumberFormatException {
|
||||
CardCriteria criteria = new CardCriteria();
|
||||
criteria.nameExact(cardName);
|
||||
|
@ -621,7 +595,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
List<CardInfo> cards = CardRepository.instance.findCards(criteria);
|
||||
|
||||
String urlLandDocument = "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=" + multiverseId;
|
||||
Document landDoc = getDocument(urlLandDocument);
|
||||
Document landDoc = CardImageUtils.downloadHtmlDocument(urlLandDocument);
|
||||
Elements variations = landDoc.select("a.variationlink");
|
||||
if (!variations.isEmpty()) {
|
||||
if (variations.size() > cards.size()) {
|
||||
|
@ -668,7 +642,7 @@ public enum WizardCardsImageSource implements CardImageSource {
|
|||
|
||||
private HashMap<String, Integer> getlocalizedMultiverseIds(Integer englishMultiverseId) throws IOException {
|
||||
String cardLanguagesUrl = "http://gatherer.wizards.com/Pages/Card/Languages.aspx?multiverseid=" + englishMultiverseId;
|
||||
Document cardLanguagesDoc = getDocument(cardLanguagesUrl);
|
||||
Document cardLanguagesDoc = CardImageUtils.downloadHtmlDocument(cardLanguagesUrl);
|
||||
Elements languageTableRows = cardLanguagesDoc.select("tr.cardItem");
|
||||
HashMap<String, Integer> localizedIds = new HashMap<>();
|
||||
if (!languageTableRows.isEmpty()) {
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package org.mage.plugins.card.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.constants.Constants;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
|
@ -13,6 +19,8 @@ import mage.remote.Connection;
|
|||
import mage.remote.Connection.ProxyType;
|
||||
import net.java.truevfs.access.TFile;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.mage.plugins.card.images.CardDownloadData;
|
||||
import org.mage.plugins.card.properties.SettingsManager;
|
||||
|
||||
|
@ -22,7 +30,6 @@ public final class CardImageUtils {
|
|||
private static final Logger log = Logger.getLogger(CardImageUtils.class);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param card
|
||||
* @return String if image exists, else null
|
||||
*/
|
||||
|
@ -54,7 +61,6 @@ public final class CardImageUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param card
|
||||
* @return String regardless of whether image exists
|
||||
*/
|
||||
|
@ -280,4 +286,31 @@ public final class CardImageUtils {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Document downloadHtmlDocument(String urlString) throws NumberFormatException, IOException {
|
||||
Preferences prefs = MageFrame.getPreferences();
|
||||
Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None"));
|
||||
Document doc;
|
||||
if (proxyType == ProxyType.NONE) {
|
||||
doc = Jsoup.connect(urlString).timeout(60 * 1000).get();
|
||||
} else {
|
||||
String proxyServer = prefs.get("proxyAddress", "");
|
||||
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
|
||||
URL url = new URL(urlString);
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
|
||||
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
|
||||
uc.setConnectTimeout(10000);
|
||||
uc.setReadTimeout(60000);
|
||||
uc.connect();
|
||||
|
||||
String line;
|
||||
StringBuffer tmp = new StringBuffer();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
|
||||
while ((line = in.readLine()) != null) {
|
||||
tmp.append(line);
|
||||
}
|
||||
doc = Jsoup.parse(String.valueOf(tmp));
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,8 @@ package mage.deck;
|
|||
import java.util.*;
|
||||
import mage.abilities.common.CanBeYourCommanderAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.constants.SetType;
|
||||
import mage.filter.FilterMana;
|
||||
|
||||
/**
|
||||
|
@ -22,50 +19,11 @@ public class Brawl extends Constructed {
|
|||
super("Brawl");
|
||||
|
||||
// Copy of standard sets
|
||||
GregorianCalendar current = new GregorianCalendar();
|
||||
List<ExpansionSet> sets = new ArrayList(Sets.getInstance().values());
|
||||
Collections.sort(sets, new Comparator<ExpansionSet>() {
|
||||
@Override
|
||||
public int compare(final ExpansionSet lhs, ExpansionSet rhs) {
|
||||
return lhs.getReleaseDate().after(rhs.getReleaseDate()) ? -1 : 1;
|
||||
}
|
||||
});
|
||||
int fallSetsAdded = 0;
|
||||
Date earliestDate = null;
|
||||
// Get the second most recent fall set that's been released.
|
||||
for (ExpansionSet set : sets) {
|
||||
if (set.getReleaseDate().after(current.getTime())) {
|
||||
continue;
|
||||
}
|
||||
if (isFallSet(set)) {
|
||||
fallSetsAdded++;
|
||||
if (fallSetsAdded == 2) {
|
||||
earliestDate = set.getReleaseDate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get all sets released on or after the second most recent fall set's release
|
||||
for (ExpansionSet set : sets) {
|
||||
if ((set.getSetType() == SetType.CORE
|
||||
|| set.getSetType() == SetType.EXPANSION
|
||||
|| set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL)
|
||||
&& (!set.getReleaseDate().before(earliestDate)
|
||||
&& !set.getReleaseDate().after(current.getTime()))) {
|
||||
setCodes.add(set.getCode());
|
||||
}
|
||||
}
|
||||
setCodes.addAll(Standard.makeLegalSets());
|
||||
|
||||
banned.add("Baral, Chief of Compliance");
|
||||
banned.add("Smuggler's Copter");
|
||||
banned.add("Sorcerers' Spyglass");
|
||||
}
|
||||
|
||||
private static boolean isFallSet(ExpansionSet set) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(set.getReleaseDate());
|
||||
// Fall sets are normally released during or after September
|
||||
return set.getSetType() == SetType.EXPANSION
|
||||
&& (cal.get(Calendar.MONTH) > 7);
|
||||
banned.add("Sorcerous Spyglass");
|
||||
}
|
||||
|
||||
public Brawl(String name) {
|
||||
|
|
|
@ -20,6 +20,28 @@ public class Standard extends Constructed {
|
|||
|
||||
public Standard() {
|
||||
super("Constructed - Standard");
|
||||
|
||||
setCodes.addAll(makeLegalSets());
|
||||
|
||||
banned.add("Attune with Aether"); // since 2018-01-15
|
||||
banned.add("Aetherworks Marvel");
|
||||
banned.add("Felidar Guardian");
|
||||
banned.add("Rampaging Ferocidon"); // since 2018-01-15
|
||||
banned.add("Ramunap Ruins"); // since 2018-01-15
|
||||
banned.add("Rogue Refiner"); // since 2018-01-15
|
||||
banned.add("Smuggler's Copter");
|
||||
}
|
||||
|
||||
private static boolean isFallSet(ExpansionSet set) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(set.getReleaseDate());
|
||||
// Fall sets are normally released during or after September
|
||||
return set.getSetType() == SetType.EXPANSION
|
||||
&& (cal.get(Calendar.MONTH) > 7);
|
||||
}
|
||||
|
||||
public static List<String> makeLegalSets() {
|
||||
List<String> codes = new ArrayList();
|
||||
GregorianCalendar current = new GregorianCalendar();
|
||||
List<ExpansionSet> sets = new ArrayList(Sets.getInstance().values());
|
||||
Collections.sort(sets, new Comparator<ExpansionSet>() {
|
||||
|
@ -50,23 +72,9 @@ public class Standard extends Constructed {
|
|||
|| set.getSetType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL)
|
||||
&& !set.getReleaseDate().before(earliestDate)) {
|
||||
// && !set.getReleaseDate().after(current.getTime()))) {
|
||||
setCodes.add(set.getCode());
|
||||
codes.add(set.getCode());
|
||||
}
|
||||
}
|
||||
banned.add("Attune with Aether"); // since 2018-01-15
|
||||
banned.add("Aetherworks Marvel");
|
||||
banned.add("Felidar Guardian");
|
||||
banned.add("Rampaging Ferocidon"); // since 2018-01-15
|
||||
banned.add("Ramunap Ruins"); // since 2018-01-15
|
||||
banned.add("Rogue Refiner"); // since 2018-01-15
|
||||
banned.add("Smuggler's Copter");
|
||||
}
|
||||
|
||||
private static boolean isFallSet(ExpansionSet set) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(set.getReleaseDate());
|
||||
// Fall sets are normally released during or after September
|
||||
return set.getSetType() == SetType.EXPANSION
|
||||
&& (cal.get(Calendar.MONTH) > 7);
|
||||
return codes;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ public class BrawlDuelMatch extends MatchImpl {
|
|||
|
||||
@Override
|
||||
public void startGame() throws GameException {
|
||||
int startLife = 20;
|
||||
int startLife = 25;
|
||||
boolean alsoHand = true;
|
||||
BrawlDuel game = new BrawlDuel(options.getAttackOption(), options.getRange(), options.getFreeMulligans(), startLife);
|
||||
game.setCheckCommanderDamage(false);
|
||||
|
|
|
@ -341,8 +341,18 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
replacementEffectChoice.getChoices().clear();
|
||||
replacementEffectChoice.setKeyChoices(rEffects);
|
||||
|
||||
// Check if there are different ones
|
||||
int differentChoices = 0;
|
||||
String lastChoice = "";
|
||||
for (String value : replacementEffectChoice.getKeyChoices().values()) {
|
||||
if (!lastChoice.equalsIgnoreCase(value)) {
|
||||
lastChoice = value;
|
||||
differentChoices++;
|
||||
}
|
||||
}
|
||||
|
||||
while (!abort) {
|
||||
while (!abort && differentChoices > 1) {
|
||||
updateGameStatePriority("chooseEffect", game);
|
||||
prepareForResponse(game);
|
||||
if (!isExecutingMacro()) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.server.game;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -1149,7 +1148,7 @@ public class GameController implements GameCallback {
|
|||
sb.append(state.getTurnMods());
|
||||
sb.append("<br>getTurnNum: ");
|
||||
sb.append(state.getTurnNum());
|
||||
|
||||
|
||||
sb.append("<br>Using plane chase?:" + state.isPlaneChase());
|
||||
if (state.isPlaneChase()) {
|
||||
Plane currentPlane = state.getCurrentPlane();
|
||||
|
@ -1157,7 +1156,7 @@ public class GameController implements GameCallback {
|
|||
sb.append("<br>Current plane:" + currentPlane.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sb.append("<br>Future Timeout:");
|
||||
if (futureTimeout != null) {
|
||||
sb.append("Cancelled?=");
|
||||
|
@ -1188,8 +1187,13 @@ public class GameController implements GameCallback {
|
|||
|
||||
sb.append("<br>Active player is: ");
|
||||
sb.append(game.getPlayer(state.getActivePlayerId()).getName());
|
||||
|
||||
PassAbility pass = new PassAbility();
|
||||
if (game.getPlayer(state.getActivePlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getActivePlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null) {
|
||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||
|
@ -1204,6 +1208,10 @@ public class GameController implements GameCallback {
|
|||
sb.append("<br>getChoosingPlayerId: ");
|
||||
if (state.getChoosingPlayerId() != null) {
|
||||
if (game.getPlayer(state.getChoosingPlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getChoosingPlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null && !fixedAlready) {
|
||||
currentPhase.getStep().endStep(game, state.getActivePlayerId());
|
||||
|
@ -1218,7 +1226,11 @@ public class GameController implements GameCallback {
|
|||
|
||||
sb.append("<br><font color=orange>Player with Priority is: ");
|
||||
if (state.getPriorityPlayerId() != null) {
|
||||
if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) {
|
||||
if (game.getPlayer(state.getPriorityPlayerId()).hasLeft()) {
|
||||
Player p = game.getPlayer(state.getPriorityPlayerId());
|
||||
if (p != null) {
|
||||
p.concede(game);
|
||||
}
|
||||
Phase currentPhase = game.getPhase();
|
||||
if (currentPhase != null && !fixedAlready) {
|
||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||
|
@ -1228,7 +1240,7 @@ public class GameController implements GameCallback {
|
|||
}
|
||||
sb.append(game.getPlayer(state.getPriorityPlayerId()).getName());
|
||||
sb.append("</font>");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append("<br>Future Timeout:");
|
||||
if (futureTimeout != null) {
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.ControlsCreatureGreatestToughnessCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -27,7 +27,7 @@ public final class AbzanBeastmaster extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false),
|
||||
ControlsCreatureGreatestToughnessCondition.instance,
|
||||
"At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness."
|
||||
|
|
50
Mage.Sets/src/mage/cards/a/AetherflameWall.java
Normal file
50
Mage.Sets/src/mage/cards/a/AetherflameWall.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CanBlockAsThoughtItHadShadowEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.keyword.DefenderAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public final class AetherflameWall extends CardImpl {
|
||||
|
||||
public AetherflameWall(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
|
||||
|
||||
this.subtype.add(SubType.WALL);
|
||||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(4);
|
||||
|
||||
// Defender
|
||||
this.addAbility(DefenderAbility.getInstance());
|
||||
|
||||
// Aetherflame Wall can block creatures with shadow as though they didn’t have shadow.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanBlockAsThoughtItHadShadowEffect(Duration.WhileOnBattlefield)));
|
||||
|
||||
// {R}: Aetherflame Wall gets +1/+0 until end of turn.
|
||||
this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")));
|
||||
}
|
||||
|
||||
public AetherflameWall(final AetherflameWall card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AetherflameWall copy() {
|
||||
return new AetherflameWall(this);
|
||||
}
|
||||
}
|
98
Mage.Sets/src/mage/cards/a/Aetherplasm.java
Normal file
98
Mage.Sets/src/mage/cards/a/Aetherplasm.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BlocksTriggeredAbility;
|
||||
import mage.abilities.costs.common.ReturnToHandFromBattlefieldSourceCost;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public final class Aetherplasm extends CardImpl {
|
||||
|
||||
public Aetherplasm(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");
|
||||
|
||||
this.subtype.add(SubType.ILLUSION);
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// Whenever Aetherplasm blocks a creature, you may return Aetherplasm to its owner's hand. If you do, you may put a creature card from your hand onto the battlefield blocking that creature.
|
||||
this.addAbility(new BlocksTriggeredAbility
|
||||
(new DoIfCostPaid(new AetherplasmEffect(), new ReturnToHandFromBattlefieldSourceCost()), false, true));
|
||||
}
|
||||
|
||||
public Aetherplasm(final Aetherplasm card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Aetherplasm copy() {
|
||||
return new Aetherplasm(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AetherplasmEffect extends OneShotEffect {
|
||||
|
||||
public AetherplasmEffect() {
|
||||
super(Outcome.PutCardInPlay);
|
||||
this.staticText = "you may put a creature card from your hand onto the battlefield blocking that creature";
|
||||
}
|
||||
|
||||
public AetherplasmEffect(AetherplasmEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Permanent blockedCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.chooseUse(Outcome.PutCardInPlay, "Put a creature card from your hand onto the battlefield?", source, game)) {
|
||||
TargetCardInHand target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A);
|
||||
if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
if(player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null)
|
||||
&& game.getCombat() != null && blockedCreature != null){
|
||||
CombatGroup attacker = game.getCombat().findGroup(blockedCreature.getId());
|
||||
Permanent putIntoPlay = game.getPermanent(target.getFirstTarget());
|
||||
if (putIntoPlay != null && putIntoPlay.isCreature() &&attacker != null) {
|
||||
game.getCombat().findGroup(blockedCreature.getId()).addBlocker(putIntoPlay.getId(), source.getControllerId(), game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AetherplasmEffect copy() {
|
||||
return new AetherplasmEffect(this);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -36,7 +36,7 @@ public final class AfflictedDeserter extends CardImpl {
|
|||
// At the beginning of each upkeep, if no spells were cast last turn, transform Afflicted Deserter.
|
||||
this.addAbility(new TransformAbility());
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
}
|
||||
|
||||
public AfflictedDeserter(final AfflictedDeserter card) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
|
||||
import mage.abilities.condition.common.RevoltCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
|
@ -33,7 +33,7 @@ public final class AidFromTheCowl extends CardImpl {
|
|||
// <i>Revolt</i> — At the beginning of your end step, if a permanent you controlled left the battlefield this turn,
|
||||
// reveal the top card of your library. If it is a permanent card, you may put it onto the battlefield. Otherwise, put it on the bottom of your library.
|
||||
TriggeredAbility ability = new BeginningOfYourEndStepTriggeredAbility(new AidFromTheCowlEffect(), false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, RevoltCondition.instance, ruleText), new RevoltWatcher());
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, RevoltCondition.instance, ruleText), new RevoltWatcher());
|
||||
}
|
||||
|
||||
public AidFromTheCowl(final AidFromTheCowl card) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.RevoltCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -34,7 +34,7 @@ public final class AirdropAeronauts extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// <i>Revolt</i> — When Airdrop Aeronauts enters the battlefield, if a permanent you controlled left the battlefield this turn, you gain 5 life.
|
||||
Ability ability = new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new GainLifeEffect(5), false), RevoltCondition.instance,
|
||||
"<i>Revolt</i> — When {this} enters the battlefield, if a permanent you controlled left"
|
||||
+ " the battlefield this turn, you gain 5 life."
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -43,7 +43,7 @@ public final class AjanisComrade extends CardImpl {
|
|||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// At the beginning of combat on your turn, if you control an Ajani planeswalker, put a +1/+1 counter on Ajani's Comrade.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false),
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"At the beginning of combat on your turn, if you control an Ajani planeswalker, put a +1/+1 counter on {this}."));
|
||||
|
|
|
@ -5,7 +5,7 @@ import mage.abilities.TriggeredAbilityImpl;
|
|||
import mage.abilities.common.DiscardedByOpponentTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -39,7 +39,7 @@ public final class AjanisLastStand extends CardImpl {
|
|||
this.addAbility(new AjanisLastStandTriggeredAbility());
|
||||
|
||||
// When a spell or ability an opponent controls causes you to discard this card, if you control a Plains, create a 4/4 white Avatar creature token with flying.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new DiscardedByOpponentTriggeredAbility(new CreateTokenEffect(new AvatarToken2())),
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"When a spell or ability an opponent controls causes you to discard this card, "
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.MoreCardsInHandThanOpponentsCondition;
|
||||
import mage.abilities.costs.common.SacrificeTargetCost;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
|
@ -40,7 +40,7 @@ public final class AkutaBornOfAsh extends CardImpl {
|
|||
// Haste
|
||||
this.addAbility(HasteAbility.getInstance());
|
||||
// At the beginning of your upkeep, if you have more cards in hand than each opponent, you may sacrifice a Swamp. If you do, return Akuta, Born of Ash from your graveyard to the battlefield.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD,
|
||||
new DoIfCostPaid(new ReturnSourceFromGraveyardToBattlefieldEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filterSwamp))),
|
||||
TargetController.YOU, false),
|
||||
|
|
|
@ -111,7 +111,7 @@ class AlhammarretsArchiveReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getPlayerId().equals(source.getControllerId())) {
|
||||
if (game.getActivePlayerId().equals(event.getPlayerId())
|
||||
if (game.isActivePlayer(event.getPlayerId())
|
||||
&& game.getPhase().getStep().getType() == PhaseStep.DRAW) {
|
||||
CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName());
|
||||
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.KickedCostCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.discard.DiscardTargetEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
|
@ -51,12 +51,12 @@ public final class AnaBattlemage extends CardImpl {
|
|||
// When Ana Battlemage enters the battlefield, if it was kicked with its {2}{U} kicker, target player discards three cards.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(3));
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new KickedCostCondition("{2}{U}"),
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new KickedCostCondition("{2}{U}"),
|
||||
"When {this} enters the battlefield, if it was kicked with its {2}{U} kicker, target player discards three cards."));
|
||||
// When Ana Battlemage enters the battlefield, if it was kicked with its {1}{B} kicker, tap target untapped creature and that creature deals damage equal to its power to its controller.
|
||||
ability = new EntersBattlefieldTriggeredAbility(new AnaBattlemageKickerEffect());
|
||||
ability.addTarget(new TargetCreaturePermanent(filter));
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new KickedCostCondition("{1}{B}"),
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new KickedCostCondition("{1}{B}"),
|
||||
"When {this} enters the battlefield, if it was kicked with its {1}{B} kicker, tap target untapped creature and that creature deals damage equal to its power to its controller."));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package mage.cards.a;
|
|||
import java.util.UUID;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SanctuaryTriggeredAbility;
|
||||
import mage.abilities.common.SanctuaryInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
|
@ -27,7 +27,7 @@ public final class AnaSanctuary extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
|
||||
|
||||
// At the beginning of your upkeep, if you control a blue or black permanent, target creature gets +1/+1 until end of turn. If you control a blue permanent and a black permanent, that creature gets +5/+5 until end of turn instead.
|
||||
Ability ability = new SanctuaryTriggeredAbility(
|
||||
Ability ability = new SanctuaryInterveningIfTriggeredAbility(
|
||||
new BoostEffect(1), new BoostEffect(5), ObjectColor.BLACK, ObjectColor.BLUE,
|
||||
"At the beginning of your upkeep, if you control a blue or black permanent, "
|
||||
+ "target creature gets +1/+1 until end of turn. If you control a blue permanent and a black permanent, that creature gets +5/+5 until end of turn instead."
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.condition.common.DeliriumCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
@ -46,7 +46,7 @@ public final class AngelOfDeliverance extends CardImpl {
|
|||
|
||||
// <i>Delirium</i> — Whenever Angel of Deliverance deals damage, if there are four or more card types among cards in your graveyard,
|
||||
// exile target creature an opponent controls.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new AngelOfDeliveranceDealsDamageTriggeredAbility(),
|
||||
DeliriumCondition.instance,
|
||||
"<i>Delirium</i> — Whenever {this} deals damage, if there are four or more card types among cards in your graveyard, exile target creature an opponent controls"
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.CastFromHandSourceCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.ExileAllEffect;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
|
@ -34,7 +34,7 @@ public final class AngelOfTheDireHour extends CardImpl {
|
|||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
// When Angel of the Dire Hour enters the battlefield, if you cast it from your hand, exile all attacking creatures.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new ExileAllEffect(new FilterAttackingCreature("attacking creatures")), false),
|
||||
CastFromHandSourceCondition.instance,
|
||||
"When {this} enters the battlefield, if you cast it from your hand, exile all attacking creatures."),
|
||||
|
|
|
@ -65,7 +65,7 @@ class AngelicArbiterCantAttackTargetEffect extends RestrictionEffect {
|
|||
|
||||
@Override
|
||||
public boolean applies(Permanent permanent, Ability source, Game game) {
|
||||
if (game.getActivePlayerId().equals(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) {
|
||||
if (game.isActivePlayer(permanent.getControllerId()) && game.getOpponents(source.getControllerId()).contains(permanent.getControllerId())) {
|
||||
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
|
||||
if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(permanent.getControllerId()) > 0) {
|
||||
return true;
|
||||
|
@ -113,7 +113,7 @@ class AngelicArbiterEffect2 extends ContinuousRuleModifyingEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
|
||||
if (game.isActivePlayer(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
|
||||
PlayerAttackedWatcher watcher = (PlayerAttackedWatcher) game.getState().getWatchers().get(PlayerAttackedWatcher.class.getSimpleName());
|
||||
if (watcher != null && watcher.getNumberOfAttackersCurrentTurn(event.getPlayerId()) > 0) {
|
||||
return true;
|
||||
|
|
|
@ -62,7 +62,7 @@ class AngelicBenedictionTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (game.getActivePlayerId().equals(this.controllerId)) {
|
||||
if (game.isActivePlayer(this.controllerId)) {
|
||||
if (game.getCombat().attacksAlone()) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
|||
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceOnBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||
|
@ -47,7 +47,7 @@ public final class AnimateDead extends CardImpl {
|
|||
// When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard"
|
||||
// and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield
|
||||
// under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new AnimateDeadReAttachEffect(), false),
|
||||
SourceOnBattlefieldCondition.instance,
|
||||
"When {this} enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with {this}.\" Return enchanted creature card to the battlefield under your control and attach {this} to it.");
|
||||
|
|
|
@ -5,7 +5,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -42,7 +42,7 @@ public final class ApothecaryGeist extends CardImpl {
|
|||
|
||||
// When Apothecary Geist enters the battlefield, if you control another Spirit, you gain 3 life.
|
||||
TriggeredAbility triggeredAbility = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3));
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
triggeredAbility,
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"When {this} enters the battlefield, if you control another Spirit, you gain 3 life."));
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
|
|||
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
|
||||
import mage.abilities.condition.common.SourceOnBattlefieldOrCommandZoneCondition;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
|
@ -56,7 +56,7 @@ public final class ArahboRoarOfTheWorld extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
// Eminence — At the beginning of combat on your turn, if Arahbo, Roar of the World is in the command zone or on the battlefield, another target Cat you control gets +3/+3 until end of turn.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfCombatTriggeredAbility(Zone.ALL, new BoostTargetEffect(3, 3, Duration.EndOfTurn), TargetController.YOU, false, false),
|
||||
SourceOnBattlefieldOrCommandZoneCondition.instance,
|
||||
"<i>Eminence</i> — At the beginning of combat on your turn, if Arahbo, Roar of the World is in the command zone or on the battlefield, another target Cat you control gets +3/+3 until end of turn.");
|
||||
|
|
|
@ -133,7 +133,7 @@ class ArchonOfValorsReachChoice extends ChoiceImpl {
|
|||
return CardType.INSTANT;
|
||||
case "Sorcery":
|
||||
return CardType.SORCERY;
|
||||
case "Planewswalker":
|
||||
case "Planeswalker":
|
||||
return CardType.PLANESWALKER;
|
||||
default:
|
||||
return null;
|
||||
|
|
|
@ -8,7 +8,7 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.condition.common.FatefulHourCondition;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
|
@ -40,7 +40,7 @@ public final class ArguelsBloodFast extends CardImpl {
|
|||
|
||||
// At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.
|
||||
this.addAbility(new TransformAbility());
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, true),
|
||||
FatefulHourCondition.instance,
|
||||
"At the beginning of your upkeep, if you have 5 or less life, you may transform {this}"
|
||||
|
|
|
@ -74,7 +74,7 @@ class AbilityActivatedTriggeredAbility extends TriggeredAbilityImpl {
|
|||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent aura = game.getPermanent(this.getSourceId());
|
||||
return aura != null && aura.getAttachedTo() != null && aura.getAttachedTo().equals(event.getSourceId());
|
||||
return aura != null && aura.isAttachedTo(event.getSourceId());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.common.BecomesBlockedTriggeredAbility;
|
||||
import mage.abilities.condition.common.HateCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.BlockedCreatureCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
|
||||
|
@ -45,7 +45,7 @@ public final class AsajjVentress extends CardImpl {
|
|||
this.addAbility(new BecomesBlockedTriggeredAbility(effect, false));
|
||||
|
||||
// <i>Hate</i> — Whenever Asajj Ventress attacks, if an opponent lost life from a source other than combat damage this turn, target creature blocks this turn if able.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new AttacksTriggeredAbility(new BlocksIfAbleTargetEffect(Duration.EndOfTurn), false),
|
||||
HateCondition.instance,
|
||||
"<i>Hate</i> — Whenever Asajj Ventress attacks, if an opponent lost life from a source other than combat damage this turn, target creature blocks this turn if able");
|
||||
|
|
|
@ -61,8 +61,8 @@ enum AshenGhoulCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (!game.getStep().getType().equals(PhaseStep.UPKEEP)
|
||||
|| !game.getActivePlayerId().equals(source.getControllerId())) {
|
||||
if (game.getStep().getType() != PhaseStep.UPKEEP
|
||||
|| !game.isActivePlayer(source.getControllerId())) {
|
||||
return false;
|
||||
}
|
||||
if (controller != null) {
|
||||
|
|
|
@ -95,8 +95,8 @@ public final class AssaultSuit extends CardImpl {
|
|||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.SACRIFICE_PERMANENT) {
|
||||
Permanent equipment = game.getPermanent(source.getSourceId());
|
||||
if (equipment != null && equipment.getAttachedTo() != null) {
|
||||
return equipment.getAttachedTo().equals(event.getTargetId());
|
||||
if (equipment != null) {
|
||||
return equipment.isAttachedTo(event.getTargetId());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.CardsInHandCondition;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
||||
|
@ -33,7 +33,7 @@ public final class AsylumVisitor extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.
|
||||
Ability ability = new ConditionalTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.ANY, false),
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.ANY, false),
|
||||
new CardsInHandCondition(ComparisonType.EQUAL_TO, 0, null, TargetController.ACTIVE),
|
||||
"At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.");
|
||||
Effect effect = new LoseLifeSourceControllerEffect(1);
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TapTargetEffect;
|
||||
import mage.constants.SubType;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -37,7 +37,7 @@ public final class AuroraChampion extends CardImpl {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// Whenever Aurora Champion attacks, if your team controls another Warrior, tap target creature.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new AttacksTriggeredAbility(new TapTargetEffect(), false),
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"Whenever {this} attacks, if your team controls another Warrior, tap target creature."
|
||||
|
|
|
@ -123,7 +123,7 @@ class AzorTheLawbringerCantCastEffect extends ContinuousRuleModifyingEffectImpl
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
UUID opponentId = getTargetPointer().getFirst(game, source);
|
||||
if (game.getActivePlayerId().equals(opponentId)) {
|
||||
if (game.isActivePlayer(opponentId)) {
|
||||
if (playersNextTurn == 0) {
|
||||
playersNextTurn = game.getTurnNum();
|
||||
}
|
||||
|
|
89
Mage.Sets/src/mage/cards/b/BalduvianFallen.java
Normal file
89
Mage.Sets/src/mage/cards/b/BalduvianFallen.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.keyword.CumulativeUpkeepAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ManaEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author noahg
|
||||
*/
|
||||
public final class BalduvianFallen extends CardImpl {
|
||||
|
||||
public BalduvianFallen(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
|
||||
|
||||
this.subtype.add(SubType.ZOMBIE);
|
||||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
// Cumulative upkeep {1}
|
||||
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl("{1}")));
|
||||
|
||||
// Whenever Balduvian Fallen's cumulative upkeep is paid, it gets +1/+0 until end of turn for each {B} or {R} spent this way.
|
||||
this.addAbility(new BalduvianFallenAbility());
|
||||
}
|
||||
|
||||
public BalduvianFallen(final BalduvianFallen card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BalduvianFallen copy() {
|
||||
return new BalduvianFallen(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BalduvianFallenAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public BalduvianFallenAbility() {
|
||||
super(Zone.BATTLEFIELD, null, false);
|
||||
}
|
||||
|
||||
public BalduvianFallenAbility(final BalduvianFallenAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BalduvianFallenAbility copy() {
|
||||
return new BalduvianFallenAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.PAID_CUMULATIVE_UPKEEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
this.getEffects().clear();
|
||||
if(event.getSourceId() != null && event.getSourceId().equals(this.getSourceId()) && event instanceof ManaEvent) {
|
||||
ManaEvent manaEvent = (ManaEvent) event;
|
||||
int total = manaEvent.getMana().getBlack() + manaEvent.getMana().getRed();
|
||||
if (total > 0) {
|
||||
this.getEffects().add(new BoostSourceEffect(total, 0, Duration.EndOfTurn));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this}'s cumulative upkeep is paid, it gets +1/+0 until end of turn for each {B} or {R} spent this way";
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.AttacksEachCombatStaticAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -38,7 +38,7 @@ public final class BaneOfHanweir extends CardImpl {
|
|||
|
||||
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Bane of Hanweir.
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.instance, TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.instance, TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
|
||||
}
|
||||
|
||||
public BaneOfHanweir(final BaneOfHanweir card) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
|||
import mage.abilities.condition.CompoundCondition;
|
||||
import mage.abilities.condition.common.CardsInHandCondition;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -31,7 +31,7 @@ public final class BarrenGlory extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}{W}");
|
||||
|
||||
// At the beginning of your upkeep, if you control no permanents other than Barren Glory and have no cards in hand, you win the game.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect(), TargetController.YOU, false),
|
||||
new CompoundCondition(
|
||||
new CardsInHandCondition(ComparisonType.EQUAL_TO, 0),
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -27,7 +27,7 @@ public final class BattleOfWits extends CardImpl {
|
|||
|
||||
// At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game.
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new WinGameSourceControllerEffect(), TargetController.YOU, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new BattleOfWitsCondition(), "At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game."));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new BattleOfWitsCondition(), "At the beginning of your upkeep, if you have 200 or more cards in your library, you win the game."));
|
||||
}
|
||||
|
||||
public BattleOfWits(final BattleOfWits card) {
|
||||
|
|
|
@ -77,7 +77,7 @@ class BattlegraceAngelAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (game.getActivePlayerId().equals(this.controllerId) ) {
|
||||
if (game.isActivePlayer(this.controllerId) ) {
|
||||
if (game.getCombat().attacksAlone()) {
|
||||
for (Effect effect: this.getEffects()) {
|
||||
effect.setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0)));
|
||||
|
|
|
@ -5,7 +5,7 @@ import mage.MageInt;
|
|||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.InvertCondition;
|
||||
import mage.abilities.condition.common.RaidCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -29,7 +29,7 @@ public final class BellowingSaddlebrute extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
// Raid - When Bellowing Saddlebrute enters the battlefield, you lose 4 life unless you attacked with a creature this turn
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new LoseLifeSourceControllerEffect(4)),
|
||||
new InvertCondition(RaidCondition.instance),
|
||||
"<i>Raid</i> — When {this} enters the battlefield, you lose 4 life unless you attacked with a creature this turn"
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.KickedCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -33,7 +33,7 @@ public final class BenalishEmissary extends CardImpl {
|
|||
// When Benalish Emissary enters the battlefield, if it was kicked, destroy target land.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect());
|
||||
ability.addTarget(new TargetLandPermanent());
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.instance,
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, KickedCondition.instance,
|
||||
"When {this} enters the battlefield, if it was kicked, destroy target land."));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
|
@ -31,9 +31,10 @@ public final class BladeTribeBerserkers extends CardImpl {
|
|||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
//Metalcraft - When Blade-Tribe Berserkers enters the battlefield, if you control three or more artifacts, Blade-Tribe Berserkers gets +3/+3 and gains haste until end of turn.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new BoostSourceEffect(3, 3, Duration.EndOfTurn), false);
|
||||
ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
}
|
||||
|
||||
public BladeTribeBerserkers(final BladeTribeBerserkers card) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.MetalcraftCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -31,12 +31,13 @@ public final class BleakCovenVampires extends CardImpl {
|
|||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
//Metalcraft - When Bleak Coven Vampires enters the battlefield, if you control three or more artifacts, target player loses 4 life and you gain 4 life.
|
||||
TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new LoseLifeTargetEffect(4), false);
|
||||
ability.addEffect(new GainLifeEffect(4));
|
||||
Target target = new TargetPlayer();
|
||||
ability.addTarget(target);
|
||||
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MetalcraftCondition.instance, effectText));
|
||||
}
|
||||
|
||||
public BleakCovenVampires(final BleakCovenVampires card) {
|
||||
|
|
|
@ -72,12 +72,7 @@ class BloodSunEffect extends ContinuousEffectImpl {
|
|||
for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_LANDS, player.getId(), source.getSourceId(), game)) {
|
||||
switch (layer) {
|
||||
case AbilityAddingRemovingEffects_6:
|
||||
for (Iterator<Ability> it = permanent.getAbilities().iterator(); it.hasNext();) {
|
||||
Ability ability = it.next();
|
||||
if (!ability.getAbilityType().equals(AbilityType.MANA)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
permanent.getAbilities().removeIf(ability -> ability.getAbilityType() != AbilityType.MANA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
|
|||
import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility;
|
||||
import mage.abilities.condition.common.OpponentLostLifeCondition;
|
||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -38,7 +38,7 @@ public final class BloodchiefAscension extends CardImpl {
|
|||
true));
|
||||
|
||||
// Whenever a card is put into an opponent's graveyard from anywhere, if Bloodchief Ascension has three or more quest counters on it, you may have that player lose 2 life. If you do, you gain 2 life.
|
||||
Ability ability = new ConditionalTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(
|
||||
new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
|
||||
new LoseLifeTargetEffect(2), true, new FilterCard("a card"), TargetController.OPPONENT, SetTargetPointer.PLAYER),
|
||||
new SourceHasCounterCondition(CounterType.QUEST, 3, Integer.MAX_VALUE),
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
|
||||
import mage.abilities.condition.common.HellbentCondition;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.keyword.MadnessAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -31,7 +31,7 @@ public final class BloodhallPriest extends CardImpl {
|
|||
// Whenever Bloodhall Priest enters the battlefield or attacks, if you have no cards in hand, Bloodhall Priest deals 2 damage to any target.
|
||||
TriggeredAbility triggeredAbility = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DamageTargetEffect(2));
|
||||
triggeredAbility.addTarget(new TargetAnyTarget());
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
triggeredAbility,
|
||||
HellbentCondition.instance,
|
||||
"Whenever {this} enters the battlefield or attacks, if you have no cards in hand, {this} deals 2 damage to any target"
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -34,12 +34,12 @@ public final class BlowflyInfestation extends CardImpl {
|
|||
public BlowflyInfestation(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}");
|
||||
|
||||
|
||||
//Whenever a creature dies, if it had a -1/-1 counter on it, put a -1/-1 counter on target creature.
|
||||
Effect effect = new BlowflyInfestationEffect();
|
||||
TriggeredAbility triggeredAbility = new DiesCreatureTriggeredAbility(effect, false, false, true);
|
||||
triggeredAbility.addTarget(new TargetCreaturePermanent());
|
||||
Condition condition = new BlowflyInfestationCondition();
|
||||
this.addAbility(new ConditionalTriggeredAbility(triggeredAbility, condition, rule));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggeredAbility, condition, rule));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class DiesWhileInGraveyardTriggeredAbility extends TriggeredAbilityImpl {
|
|||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
for (Zone z : Zone.values()) {
|
||||
if (game.getShortLivingLKI(sourceId, z) && !z.equals(Zone.GRAVEYARD)) {
|
||||
if (game.getShortLivingLKI(sourceId, z) && z != Zone.GRAVEYARD) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
97
Mage.Sets/src/mage/cards/b/BoobyTrap.java
Normal file
97
Mage.Sets/src/mage/cards/b/BoobyTrap.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.AsEntersBattlefieldAbility;
|
||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.effects.common.ChooseACardNameEffect;
|
||||
import mage.abilities.effects.common.ChooseOpponentEffect;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.abilities.effects.common.DoIfCostPaid;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.players.Player;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author noahg
|
||||
*/
|
||||
public final class BoobyTrap extends CardImpl {
|
||||
|
||||
public BoobyTrap(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
|
||||
|
||||
// As Booby Trap enters the battlefield, name a card other than a basic land card and choose an opponent.
|
||||
AsEntersBattlefieldAbility etbAbility = new AsEntersBattlefieldAbility(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NOT_BASIC_LAND_NAME));
|
||||
etbAbility.addEffect(new ChooseOpponentEffect(Outcome.Damage));
|
||||
this.addAbility(etbAbility);
|
||||
|
||||
// The chosen player reveals each card he or she draws.
|
||||
// When the chosen player draws the named card, sacrifice Booby Trap. If you do, Booby Trap deals 10 damage to that player.
|
||||
this.addAbility(new BoobyTrapTriggeredAbility());
|
||||
}
|
||||
|
||||
public BoobyTrap(final BoobyTrap card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoobyTrap copy() {
|
||||
return new BoobyTrap(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BoobyTrapTriggeredAbility extends TriggeredAbilityImpl {
|
||||
|
||||
public BoobyTrapTriggeredAbility() {
|
||||
super(Zone.BATTLEFIELD, new DoIfCostPaid(new DamageTargetEffect(10, true, "that player"), new SacrificeSourceCost(), "", false), false);
|
||||
}
|
||||
|
||||
public BoobyTrapTriggeredAbility(BoobyTrapTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.DREW_CARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Player controller = game.getPlayer(getControllerId());
|
||||
if (event.getPlayerId() == null || game.getState() == null || controller == null) {
|
||||
return false;
|
||||
}
|
||||
if (event.getPlayerId().equals(game.getState().getValue(getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY))) {
|
||||
Card drawn = game.getCard(event.getTargetId());
|
||||
if (drawn != null) {
|
||||
controller.revealCards(this, new CardsImpl(drawn), game);
|
||||
if (drawn.getName().equals(game.getState().getValue(getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) {
|
||||
//Set target
|
||||
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoobyTrapTriggeredAbility copy() {
|
||||
return new BoobyTrapTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "The chosen player reveals each card he or she draws.\n" +
|
||||
"When the chosen player draws the named card, sacrifice {this}. If you do, {this} deals 10 damage to that player.";
|
||||
}
|
||||
}
|
|
@ -13,11 +13,10 @@ import mage.abilities.costs.common.PayLifeCost;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterInstantOrSorceryCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.stack.Spell;
|
||||
|
@ -42,9 +41,9 @@ public final class BoseijuWhoSheltersAll extends CardImpl {
|
|||
SimpleManaAbility ability = new SimpleManaAbility(Zone.BATTLEFIELD, mana, new TapSourceCost());
|
||||
ability.addCost(new PayLifeCost(2));
|
||||
ability.getEffects().get(0).setText("Add {C}. If that mana is spent on an instant or sorcery spell, that spell can't be countered");
|
||||
this.addAbility(ability);
|
||||
this.addAbility(ability, new BoseijuWhoSheltersAllWatcher(ability.getOriginalId()));
|
||||
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoseijuWhoSheltersAllCantCounterEffect()), new BoseijuWhoSheltersAllWatcher());
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new BoseijuWhoSheltersAllCantCounterEffect()));
|
||||
}
|
||||
|
||||
public BoseijuWhoSheltersAll(final BoseijuWhoSheltersAll card) {
|
||||
|
@ -59,14 +58,18 @@ public final class BoseijuWhoSheltersAll extends CardImpl {
|
|||
|
||||
class BoseijuWhoSheltersAllWatcher extends Watcher {
|
||||
|
||||
public List<UUID> spells = new ArrayList<>();
|
||||
private List<UUID> spells = new ArrayList<>();
|
||||
private final String originalId;
|
||||
|
||||
public BoseijuWhoSheltersAllWatcher() {
|
||||
super(BoseijuWhoSheltersAllWatcher.class.getSimpleName(), WatcherScope.GAME);
|
||||
public BoseijuWhoSheltersAllWatcher(UUID originalId) {
|
||||
super(BoseijuWhoSheltersAllWatcher.class.getSimpleName(), WatcherScope.CARD);
|
||||
this.originalId = originalId.toString();
|
||||
}
|
||||
|
||||
public BoseijuWhoSheltersAllWatcher(final BoseijuWhoSheltersAllWatcher watcher) {
|
||||
super(watcher);
|
||||
this.spells.addAll(watcher.spells);
|
||||
this.originalId = watcher.originalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,14 +80,19 @@ class BoseijuWhoSheltersAllWatcher extends Watcher {
|
|||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.MANA_PAID) {
|
||||
MageObject object = game.getObject(event.getSourceId());
|
||||
// TODO: Replace identification by name by better method that also works if ability is copied from other land with other name
|
||||
if (object != null && object.getName().equals("Boseiju, Who Shelters All") && event.getFlag()) {
|
||||
spells.add(event.getTargetId());
|
||||
if (event.getData() != null && event.getData().equals(originalId)) {
|
||||
Card spell = game.getCard(event.getTargetId());
|
||||
if (spell != null && (spell.isInstant() || spell.isSorcery())) {
|
||||
spells.add(event.getTargetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean spellCantBeCountered(UUID spellId) {
|
||||
return spells.contains(spellId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
|
@ -94,10 +102,8 @@ class BoseijuWhoSheltersAllWatcher extends Watcher {
|
|||
|
||||
class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterInstantOrSorceryCard();
|
||||
|
||||
public BoseijuWhoSheltersAllCantCounterEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Benefit);
|
||||
super(Duration.EndOfGame, Outcome.Benefit);
|
||||
staticText = null;
|
||||
}
|
||||
|
||||
|
@ -119,7 +125,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffe
|
|||
public String getInfoMessage(Ability source, GameEvent event, Game game) {
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (sourceObject != null) {
|
||||
return "This spell can't be countered (" + sourceObject.getName() + ").";
|
||||
return "This spell can't be countered because mana from " + sourceObject.getName() + " was spent to cast it.";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -131,13 +137,8 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifyingEffe
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get(BoseijuWhoSheltersAllWatcher.class.getSimpleName());
|
||||
BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get(BoseijuWhoSheltersAllWatcher.class.getSimpleName(), source.getSourceId());
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null && watcher.spells.contains(spell.getId())) {
|
||||
if (filter.match(spell.getCard(), game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return spell != null && watcher != null && watcher.spellCantBeCountered(spell.getId());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -34,7 +34,7 @@ public final class BrandedHowler extends CardImpl {
|
|||
|
||||
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Branded Howler.
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.instance, TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.instance, TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
|
||||
}
|
||||
|
||||
public BrandedHowler(final BrandedHowler card) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import mage.ObjectColor;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.CastFromHandSourceCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
|
||||
|
@ -40,7 +40,7 @@ public final class BreachingLeviathan extends CardImpl {
|
|||
this.toughness = new MageInt(9);
|
||||
|
||||
// When Breaching Leviathan enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new BreachingLeviathanEffect(), false),
|
||||
CastFromHandSourceCondition.instance,
|
||||
"When {this} enters the battlefield, if you cast it from your hand, tap all nonblue creatures. Those creatures don't untap during their controllers' next untap steps."),
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -34,7 +34,7 @@ public final class BreakneckRider extends CardImpl {
|
|||
// At the beginning of each upkeep, if no spells were cast last turn, transform Breakneck Rider.
|
||||
this.addAbility(new TransformAbility());
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
}
|
||||
|
||||
public BreakneckRider(final BreakneckRider card) {
|
||||
|
|
|
@ -80,7 +80,7 @@ class BreathOfFuryAbility extends TriggeredAbilityImpl {
|
|||
Permanent enchantment = game.getPermanent(getSourceId());
|
||||
if (damageEvent.isCombatDamage()
|
||||
&& enchantment != null
|
||||
&& enchantment.getAttachedTo().equals(event.getSourceId())) {
|
||||
&& enchantment.isAttachedTo(event.getSourceId())) {
|
||||
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
|
||||
if (creature != null) {
|
||||
for (Effect effect : getEffects()) {
|
||||
|
|
|
@ -18,6 +18,8 @@ import mage.constants.SubType;
|
|||
import mage.constants.Zone;
|
||||
import mage.filter.FilterSpell;
|
||||
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
|
||||
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardTypePredicate;
|
||||
import mage.target.TargetSpell;
|
||||
|
@ -30,7 +32,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
*/
|
||||
public final class BrineShaman extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterSpell("noncreature spell");
|
||||
private static final FilterSpell filter = new FilterSpell("creature spell");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
|
||||
|
@ -54,7 +56,7 @@ public final class BrineShaman extends CardImpl {
|
|||
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(),
|
||||
new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
|
||||
ability.addCost(new ManaCostsImpl("{1}{U}{U}"));
|
||||
ability.addTarget(new TargetSpell(filter));
|
||||
ability.addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_CREATURE));
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.CardsInHandCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||
import mage.cards.Card;
|
||||
|
@ -37,7 +37,7 @@ public final class BrinkOfMadness extends CardImpl {
|
|||
ability.addEffect(new BrinkOfMadnessEffect());
|
||||
ability.addTarget(new TargetOpponent());
|
||||
CardsInHandCondition contition = new CardsInHandCondition(ComparisonType.EQUAL_TO, 0);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, contition, "At the beginning of your upkeep, if you have no cards in hand, sacrifice {this} and target opponent discards their hand."));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, contition, "At the beginning of your upkeep, if you have no cards in hand, sacrifice {this} and target opponent discards their hand."));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.FlipSourceEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -20,7 +20,6 @@ import mage.counters.CounterType;
|
|||
import mage.filter.StaticFilters;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -44,7 +43,7 @@ public final class BudokaPupil extends CardImpl {
|
|||
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.SPIRIT_OR_ARCANE_CARD, true));
|
||||
|
||||
// At the beginning of the end step, if there are two or more ki counters on Budoka Pupil, you may flip it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new FlipSourceEffect(new IchigaWhoTopplesOaks()), true),
|
||||
new SourceHasCounterCondition(CounterType.KI, 2, Integer.MAX_VALUE),
|
||||
"At the beginning of the end step, if there are two or more ki counters on {this}, you may flip it."));
|
||||
|
|
|
@ -77,7 +77,7 @@ class BuildersBaneEffect extends OneShotEffect {
|
|||
if (permanent.destroy(source.getSourceId(), game, false)) {
|
||||
game.applyEffects();
|
||||
if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId())
|
||||
&& !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) {
|
||||
&& game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) {
|
||||
// A replacement effect has moved the card to another zone as grvayard
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.constants.SubType;
|
||||
|
@ -36,7 +36,7 @@ public final class BullRushBruiser extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// Whenever Bull-Rush Bruiser attacks, if your team controls another Warrior, Bull-Rush Bruiser gains first strike until end of turn.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new AttacksTriggeredAbility(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), false),
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"Whenever {this} attacks, if your team controls another Warrior, "
|
||||
|
|
|
@ -18,40 +18,41 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public final class BurntheImpure extends CardImpl {
|
||||
public final class BurnTheImpure extends CardImpl {
|
||||
|
||||
public BurntheImpure(UUID ownerId, CardSetInfo setInfo) {
|
||||
public BurnTheImpure(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}");
|
||||
|
||||
// Burn the Impure deals 3 damage to target creature. If that creature has infect, Burn the Impure deals 3 damage to that creature’s controller.
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().addEffect(new BurntheImpureEffect());
|
||||
this.getSpellAbility().addEffect(new BurnTheImpureEffect());
|
||||
}
|
||||
|
||||
public BurntheImpure(final BurntheImpure card) {
|
||||
public BurnTheImpure(final BurnTheImpure card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BurntheImpure copy() {
|
||||
return new BurntheImpure(this);
|
||||
public BurnTheImpure copy() {
|
||||
return new BurnTheImpure(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BurntheImpureEffect extends OneShotEffect {
|
||||
class BurnTheImpureEffect extends OneShotEffect {
|
||||
|
||||
public BurntheImpureEffect() {
|
||||
public BurnTheImpureEffect() {
|
||||
super(Outcome.Damage);
|
||||
staticText = "{this} deals 3 damage to target creature. If that creature has infect, {this} deals 3 damage to that creature's controller.";
|
||||
}
|
||||
|
||||
public BurntheImpureEffect(final BurntheImpureEffect effect) {
|
||||
public BurnTheImpureEffect(final BurnTheImpureEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BurntheImpureEffect copy() {
|
||||
return new BurntheImpureEffect(this);
|
||||
public BurnTheImpureEffect copy() {
|
||||
return new BurnTheImpureEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DiesTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -31,7 +31,7 @@ public final class BurningEyeZubera extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// When Burning-Eye Zubera dies, if 4 or more damage was dealt to it this turn, Burning-Eye Zubera deals 3 damage to any target.
|
||||
Ability ability = new ConditionalTriggeredAbility(new DiesTriggeredAbility(new DamageTargetEffect(3)),new SourceGotFourDamage(),
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(new DiesTriggeredAbility(new DamageTargetEffect(3)),new SourceGotFourDamage(),
|
||||
"When {this} dies, if 4 or more damage was dealt to it this turn, Burning-Eye Zubera deals 3 damage to any target");
|
||||
ability.addTarget(new TargetAnyTarget());
|
||||
this.addAbility(ability);
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.KickedCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
|
@ -32,7 +32,7 @@ public final class CaligoSkinWitch extends CardImpl {
|
|||
this.addAbility(new KickerAbility("{3}{B}"));
|
||||
|
||||
// When Caligo Skin-Witch enters the battlefield, if it was kicked, each opponent discards two cards.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(
|
||||
new StaticValue(2),
|
||||
false,
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.RevoltCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.CountersSourceCount;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
|
@ -34,7 +34,7 @@ public final class CallForUnity extends CardImpl {
|
|||
|
||||
// <i>Revolt</i> — At the beginning of your end step, if a permanent you controlled left the battlefield this turn, put a unity counter on Call for Unity.
|
||||
TriggeredAbility ability = new BeginningOfYourEndStepTriggeredAbility(new AddCountersSourceEffect(CounterType.UNITY.createInstance(), true), false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, RevoltCondition.instance, ruleText), new RevoltWatcher());
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, RevoltCondition.instance, ruleText), new RevoltWatcher());
|
||||
|
||||
// Creatures you control get +1/+1 for each unity counter on Call for Unity.
|
||||
Effect effect = new BoostControlledEffect(new CountersSourceCount(CounterType.UNITY), new CountersSourceCount(CounterType.UNITY), Duration.WhileOnBattlefield,
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.AttachEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||
|
@ -47,7 +47,7 @@ public final class CallOfTheFullMoon extends CardImpl {
|
|||
|
||||
// At the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice Call of the Full Moon.
|
||||
TriggeredAbility ability2 = new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect(), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability2, TwoOrMoreSpellsWereCastLastTurnCondition.instance,
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability2, TwoOrMoreSpellsWereCastLastTurnCondition.instance,
|
||||
"At the beginning of each upkeep, if a player cast two or more spells last turn, sacrifice {this}."));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.OnEventTriggeredAbility;
|
||||
import mage.abilities.condition.common.CreatureCountCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.SacrificeEffect;
|
||||
import mage.abilities.effects.common.SacrificeSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -42,7 +42,7 @@ public final class CallToTheGrave extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
// At the beginning of the end step, if no creatures are on the battlefield, sacrifice Call to the Grave.
|
||||
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect());
|
||||
this.addAbility(new ConditionalTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText));
|
||||
}
|
||||
|
||||
public CallToTheGrave(final CallToTheGrave card) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
|||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||
import mage.abilities.costs.common.RemoveCountersSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.CounterUnlessPaysEffect;
|
||||
import mage.abilities.effects.common.FlipSourceEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -24,7 +24,6 @@ import mage.counters.CounterType;
|
|||
import mage.filter.StaticFilters;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.target.TargetSpell;
|
||||
|
||||
/**
|
||||
|
@ -47,7 +46,7 @@ public final class CallowJushi extends CardImpl {
|
|||
this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.KI.createInstance()), StaticFilters.SPIRIT_OR_ARCANE_CARD, true));
|
||||
|
||||
// At the beginning of the end step, if there are two or more ki counters on Callow Jushi, you may flip it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new FlipSourceEffect(new JarakuTheInterloper()), true),
|
||||
new SourceHasCounterCondition(CounterType.KI, 2, Integer.MAX_VALUE),
|
||||
"At the beginning of the end step, if there are two or more ki counters on {this}, you may flip it."));
|
||||
|
|
|
@ -4,7 +4,7 @@ package mage.cards.c;
|
|||
import java.util.UUID;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SanctuaryTriggeredAbility;
|
||||
import mage.abilities.common.SanctuaryInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawDiscardControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -20,7 +20,7 @@ public final class CetaSanctuary extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
|
||||
|
||||
// At the beginning of your upkeep, if you control a red or green permanent, draw a card, then discard a card. If you control a red permanent and a green permanent, instead draw two cards, then discard a card.
|
||||
Ability ability = new SanctuaryTriggeredAbility(
|
||||
Ability ability = new SanctuaryInterveningIfTriggeredAbility(
|
||||
new DrawDiscardControllerEffect(1, 1), new DrawDiscardControllerEffect(2, 1), ObjectColor.GREEN, ObjectColor.RED,
|
||||
"At the beginning of your upkeep, if you control a red or green permanent, draw a card, then discard a card. "
|
||||
+ "If you control a red permanent and a green permanent, instead draw two cards, then discard a card."
|
||||
|
|
|
@ -85,7 +85,7 @@ class ChainsOfMephistophelesReplacementEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (game.getActivePlayerId().equals(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) {
|
||||
if (game.isActivePlayer(event.getPlayerId()) && game.getPhase().getStep().getType() == PhaseStep.DRAW) {
|
||||
CardsDrawnDuringDrawStepWatcher watcher = (CardsDrawnDuringDrawStepWatcher) game.getState().getWatchers().get(CardsDrawnDuringDrawStepWatcher.class.getSimpleName());
|
||||
if (watcher != null && watcher.getAmountCardsDrawn(event.getPlayerId()) > 0) {
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SpellCastControllerTriggeredAbility;
|
||||
|
@ -15,6 +14,8 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.abilities.TriggeredAbility;
|
|||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.SourceHasCounterCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.WinGameSourceControllerEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -32,7 +32,7 @@ public final class ChanceEncounter extends CardImpl {
|
|||
|
||||
// At the beginning of your upkeep, if Chance Encounter has ten or more luck counters on it, you win the game.
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new WinGameSourceControllerEffect(), TargetController.YOU, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new SourceHasCounterCondition(CounterType.LUCK, 10, Integer.MAX_VALUE),
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceHasCounterCondition(CounterType.LUCK, 10, Integer.MAX_VALUE),
|
||||
"At the beginning of your upkeep, if {this} has ten or more luck counters on it, you win the game"));
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ class ChancellorOfTheTangleDelayedTriggeredAbility extends DelayedTriggeredAbili
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return game.getActivePlayerId().equals(controllerId);
|
||||
return game.isActivePlayer(controllerId);
|
||||
}
|
||||
@Override
|
||||
public ChancellorOfTheTangleDelayedTriggeredAbility copy() {
|
||||
|
|
|
@ -82,14 +82,16 @@ class ChaosWandEffect extends OneShotEffect {
|
|||
break;
|
||||
}
|
||||
opponent.moveCards(card, Zone.EXILED, source, game);
|
||||
controller.revealCards(source, new CardsImpl(card), game);
|
||||
if (card.isInstant() || card.isSorcery()) {
|
||||
if (!controller.chooseUse(outcome, "Cast " + card.getName() + " without paying its mana cost?", source, game)
|
||||
|| !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
|
||||
cardsToShuffle.add(card);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
cardsToShuffle.add(card);
|
||||
}
|
||||
cardsToShuffle.add(card);
|
||||
}
|
||||
return opponent.putCardsOnBottomOfLibrary(cardsToShuffle, game, source, false);
|
||||
}
|
||||
|
|
|
@ -72,10 +72,9 @@ class ChronicFloodingAbility extends TriggeredAbilityImpl {
|
|||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
Permanent source = game.getPermanent(this.sourceId);
|
||||
if (source != null && source.getAttachedTo().equals(event.getTargetId())) {
|
||||
if (source != null && source.isAttachedTo(event.getTargetId())) {
|
||||
Permanent attached = game.getPermanent(source.getAttachedTo());
|
||||
if (attached != null) {
|
||||
|
||||
for (Effect e : getEffects()) {
|
||||
e.setTargetPointer(new FixedTarget(attached.getControllerId()));
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.DiesTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
import mage.abilities.condition.common.LastTimeCounterRemovedCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.CreateTokenCopySourceEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -46,7 +46,7 @@ public final class Chronozoa extends CardImpl {
|
|||
// When Chronozoa is put into a graveyard from play, if it had no time counters on it, create two tokens that are copies of it.
|
||||
Effect effect = new CreateTokenCopySourceEffect(2);
|
||||
effect.setText("create two tokens that are copies of it");
|
||||
this.addAbility(new ConditionalTriggeredAbility(new DiesTriggeredAbility(effect, false),
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new DiesTriggeredAbility(effect, false),
|
||||
LastTimeCounterRemovedCondition.instance,
|
||||
"When {this} dies, if it had no time counters on it, create two tokens that are copies of it."));
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class CinderCloudEffect extends OneShotEffect {
|
|||
if (permanent != null && permanent.destroy(source.getSourceId(), game, false) && permanent.getColor(game).equals(ObjectColor.WHITE)) {
|
||||
game.applyEffects();
|
||||
if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId())
|
||||
&& !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) {
|
||||
&& game.getState().getZone(permanent.getId()) != Zone.GRAVEYARD) {
|
||||
// A replacement effect has moved the card to another zone as grvayard
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
|
||||
import mage.abilities.common.EntersBattlefieldAbility;
|
||||
|
@ -21,6 +20,8 @@ import mage.game.Game;
|
|||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.KickedCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.keyword.KickerAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -31,7 +31,7 @@ public final class CitanulWoodreaders extends CardImpl {
|
|||
this.addAbility(new KickerAbility("{2}{G}"));
|
||||
|
||||
// When Citanul Woodreaders enters the battlefield, if it was kicked, draw two cards.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(2)),
|
||||
KickedCondition.instance,
|
||||
"When {this} enters the battlefield, if it was kicked, draw two cards."
|
||||
|
|
|
@ -67,7 +67,7 @@ class CityOfSolitudeEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
return !game.getActivePlayerId().equals(event.getPlayerId());
|
||||
return !game.isActivePlayer(event.getPlayerId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,7 +11,7 @@ import mage.abilities.condition.common.IsStepCondition;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -51,7 +51,7 @@ public final class ClockworkAvian extends CardImpl {
|
|||
));
|
||||
|
||||
// At end of combat, if Clockwork Avian attacked or blocked this combat, remove a +1/+0 counter from it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false),
|
||||
AttackedOrBlockedThisCombatSourceCondition.instance,
|
||||
"At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."),
|
||||
|
|
|
@ -11,7 +11,7 @@ import mage.abilities.condition.common.IsStepCondition;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||
|
@ -47,7 +47,7 @@ public final class ClockworkBeast extends CardImpl {
|
|||
));
|
||||
|
||||
// At end of combat, if Clockwork Beast attacked or blocked this combat, remove a +1/+0 counter from it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false),
|
||||
AttackedOrBlockedThisCombatSourceCondition.instance,
|
||||
"At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."),
|
||||
|
|
|
@ -12,7 +12,7 @@ import mage.abilities.condition.common.IsStepCondition;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
|
||||
|
@ -58,7 +58,7 @@ public final class ClockworkSteed extends CardImpl {
|
|||
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
|
||||
|
||||
// At end of combat, if Clockwork Steed attacked or blocked this combat, remove a +1/+0 counter from it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false),
|
||||
AttackedOrBlockedThisCombatSourceCondition.instance,
|
||||
"At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."),
|
||||
|
|
|
@ -12,7 +12,7 @@ import mage.abilities.condition.common.IsStepCondition;
|
|||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.decorator.ConditionalActivatedAbility;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
|
||||
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
|
||||
|
@ -62,7 +62,7 @@ public final class ClockworkSwarm extends CardImpl {
|
|||
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
|
||||
|
||||
// At end of combat, if Clockwork Swarm attacked or blocked this combat, remove a +1/+0 counter from it.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false),
|
||||
AttackedOrBlockedThisCombatSourceCondition.instance,
|
||||
"At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."),
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.Mana;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.CastFromHandSourceCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -27,7 +27,7 @@ public final class CoalStoker extends CardImpl {
|
|||
this.toughness = new MageInt(3);
|
||||
|
||||
// When Coal Stoker enters the battlefield, if you cast it from your hand, add {R}{R}{R}.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new EntersBattlefieldTriggeredAbility(new BasicManaEffect(Mana.RedMana(3)), false),
|
||||
CastFromHandSourceCondition.instance,
|
||||
"When {this} enters the battlefield, if you cast it from your hand, add {R}{R}{R}."),
|
||||
|
|
|
@ -3,7 +3,7 @@ package mage.cards.c;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.FerociousCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -20,7 +20,7 @@ public final class ColossalMajesty extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
|
||||
|
||||
// At the beginning of your upkeep, if you control a creature with power 4 or greater, draw a card.
|
||||
this.addAbility(new ConditionalTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new BeginningOfUpkeepTriggeredAbility(
|
||||
new DrawCardSourceControllerEffect(1),
|
||||
TargetController.YOU, false
|
||||
|
|
|
@ -105,7 +105,7 @@ class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl {
|
|||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (castOnTurn != game.getTurnNum() && game.getPhase().getStep().getType() == PhaseStep.END_TURN) {
|
||||
if (game.getActivePlayerId().equals(source.getControllerId())) {
|
||||
if (game.isActivePlayer(source.getControllerId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -31,7 +31,7 @@ public final class ComplexAutomaton extends CardImpl {
|
|||
|
||||
// At the beginning of your upkeep, if you control seven or more permanents, return Complex Automaton to its owner's hand.
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new ReturnToHandSourceEffect(true), TargetController.YOU, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(), ComparisonType.MORE_THAN, 6),
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(), ComparisonType.MORE_THAN, 6),
|
||||
"At the beginning of your upkeep, if you control seven or more permanents, return Complex Automaton to its owner's hand."));
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ class ConquerorsFlailEffect extends ContinuousRuleModifyingEffectImpl {
|
|||
}
|
||||
}
|
||||
|
||||
if (isAttached && game.getActivePlayerId().equals(source.getControllerId())
|
||||
if (isAttached && game.isActivePlayer(source.getControllerId())
|
||||
&& game.getPlayer(source.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.abilities.common.AttacksTriggeredAbility;
|
||||
import mage.abilities.condition.common.RenownedSourceCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||
import mage.abilities.keyword.FirstStrikeAbility;
|
||||
import mage.abilities.keyword.RenownAbility;
|
||||
|
@ -34,7 +34,7 @@ public final class ConsulsLieutenant extends CardImpl {
|
|||
// Renown 1
|
||||
this.addAbility(new RenownAbility(1));
|
||||
// Whenever Consul's Lieutenant attacks, if it's renowned, other attacking creatures you control get +1/+1 until end of turn.
|
||||
this.addAbility(new ConditionalTriggeredAbility(new AttacksTriggeredAbility(
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(new AttacksTriggeredAbility(
|
||||
new BoostControlledEffect(1, 1, Duration.EndOfTurn, new FilterAttackingCreature("other attacking creatures you control"), true), false),
|
||||
RenownedSourceCondition.instance,
|
||||
"Whenever Consul's Lieutenant attacks, if it's renowned, other attacking creatures you control get +1/+1 until end of turn."));
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.XorLessLifeCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
|
@ -27,7 +27,7 @@ public final class ConvalescentCare extends CardImpl {
|
|||
Effect effect = new DrawCardSourceControllerEffect(1);
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new GainLifeEffect(3), TargetController.YOU, false);
|
||||
ability.addEffect(effect);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, new XorLessLifeCondition(XorLessLifeCondition.CheckType.CONTROLLER, 5), "At the beginning of your upkeep, if you have 5 or less life, you gain 3 life and draw a card."));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new XorLessLifeCondition(XorLessLifeCondition.CheckType.CONTROLLER, 5), "At the beginning of your upkeep, if you have 5 or less life, you gain 3 life and draw a card."));
|
||||
}
|
||||
|
||||
public ConvalescentCare(final ConvalescentCare card) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -35,7 +35,7 @@ public final class ConvictedKiller extends CardImpl {
|
|||
// At the beginning of each upkeep, if no spells were cast last turn, transform Convicted Killer.
|
||||
this.addAbility(new TransformAbility());
|
||||
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
|
||||
this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.instance, TransformAbility.NO_SPELLS_TRANSFORM_RULE));
|
||||
}
|
||||
|
||||
public ConvictedKiller(final ConvictedKiller card) {
|
||||
|
|
|
@ -175,8 +175,8 @@ class CorrosiveOozeCombatWatcher extends Watcher {
|
|||
}
|
||||
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
|
||||
if (((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD)) {
|
||||
if (game.getTurn() != null && TurnPhase.COMBAT.equals(game.getTurn().getPhaseType())) {
|
||||
if (((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
|
||||
if (game.getTurn() != null && TurnPhase.COMBAT == game.getTurn().getPhaseType()) {
|
||||
// Check if a previous blocked or blocked by creatures is leaving the battlefield
|
||||
for (Map.Entry<MageObjectReference, HashSet<MageObjectReference>> entry : oozeBlocksOrBlocked.entrySet()) {
|
||||
for (MageObjectReference mor : entry.getValue()) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.c;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -28,7 +27,7 @@ import mage.target.common.TargetNonlandPermanent;
|
|||
public final class CouncilsJudgment extends CardImpl {
|
||||
|
||||
public CouncilsJudgment(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}{W}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}{W}");
|
||||
|
||||
// Will of the council - Starting with you, each player votes for a nonland permanent you don't control. Exile each permanent with the most votes or tied for most votes.
|
||||
this.getSpellAbility().addEffect(new CouncilsJudgmentEffect());
|
||||
|
@ -89,7 +88,7 @@ class CouncilsJudgmentEffect extends OneShotEffect {
|
|||
}
|
||||
chosenCards.put(permanent, 1);
|
||||
}
|
||||
game.informPlayers(player.getLogName() + " has chosen: " + permanent.getName());
|
||||
game.informPlayers(player.getLogName() + " has chosen: " + permanent.getLogName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.condition.common.RevoltCondition;
|
||||
import mage.abilities.decorator.ConditionalTriggeredAbility;
|
||||
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
@ -31,7 +31,7 @@ public final class CountlessGearsRenegade extends CardImpl {
|
|||
|
||||
// <i>Revolt</i> — When Countless Gears Renegade enters the battlefield, if a permanent you controlled
|
||||
// left the battlefield this turn, create a 1/1 colorless Servo artifact creature token.
|
||||
Ability ability = new ConditionalTriggeredAbility(new EntersBattlefieldTriggeredAbility(
|
||||
Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(
|
||||
new CreateTokenEffect(new ServoToken(), 1), false), RevoltCondition.instance,
|
||||
"<i>Revolt</i> — When {this} enters the battlefield, if a permanent you controlled left"
|
||||
+ " the battlefield this turn, create a 1/1 colorless Servo artifact creature token.");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue