Merge pull request #74 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
L_J 2018-09-30 12:00:31 +02:00 committed by GitHub
commit b0455ffc02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
772 changed files with 19656 additions and 1866 deletions

View file

@ -538,7 +538,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
// Always hide not hidden popup window or enlarged card view if a frame is set to active // Always hide not hidden popup window or enlarged card view if a frame is set to active
try { try {
ActionCallback callback = Plugins.instance.getActionCallback(); ActionCallback callback = Plugins.instance.getActionCallback();
if (callback != null && callback instanceof MageActionCallback) { if (callback instanceof MageActionCallback) {
((MageActionCallback) callback).hideEnlargedCard(); ((MageActionCallback) callback).hideEnlargedCard();
} }
Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER); Component container = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);

View file

@ -319,7 +319,7 @@ public class DialogManager extends JComponent implements MouseListener,
if (e.getButton() == MouseEvent.BUTTON1) { if (e.getButton() == MouseEvent.BUTTON1) {
j = (JComponent) getComponentAt(e.getX(), e.getY()); j = (JComponent) getComponentAt(e.getX(), e.getY());
if (j != null && j instanceof DialogContainer) { if (j instanceof DialogContainer) {
rec = j.getBounds(); rec = j.getBounds();
bDragged = true; bDragged = true;
mx = e.getX(); mx = e.getX();

View file

@ -398,18 +398,6 @@ public class MageBook extends JComponent {
cardImg.setCardCaptionTopOffset(8); // card caption below real card caption to see full name even with mana icons cardImg.setCardCaptionTopOffset(8); // card caption below real card caption to see full name even with mana icons
boolean implemented = card.getRarity() != Rarity.NA;
// implemented label
// old code, nowadays app load only implemented cards (JayDi85, 23.11.2017)
/*
GlowText label = new GlowText();
label.setGlow(implemented ? Color.green : NOT_IMPLEMENTED, 12, 0.0f);
label.setText(implemented ? "Implemented" : "Not implemented");
int dx = implemented ? 15 : 5;
label.setBounds(rectangle.x + dx, rectangle.y + cardDimensions.frameHeight + 7, 110, 30);
jLayeredPane.add(label);
*/
// card number label // card number label
JLabel cardNumber = new JLabel(); JLabel cardNumber = new JLabel();
int dy = -5; // image panel have empty space in bottom (bug?), need to move label up int dy = -5; // image panel have empty space in bottom (bug?), need to move label up
@ -542,7 +530,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className); Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object newToken = cons.newInstance(); Object newToken = cons.newInstance();
if (newToken != null && newToken instanceof mage.game.permanent.token.Token) { if (newToken instanceof Token) {
((Token) newToken).setExpansionSetCodeForImage(set); ((Token) newToken).setExpansionSetCodeForImage(set);
((Token) newToken).setOriginalExpansionSetCode(set); ((Token) newToken).setOriginalExpansionSetCode(set);
((Token) newToken).setTokenType(token.getType()); ((Token) newToken).setTokenType(token.getType());
@ -592,7 +580,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className); Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object newEmblem = cons.newInstance(); Object newEmblem = cons.newInstance();
if (newEmblem != null && newEmblem instanceof mage.game.command.Emblem) { if (newEmblem instanceof Emblem) {
((Emblem) newEmblem).setExpansionSetCodeForImage(set); ((Emblem) newEmblem).setExpansionSetCodeForImage(set);
emblems.add((Emblem) newEmblem); emblems.add((Emblem) newEmblem);
@ -649,7 +637,7 @@ public class MageBook extends JComponent {
Class<?> c = Class.forName(className); Class<?> c = Class.forName(className);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object newPlane = cons.newInstance(); Object newPlane = cons.newInstance();
if (newPlane != null && newPlane instanceof mage.game.command.Plane) { if (newPlane instanceof Plane) {
((Plane) newPlane).setExpansionSetCodeForImage(set); ((Plane) newPlane).setExpansionSetCodeForImage(set);
planes.add((Plane) newPlane); planes.add((Plane) newPlane);

View file

@ -369,7 +369,7 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
if (!card.getId().equals(bigCard.getCardId())) { if (!card.getId().equals(bigCard.getCardId())) {
if (!MageFrame.isLite()) { if (!MageFrame.isLite()) {
Image image = Plugins.instance.getOriginalImage(card); Image image = Plugins.instance.getOriginalImage(card);
if (image != null && image instanceof BufferedImage) { if (image instanceof BufferedImage) {
// XXX: scaled to fit width // XXX: scaled to fit width
bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, new ArrayList<>(), false); bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, new ArrayList<>(), false);
} else { } else {

View file

@ -617,7 +617,7 @@ public class MageActionCallback implements ActionCallback {
} }
private void displayCardInfo(MageCard mageCard, Image image, BigCard bigCard) { private void displayCardInfo(MageCard mageCard, Image image, BigCard bigCard) {
if (image != null && image instanceof BufferedImage) { if (image instanceof BufferedImage) {
// XXX: scaled to fit width // XXX: scaled to fit width
bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules(), mageCard.getOriginal().isToRotate()); bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules(), mageCard.getOriginal().isToRotate());
// if it's an ability, show only the ability text as overlay // if it's an ability, show only the ability text as overlay

View file

@ -33,8 +33,8 @@ public final class Config {
static { static {
Properties p = new Properties(); Properties p = new Properties();
try { try(FileInputStream fis =new FileInputStream(new File("config/config.properties"))) {
p.load(new FileInputStream(new File("config/config.properties"))); p.load(fis);
} catch (IOException ex) { } catch (IOException ex) {
logger.fatal("Config error ", ex); logger.fatal("Config error ", ex);
} }

View file

@ -47,7 +47,7 @@ public class CountryItemEditor extends BasicComboBoxEditor {
@Override @Override
public void setItem(Object item) { public void setItem(Object item) {
if (item == null || !(item instanceof String[])) { if (!(item instanceof String[])) {
return; return;
} }

View file

@ -800,7 +800,7 @@ public abstract class CardPanel extends MagePermanent implements MouseListener,
// this update removes the isChoosable mark from targetCardsInLibrary // this update removes the isChoosable mark from targetCardsInLibrary
// so only done for permanents because it's needed to redraw counters in different size, if window size was changed // so only done for permanents because it's needed to redraw counters in different size, if window size was changed
// no perfect solution yet (maybe also other not wanted effects for PermanentView objects) // no perfect solution yet (maybe also other not wanted effects for PermanentView objects)
if (updateCard != null && (updateCard instanceof PermanentView)) { if ((updateCard instanceof PermanentView)) {
update(updateCard); update(updateCard);
} }
} }

View file

@ -121,16 +121,14 @@ public class CardPluginImpl implements CardPlugin {
@Override @Override
public MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { public MagePermanent getMagePermanent(PermanentView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) {
CardPanel cardPanel = makePanel(permanent, gameId, loadImage, callback, false, dimension); CardPanel cardPanel = makePanel(permanent, gameId, loadImage, callback, false, dimension);
boolean implemented = permanent.getRarity() != Rarity.NA; cardPanel.setShowCastingCost(true);
cardPanel.setShowCastingCost(implemented);
return cardPanel; return cardPanel;
} }
@Override @Override
public MagePermanent getMageCard(CardView cardView, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { public MagePermanent getMageCard(CardView cardView, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) {
CardPanel cardPanel = makePanel(cardView, gameId, loadImage, callback, false, dimension); CardPanel cardPanel = makePanel(cardView, gameId, loadImage, callback, false, dimension);
boolean implemented = cardView.getRarity() != null && cardView.getRarity() != Rarity.NA; cardPanel.setShowCastingCost(true);
cardPanel.setShowCastingCost(implemented);
return cardPanel; return cardPanel;
} }

View file

@ -231,8 +231,9 @@ public enum MythicspoilerComSource implements CardImageSource {
supportedSets.add("DOM"); supportedSets.add("DOM");
supportedSets.add("BBD"); supportedSets.add("BBD");
supportedSets.add("M19"); supportedSets.add("M19");
// supportedSets.add("C18"); supportedSets.add("C18");
// supportedSets.add("CM2"); supportedSets.add("CM2");
supportedSets.add("GRN");
sets = new LinkedHashMap<>(); sets = new LinkedHashMap<>();
setsAliases = new HashMap<>(); setsAliases = new HashMap<>();

View file

@ -129,7 +129,10 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("WWK"); supportedSets.add("WWK");
supportedSets.add("DDE"); supportedSets.add("DDE");
supportedSets.add("ROE"); supportedSets.add("ROE");
// duels of the planewalkers:
supportedSets.add("DPA"); supportedSets.add("DPA");
supportedSets.add("DPAP");
//
supportedSets.add("ARC"); supportedSets.add("ARC");
supportedSets.add("M11"); supportedSets.add("M11");
supportedSets.add("V10"); supportedSets.add("V10");
@ -230,6 +233,10 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("CM2"); supportedSets.add("CM2");
supportedSets.add("M19"); supportedSets.add("M19");
supportedSets.add("GS1"); supportedSets.add("GS1");
supportedSets.add("GRN");
//
supportedSets.add("EURO");
supportedSets.add("GPX");
} }
@Override @Override
@ -244,6 +251,15 @@ public enum ScryfallImageSource implements CardImageSource {
String baseUrl = null; String baseUrl = null;
String alternativeUrl = null; String alternativeUrl = null;
// direct links to images (non localization)
if (baseUrl == null) {
String linkCode = card.getSet() + "/" + card.getName();
if (directDownloadLinks.containsKey(linkCode)) {
baseUrl = directDownloadLinks.get(linkCode);
alternativeUrl = null;
}
}
// special card number like "103a" already compatible // special card number like "103a" already compatible
if (baseUrl == null && card.isCollectorIdWithStr()) { if (baseUrl == null && card.isCollectorIdWithStr()) {
baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/" baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
@ -329,6 +345,40 @@ public enum ScryfallImageSource implements CardImageSource {
put("MPS-AKH", "mp2"); put("MPS-AKH", "mp2");
put("MBP", "pmei"); put("MBP", "pmei");
put("WMCQ", "pwcq"); put("WMCQ", "pwcq");
put("EURO", "pelp");
put("GPX", "pgpx");
}
};
private static final Map<String, String> directDownloadLinks = new HashMap<String, String>() {
{
// direct links to download images for special cards
// Duels of the Planeswalkers Promos -- xmage uses one set (DPAP), but scryfall store it by years
// 2009 - https://scryfall.com/sets/pdtp
put("DPAP/Garruk Wildspeaker", "https://img.scryfall.com/cards/large/en/pdtp/1.jpg");
// 2010 - https://scryfall.com/sets/pdp10
put("DPAP/Liliana Vess", "https://img.scryfall.com/cards/large/en/pdp10/1.jpg");
put("DPAP/Nissa Revane", "https://img.scryfall.com/cards/large/en/pdp10/2.jpg");
// 2011 - https://scryfall.com/sets/pdp11
put("DPAP/Frost Titan", "https://img.scryfall.com/cards/large/en/pdp11/1.jpg");
put("DPAP/Grave Titan", "https://img.scryfall.com/cards/large/en/pdp11/2.jpg");
put("DPAP/Inferno Titan", "https://img.scryfall.com/cards/large/en/pdp11/3.jpg");
// 2012 - https://scryfall.com/sets/pdp12
put("DPAP/Primordial Hydra", "https://img.scryfall.com/cards/large/en/pdp12/1.jpg");
put("DPAP/Serra Avatar", "https://img.scryfall.com/cards/large/en/pdp12/2.jpg");
put("DPAP/Vampire Nocturnus", "https://img.scryfall.com/cards/large/en/pdp12/3.jpg");
// 2013 - https://scryfall.com/sets/pdp13
put("DPAP/Bonescythe Sliver", "https://img.scryfall.com/cards/large/en/pdp13/1.jpg");
put("DPAP/Ogre Battledriver", "https://img.scryfall.com/cards/large/en/pdp13/2.jpg");
put("DPAP/Scavenging Ooze", "https://img.scryfall.com/cards/large/en/pdp13/3.jpg");
// 2014 - https://scryfall.com/sets/pdp14
put("DPAP/Soul of Ravnica", "https://img.scryfall.com/cards/large/en/pdp14/1.jpg");
put("DPAP/Soul of Zendikar", "https://img.scryfall.com/cards/large/en/pdp14/2.jpg");
// TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg )
put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg");
} }
}; };

View file

@ -140,7 +140,7 @@ public enum WizardCardsImageSource implements CardImageSource {
supportedSets.add("WWK"); supportedSets.add("WWK");
supportedSets.add("DDE"); supportedSets.add("DDE");
supportedSets.add("ROE"); supportedSets.add("ROE");
supportedSets.add("DPA"); //supportedSets.add("DPA");
supportedSets.add("ARC"); supportedSets.add("ARC");
supportedSets.add("M11"); supportedSets.add("M11");
supportedSets.add("V10"); supportedSets.add("V10");

View file

@ -39,7 +39,7 @@ public class ActionData {
this.gameId = gameId; this.gameId = gameId;
} }
public class CustomExclusionStrategy implements ExclusionStrategy { static class CustomExclusionStrategy implements ExclusionStrategy {
// FIXME: Very crude way of whitelisting, as it applies to all levels of the JSON tree. // FIXME: Very crude way of whitelisting, as it applies to all levels of the JSON tree.
private final java.util.Set<String> KEEP = new java.util.HashSet<>( private final java.util.Set<String> KEEP = new java.util.HashSet<>(

View file

@ -225,7 +225,7 @@ public class Connection {
for (InterfaceAddress addr : iface.getInterfaceAddresses()) { for (InterfaceAddress addr : iface.getInterfaceAddresses()) {
if (addr != null) { if (addr != null) {
InetAddress iaddr = addr.getAddress(); InetAddress iaddr = addr.getAddress();
if (iaddr != null && iaddr instanceof Inet4Address) { if (iaddr instanceof Inet4Address) {
return iaddr; return iaddr;
} }
} }

View file

@ -39,7 +39,7 @@ public final class CompressUtil {
* @return Decompressed object * @return Decompressed object
*/ */
public static Object decompress(Object data) { public static Object decompress(Object data) {
if (data == null || !(data instanceof ZippedObject)) { if (!(data instanceof ZippedObject)) {
return data; return data;
} }
return ((ZippedObject) data).unzip(); return ((ZippedObject) data).unzip();

View file

@ -14,7 +14,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 31; public final static int MAGE_VERSION_PATCH = 31;
public final static String MAGE_VERSION_MINOR_PATCH = "V1"; public final static String MAGE_VERSION_MINOR_PATCH = "V3";
public final static String MAGE_VERSION_INFO = ""; public final static String MAGE_VERSION_INFO = "";
private final int major; private final int major;

View file

@ -2,6 +2,7 @@ package mage.utils.properties;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Properties; import java.util.Properties;
@ -19,16 +20,13 @@ public final class PropertiesUtil {
private static Properties properties = new Properties(); private static Properties properties = new Properties();
static { static {
InputStream in = PropertiesUtil.class.getResourceAsStream("/xmage.properties"); try (InputStream in = PropertiesUtil.class.getResourceAsStream("/xmage.properties")) {
if (in != null) {
try {
properties.load(in); properties.load(in);
} catch (IOException e) { } catch (FileNotFoundException fnfe) {
logger.error("Couldn't load properties", e);
}
} else {
logger.warn("No xmage.properties were found on classpath"); logger.warn("No xmage.properties were found on classpath");
} catch (IOException e) {
logger.error("Couldn't load properties");
e.printStackTrace();
} }
} }
@ -39,7 +37,7 @@ public final class PropertiesUtil {
} }
public static String getDBLogUrl() { public static String getDBLogUrl () {
String url = properties.getProperty(PropertyKeys.KEY_DB_LOG_URL, LOG_JDBC_URL); String url = properties.getProperty(PropertyKeys.KEY_DB_LOG_URL, LOG_JDBC_URL);
if (url != null) { if (url != null) {
return url.trim(); return url.trim();
@ -47,11 +45,11 @@ public final class PropertiesUtil {
return null; return null;
} }
public static String getDBFeedbackUrl() { public static String getDBFeedbackUrl () {
String url = properties.getProperty(PropertyKeys.KEY_DB_FEEDBACK_URL, FEEDBACK_JDBC_URL); String url = properties.getProperty(PropertyKeys.KEY_DB_FEEDBACK_URL, FEEDBACK_JDBC_URL);
if (url != null) { if (url != null) {
return url.trim(); return url.trim();
} }
return null; return null;
} }
} }

View file

@ -512,7 +512,7 @@ public class CardView extends SimpleCardView {
} }
if (this.rarity == null && object instanceof StackAbility) { if (this.rarity == null && object instanceof StackAbility) {
StackAbility stackAbility = (StackAbility) object; StackAbility stackAbility = (StackAbility) object;
this.rarity = Rarity.NA; this.rarity = Rarity.SPECIAL;
this.rules = new ArrayList<>(); this.rules = new ArrayList<>();
this.rules.add(stackAbility.getRule()); this.rules.add(stackAbility.getRule());
if (stackAbility.getZone() == Zone.COMMAND) { if (stackAbility.getZone() == Zone.COMMAND) {
@ -644,7 +644,7 @@ public class CardView extends SimpleCardView {
this.frameColor = token.getFrameColor(null); this.frameColor = token.getFrameColor(null);
this.frameStyle = token.getFrameStyle(); this.frameStyle = token.getFrameStyle();
this.manaCost = token.getManaCost().getSymbols(); this.manaCost = token.getManaCost().getSymbols();
this.rarity = Rarity.NA; this.rarity = Rarity.SPECIAL;
this.type = token.getTokenType(); this.type = token.getTokenType();
this.tokenDescriptor = token.getTokenDescriptor(); this.tokenDescriptor = token.getTokenDescriptor();
this.tokenSetCode = token.getOriginalExpansionSetCode(); this.tokenSetCode = token.getOriginalExpansionSetCode();

View file

@ -76,8 +76,6 @@ public class AusHighlander extends Constructed {
pointMap.put("True-Name Nemesis", 1); pointMap.put("True-Name Nemesis", 1);
pointMap.put("Umezawas Jitte", 1); pointMap.put("Umezawas Jitte", 1);
pointMap.put("Wasteland", 1); pointMap.put("Wasteland", 1);
pointMap.put("Wheel of Fortune", 1);
pointMap.put("Worldly Tutor", 1);
pointMap.put("Yawgmoths Bargain", 1); pointMap.put("Yawgmoths Bargain", 1);
} }

View file

@ -21,7 +21,7 @@ public class CanadianHighlander extends Constructed {
pointMap.put("Balance", 1); pointMap.put("Balance", 1);
pointMap.put("Birthing Pod", 3); pointMap.put("Birthing Pod", 3);
pointMap.put("Black Lotus", 7); pointMap.put("Black Lotus", 7);
pointMap.put("Demonic Tutor", 4); pointMap.put("Demonic Tutor", 3);
pointMap.put("Dig Through Time", 1); pointMap.put("Dig Through Time", 1);
pointMap.put("Enlightened Tutor", 1); pointMap.put("Enlightened Tutor", 1);
pointMap.put("Fastbond", 1); pointMap.put("Fastbond", 1);

View file

@ -0,0 +1,79 @@
package mage.deck;
import mage.cards.decks.Constructed;
/**
*
* @author jmharmon
*/
public class Premodern extends Constructed {
public Premodern() {
super("Constructed - Premodern");
// Legal sets
setCodes.add(mage.sets.FourthEdition.getInstance().getCode());
setCodes.add(mage.sets.IceAge.getInstance().getCode());
setCodes.add(mage.sets.Chronicles.getInstance().getCode());
setCodes.add(mage.sets.Homelands.getInstance().getCode());
setCodes.add(mage.sets.Alliances.getInstance().getCode());
setCodes.add(mage.sets.Mirage.getInstance().getCode());
setCodes.add(mage.sets.Visions.getInstance().getCode());
setCodes.add(mage.sets.FifthEdition.getInstance().getCode());
setCodes.add(mage.sets.Weatherlight.getInstance().getCode());
setCodes.add(mage.sets.Tempest.getInstance().getCode());
setCodes.add(mage.sets.Stronghold.getInstance().getCode());
setCodes.add(mage.sets.UrzasSaga.getInstance().getCode());
setCodes.add(mage.sets.UrzasLegacy.getInstance().getCode());
setCodes.add(mage.sets.ClassicSixthEdition.getInstance().getCode());
setCodes.add(mage.sets.UrzasDestiny.getInstance().getCode());
setCodes.add(mage.sets.MercadianMasques.getInstance().getCode());
setCodes.add(mage.sets.Nemesis.getInstance().getCode());
setCodes.add(mage.sets.Prophecy.getInstance().getCode());
setCodes.add(mage.sets.Invasion.getInstance().getCode());
setCodes.add(mage.sets.Planeshift.getInstance().getCode());
setCodes.add(mage.sets.SeventhEdition.getInstance().getCode());
setCodes.add(mage.sets.Apocalypse.getInstance().getCode());
setCodes.add(mage.sets.Odyssey.getInstance().getCode());
setCodes.add(mage.sets.Torment.getInstance().getCode());
setCodes.add(mage.sets.Judgment.getInstance().getCode());
setCodes.add(mage.sets.Onslaught.getInstance().getCode());
setCodes.add(mage.sets.Legions.getInstance().getCode());
setCodes.add(mage.sets.Scourge.getInstance().getCode());
// Ban List
banned.add("Amulet of Quoz");
banned.add("Balance");
banned.add("Brainstorm");
banned.add("Bronze Tablet");
banned.add("Channel");
banned.add("Demonic Consultation");
banned.add("Earthcraft");
banned.add("Entomb");
banned.add("Flash");
banned.add("Force of Will");
banned.add("Frantic Search");
banned.add("Goblin Recruiter");
banned.add("Grim Monolith");
banned.add("Jeweled Bird");
banned.add("Mana Vault");
banned.add("Memory Jar");
banned.add("Mind Twist");
banned.add("Mind's Desire");
banned.add("Mystical Tutor");
banned.add("Necropotence");
banned.add("Rebirth");
banned.add("Show and Tell");
banned.add("Strip Mine");
banned.add("Tempest Efreet");
banned.add("Tendrils of Agony");
banned.add("Time Spiral");
banned.add("Timmerian Fiends");
banned.add("Tolarian Academy");
banned.add("Vampiric Tutor");
banned.add("Windfall");
banned.add("Worldgorger Dragon");
banned.add("Yawgmoth's Will");
}
}

View file

@ -27,7 +27,7 @@ public class LevelUpOptimizer extends BaseTreeOptimizer {
for (Ability ability : actions) { for (Ability ability : actions) {
if (ability instanceof LevelUpAbility) { if (ability instanceof LevelUpAbility) {
Permanent permanent = game.getPermanent(ability.getSourceId()); Permanent permanent = game.getPermanent(ability.getSourceId());
if (permanent != null && permanent instanceof PermanentCard) { if (permanent instanceof PermanentCard) {
PermanentCard leveler = (PermanentCard) permanent; PermanentCard leveler = (PermanentCard) permanent;
// check already existing Level counters and compare to maximum that make sense // check already existing Level counters and compare to maximum that make sense
if (permanent.getCounters(game).getCount(CounterType.LEVEL) >= leveler.getMaxLevelCounters()) { if (permanent.getCounters(game).getCount(CounterType.LEVEL) >= leveler.getMaxLevelCounters()) {

View file

@ -157,6 +157,7 @@
<deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/> <deckType name="Constructed - Old School 93/94 - Channel Fireball Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394CFB"/>
<deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/> <deckType name="Constructed - Old School 93/94 - EudoGames Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EG"/>
<deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/> <deckType name="Constructed - Old School 93/94 - EC Rules" jar="mage-deck-constructed.jar" className="mage.deck.OldSchool9394EC"/>
<deckType name="Constructed - Premodern" jar="mage-deck-constructed.jar" className="mage.deck.Premodern"/>
<deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/> <deckType name="Constructed - Freeform" jar="mage-deck-constructed.jar" className="mage.deck.Freeform"/>
<deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/> <deckType name="Variant Magic - Commander" jar="mage-deck-constructed.jar" className="mage.deck.Commander"/>
<deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/> <deckType name="Variant Magic - Duel Commander" jar="mage-deck-constructed.jar" className="mage.deck.DuelCommander"/>

View file

@ -672,7 +672,7 @@ public class MageServerImpl implements MageServer {
} catch (Exception ex) { } catch (Exception ex) {
handleException(ex); handleException(ex);
} }
return null; return Optional.empty();
} }
@Override @Override

View file

@ -153,15 +153,15 @@ public final class Main {
for (ExtensionPackage pkg : extensions) { for (ExtensionPackage pkg : extensions) {
Map<String, Class> draftCubes = pkg.getDraftCubes(); Map<String, Class> draftCubes = pkg.getDraftCubes();
for (String name : draftCubes.keySet()) { draftCubes.forEach((name, draftCube) -> {
logger.info("Loading extension: [" + name + "] " + draftCubes.get(name).toString()); logger.info("Loading extension: [" + name + "] " + draftCube.toString());
CubeFactory.instance.addDraftCube(name, draftCubes.get(name)); CubeFactory.instance.addDraftCube(name, draftCube);
} });
Map<String, Class> deckTypes = pkg.getDeckTypes(); Map<String, Class> deckTypes = pkg.getDeckTypes();
for (String name : deckTypes.keySet()) { deckTypes.forEach((name, deckType) -> {
logger.info("Loading extension: [" + name + "] " + deckTypes.get(name)); logger.info("Loading extension: [" + name + "] " + deckType);
DeckValidatorFactory.instance.addDeckType(name, deckTypes.get(name)); DeckValidatorFactory.instance.addDeckType(name, deckType);
} });
} }
logger.info("Config - max seconds idle: " + config.getMaxSecondsIdle()); logger.info("Config - max seconds idle: " + config.getMaxSecondsIdle());

View file

@ -26,7 +26,7 @@ public enum SessionManager {
logger.trace("Session with sessionId " + sessionId + " is not found"); logger.trace("Session with sessionId " + sessionId + " is not found");
return Optional.empty(); return Optional.empty();
} }
if (session.getUserId() != null && UserManager.instance.getUser(session.getUserId()) == null) { if (session.getUserId() != null && !UserManager.instance.getUser(session.getUserId()).isPresent()) {
logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed."); logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed.");
// can happen if user from same host signs in multiple time with multiple clients, after he disconnects with one client // can happen if user from same host signs in multiple time with multiple clients, after he disconnects with one client
disconnect(sessionId, DisconnectReason.ConnectingOtherInstance); disconnect(sessionId, DisconnectReason.ConnectingOtherInstance);

View file

@ -942,7 +942,7 @@ public class TableController {
if (!(table.getState() == TableState.WAITING || table.getState() == TableState.STARTING || table.getState() == TableState.READY_TO_START)) { if (!(table.getState() == TableState.WAITING || table.getState() == TableState.STARTING || table.getState() == TableState.READY_TO_START)) {
if (match == null) { if (match == null) {
logger.warn("- Match table with no match:"); logger.warn("- Match table with no match:");
logger.warn("-- matchId:" + match.getId() + " [" + match.getName() + ']'); logger.warn("-- matchId:" + match.getId() + " , table : " + table.getId());
// return false; // return false;
} else if (match.isDoneSideboarding() && match.getGame() == null) { } else if (match.isDoneSideboarding() && match.getGame() == null) {
// no sideboarding and not active game -> match seems to hang (maybe the Draw bug) // no sideboarding and not active game -> match seems to hang (maybe the Draw bug)

View file

@ -266,13 +266,13 @@ public class GameController implements GameCallback {
public void join(UUID userId) { public void join(UUID userId) {
UUID playerId = userPlayerMap.get(userId); UUID playerId = userPlayerMap.get(userId);
Optional<User> user = UserManager.instance.getUser(userId); if (playerId == null) {
if (userId == null || playerId == null) {
logger.fatal("Join game failed!"); logger.fatal("Join game failed!");
logger.fatal("- gameId: " + game.getId()); logger.fatal("- gameId: " + game.getId());
logger.fatal("- userId: " + userId); logger.fatal("- userId: " + userId);
return; return;
} }
Optional<User> user = UserManager.instance.getUser(userId);
if (!user.isPresent()) { if (!user.isPresent()) {
logger.fatal("User not found : " + userId); logger.fatal("User not found : " + userId);
return; return;

View file

@ -3,14 +3,14 @@ package mage.server.game;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import mage.MageException; import mage.MageException;
import mage.game.Game; import mage.game.Game;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
*
* @author BetaSteward_at_googlemail.com
* @param <T> * @param <T>
* @author BetaSteward_at_googlemail.com
*/ */
public class GameWorker<T> implements Callable { public class GameWorker<T> implements Callable {
@ -40,13 +40,8 @@ public class GameWorker<T> implements Callable {
} catch (Exception e) { } catch (Exception e) {
LOGGER.fatal("GameWorker general exception [" + game.getId() + "] " + e.getMessage(), e); LOGGER.fatal("GameWorker general exception [" + game.getId() + "] " + e.getMessage(), e);
if (e instanceof NullPointerException) { if (e instanceof NullPointerException) {
if (e.getStackTrace() == null) {
LOGGER.info("Stack trace is null");
} else {
LOGGER.info("Null-Pointer-Exception: Stack trace");
LOGGER.info(e.getStackTrace()); LOGGER.info(e.getStackTrace());
} }
}
} catch (Error err) { } catch (Error err) {
LOGGER.fatal("GameWorker general error [" + game.getId() + "] " + err, err); LOGGER.fatal("GameWorker general error [" + game.getId() + "] " + err, err);
} }

View file

@ -408,7 +408,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.permanent.token." + command.cardName); Class<?> c = Class.forName("mage.game.permanent.token." + command.cardName);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object token = cons.newInstance(); Object token = cons.newInstance();
if (token != null && token instanceof mage.game.permanent.token.Token) { if (token instanceof mage.game.permanent.token.Token) {
((mage.game.permanent.token.Token) token).putOntoBattlefield(command.Amount, game, null, player.getId(), false, false); ((mage.game.permanent.token.Token) token).putOntoBattlefield(command.Amount, game, null, player.getId(), false, false);
continue; continue;
} }
@ -417,7 +417,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.command.emblems." + command.cardName); Class<?> c = Class.forName("mage.game.command.emblems." + command.cardName);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object emblem = cons.newInstance(); Object emblem = cons.newInstance();
if (emblem != null && emblem instanceof mage.game.command.Emblem) { if (emblem instanceof mage.game.command.Emblem) {
((mage.game.command.Emblem) emblem).setControllerId(player.getId()); ((mage.game.command.Emblem) emblem).setControllerId(player.getId());
game.addEmblem((mage.game.command.Emblem) emblem, null, player.getId()); game.addEmblem((mage.game.command.Emblem) emblem, null, player.getId());
continue; continue;
@ -427,7 +427,7 @@ public final class SystemUtil {
Class<?> c = Class.forName("mage.game.command.planes." + command.cardName); Class<?> c = Class.forName("mage.game.command.planes." + command.cardName);
Constructor<?> cons = c.getConstructor(); Constructor<?> cons = c.getConstructor();
Object plane = cons.newInstance(); Object plane = cons.newInstance();
if (plane != null && plane instanceof mage.game.command.Plane) { if (plane instanceof mage.game.command.Plane) {
((mage.game.command.Plane) plane).setControllerId(player.getId()); ((mage.game.command.Plane) plane).setControllerId(player.getId());
game.addPlane((mage.game.command.Plane) plane, null, player.getId()); game.addPlane((mage.game.command.Plane) plane, null, player.getId());
continue; continue;

View file

@ -0,0 +1,56 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.FightTargetSourceEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class AffectionateIndrik extends CardImpl {
private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("creature you don't control");
static {
filter.add(new ControllerPredicate(TargetController.NOT_YOU));
}
public AffectionateIndrik(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Affectionate Indrik enters the battlefield, you may have it fight target creature you don't control.
Ability ability = new EntersBattlefieldTriggeredAbility(
new FightTargetSourceEffect()
.setText("you may have it fight "
+ "target creature you don't control"),
true
);
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public AffectionateIndrik(final AffectionateIndrik card) {
super(card);
}
@Override
public AffectionateIndrik copy() {
return new AffectionateIndrik(this);
}
}

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
@ -38,7 +38,7 @@ public final class AjaniAdversaryOfTyrants extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Put a +1/+1 counter on each of up to two target creatures. // +1: Put a +1/+1 counter on each of up to two target creatures.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1); Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1);

View file

@ -4,7 +4,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount; import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
@ -34,7 +34,7 @@ public final class AjaniCallerOfThePride extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Put a +1/+1 counter on up to one target creature. // +1: Put a +1/+1 counter on up to one target creature.
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance());
effect.setText("Put a +1/+1 counter on up to one target creature"); effect.setText("Put a +1/+1 counter on up to one target creature");

View file

@ -4,7 +4,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
@ -22,7 +22,6 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token;
import mage.players.Player; import mage.players.Player;
/** /**
@ -36,7 +35,7 @@ public final class AjaniGoldmane extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: You gain 2 life. // +1: You gain 2 life.
this.addAbility(new LoyaltyAbility(new GainLifeEffect(2), 1)); this.addAbility(new LoyaltyAbility(new GainLifeEffect(2), 1));

View file

@ -4,7 +4,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.abilities.effects.common.counter.DistributeCountersEffect;
@ -46,7 +46,7 @@ public final class AjaniMentorOfHeroes extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Distribute three +1/+1 counters among one, two, or three target creatures you control // +1: Distribute three +1/+1 counters among one, two, or three target creatures you control
Ability ability = new LoyaltyAbility(new DistributeCountersEffect(CounterType.P1P1, 3, false, "one, two, or three target creatures you control"), 1); Ability ability = new LoyaltyAbility(new DistributeCountersEffect(CounterType.P1P1, 3, false, "one, two, or three target creatures you control"), 1);

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect;
@ -45,7 +45,7 @@ public final class AjaniSteadfast extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Until end of turn, up to one target creature gets +1/+1 and gains first strike, vigilance, and lifelink. // +1: Until end of turn, up to one target creature gets +1/+1 and gains first strike, vigilance, and lifelink.
Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn);

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.common.ExileAndGainLifeEqualPowerTargetEffect; import mage.abilities.effects.common.ExileAndGainLifeEqualPowerTargetEffect;
import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect;
@ -43,7 +43,7 @@ public final class AjaniUnyielding extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +2: Reveal the top three cards of your library. Put all nonland permanent cards revealed this way into your hand and the rest on the bottom of your library in any order. // +2: Reveal the top three cards of your library. Put all nonland permanent cards revealed this way into your hand and the rest on the bottom of your library in any order.
this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(3, nonlandPermanentFilter, Zone.LIBRARY), 2)); this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(3, nonlandPermanentFilter, Zone.LIBRARY), 2));

View file

@ -4,7 +4,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount; import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect; import mage.abilities.effects.common.RevealCardsFromLibraryUntilEffect;
@ -33,7 +33,7 @@ public final class AjaniValiantProtector extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +2: Put two +1/+1 counters on up to one target creature. // +2: Put two +1/+1 counters on up to one target creature.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2); Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2);

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyAllControlledTargetEffect; import mage.abilities.effects.common.DestroyAllControlledTargetEffect;
@ -37,7 +37,7 @@ public final class AjaniVengeant extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +1: Target permanent doesn't untap during its controller's next untap step. // +1: Target permanent doesn't untap during its controller's next untap step.
LoyaltyAbility ability1 = new LoyaltyAbility(new DontUntapInControllersNextUntapStepTargetEffect(), 1); LoyaltyAbility ability1 = new LoyaltyAbility(new DontUntapInControllersNextUntapStepTargetEffect(), 1);

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.ControllerLifeCount; import mage.abilities.dynamicvalue.common.ControllerLifeCount;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GainLifeEffect;
@ -29,7 +29,7 @@ public final class AjaniWiseCounselor extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AJANI); this.subtype.add(SubType.AJANI);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +2: You gain 1 life for each creature you control. // +2: You gain 1 life for each creature you control.
this.addAbility(new LoyaltyAbility(new GainLifeEffect( this.addAbility(new LoyaltyAbility(new GainLifeEffect(

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID; import java.util.UUID;
@ -14,12 +13,12 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.target.targetadjustment.XTargetsAdjuster;
/** /**
* *
@ -40,7 +39,7 @@ public final class AlexiZephyrMage extends CardImpl {
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards")))); ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, new FilterCard("two cards"))));
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURES)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURES));
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS); ability.setTargetAdjuster(XTargetsAdjuster.instance);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.ExileTargetForSourceEffect;
@ -48,7 +48,7 @@ public class AminatouTheFateShifter extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.AMINATOU); this.subtype.add(SubType.AMINATOU);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +1: Draw a card, then put a card from your hand on top of your library. // +1: Draw a card, then put a card from your hand on top of your library.
Ability ability = new LoyaltyAbility(new AminatouPlusEffect(), +1); Ability ability = new LoyaltyAbility(new AminatouPlusEffect(), +1);

View file

@ -62,7 +62,7 @@ class AnZerrinRuinsDontUntapEffect extends DontUntapInControllersUntapStepAllEff
if (super.applies(event, source, game)) { if (super.applies(event, source, game)) {
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) { if (permanent != null) {
if (permanent.hasSubtype(ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game), game)) { if (permanent.hasSubtype(ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game), game)) {
return true; return true;
} }
} }

View file

@ -4,7 +4,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@ -39,7 +39,7 @@ public final class AngrathMinotaurPirate extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH); this.subtype.add(SubType.ANGRATH);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +2: Angrath, Minotaur Pirate deals 1 damage to target opponent and each creature that player controls. // +2: Angrath, Minotaur Pirate deals 1 damage to target opponent and each creature that player controls.
Effects effects1 = new Effects(); Effects effects1 = new Effects();

View file

@ -5,7 +5,7 @@ import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.LoseLifeOpponentsEffect;
@ -41,7 +41,7 @@ public final class AngrathTheFlameChained extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH); this.subtype.add(SubType.ANGRATH);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Each opponent discards a card and loses 2 life. // +1: Each opponent discards a card and loses 2 life.
LoyaltyAbility ability = new LoyaltyAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT), 1); LoyaltyAbility ability = new LoyaltyAbility(new DiscardEachPlayerEffect(TargetController.OPPONENT), 1);

View file

@ -0,0 +1,40 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.ConvokeAbility;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class ArboretumElemental extends CardImpl {
public ArboretumElemental(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{7}{G}{G}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(7);
this.toughness = new MageInt(5);
// Convoke
this.addAbility(new ConvokeAbility());
// Hexproof
this.addAbility(HexproofAbility.getInstance());
}
public ArboretumElemental(final ArboretumElemental card) {
super(card);
}
@Override
public ArboretumElemental copy() {
return new ArboretumElemental(this);
}
}

View file

@ -64,7 +64,7 @@ class ConspyEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (controller != null && subType != null) { if (controller != null && subType != null) {
// Creature cards you own that aren't on the battlefield // Creature cards you own that aren't on the battlefield
// in graveyard // in graveyard

View file

@ -1,9 +1,6 @@
package mage.cards.a; package mage.cards.a;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -15,24 +12,27 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.constants.SubType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class ArcaneArtisan extends CardImpl { public final class ArcaneArtisan extends CardImpl {
@ -46,10 +46,14 @@ public final class ArcaneArtisan extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// {2}{U}, {T}: Target player draws a card, then exiles a card from their hand. If a creature card is exiled this way, that player creates a token that's a copy of that card. // {2}{U}, {T}: Target player draws a card, then exiles a card from their hand. If a creature card is exiled this way, that player creates a token that's a copy of that card.
Ability ability = new SimpleActivatedAbility(new ArcaneArtisanCreateTokenEffect(), new ManaCostsImpl("{2}{U}")); Ability ability = new SimpleActivatedAbility(
new ArcaneArtisanCreateTokenEffect(),
new ManaCostsImpl("{2}{U}")
);
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
// When Arcane Artisan leaves the battlefield, exile all tokens created with it at the beginning of the next end step. // When Arcane Artisan leaves the battlefield, exile all tokens created with it at the beginning of the next end step.
this.addAbility(new ArcaneArtisanLeavesBattlefieldTriggeredAbility()); this.addAbility(new ArcaneArtisanLeavesBattlefieldTriggeredAbility());
} }
@ -66,13 +70,13 @@ public final class ArcaneArtisan extends CardImpl {
class ArcaneArtisanCreateTokenEffect extends OneShotEffect { class ArcaneArtisanCreateTokenEffect extends OneShotEffect {
ArcaneArtisanCreateTokenEffect() { public ArcaneArtisanCreateTokenEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "Target player draws a card, then exiles a card from their hand. " this.staticText = "Target player draws a card, then exiles a card from their hand. "
+ "If a creature card is exiled this way, that player creates a token that's a copy of that card."; + "If a creature card is exiled this way, that player creates a token that's a copy of that card.";
} }
ArcaneArtisanCreateTokenEffect(final ArcaneArtisanCreateTokenEffect effect) { public ArcaneArtisanCreateTokenEffect(final ArcaneArtisanCreateTokenEffect effect) {
super(effect); super(effect);
} }
@ -88,8 +92,8 @@ class ArcaneArtisanCreateTokenEffect extends OneShotEffect {
return false; return false;
} }
player.drawCards(1, game); player.drawCards(1, game);
Target target = new TargetCardInHand(1, new FilterCard()); TargetCard target = new TargetCardInHand(1, StaticFilters.FILTER_CARD);
if (!player.chooseTarget(Outcome.Exile, target, source, game)) { if (!player.chooseTarget(Outcome.Exile, player.getHand(), target, source, game)) {
return false; return false;
} }
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
@ -119,14 +123,14 @@ class ArcaneArtisanCreateTokenEffect extends OneShotEffect {
class ArcaneArtisanLeavesBattlefieldTriggeredAbility extends ZoneChangeTriggeredAbility { class ArcaneArtisanLeavesBattlefieldTriggeredAbility extends ZoneChangeTriggeredAbility {
ArcaneArtisanLeavesBattlefieldTriggeredAbility() { public ArcaneArtisanLeavesBattlefieldTriggeredAbility() {
super(Zone.BATTLEFIELD, null, super(Zone.BATTLEFIELD, null,
new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ArcaneArtisanExileEffect())), new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ArcaneArtisanExileEffect())),
"", false "", false
); );
} }
ArcaneArtisanLeavesBattlefieldTriggeredAbility(ArcaneArtisanLeavesBattlefieldTriggeredAbility ability) { public ArcaneArtisanLeavesBattlefieldTriggeredAbility(ArcaneArtisanLeavesBattlefieldTriggeredAbility ability) {
super(ability); super(ability);
} }
@ -143,12 +147,12 @@ class ArcaneArtisanLeavesBattlefieldTriggeredAbility extends ZoneChangeTriggered
class ArcaneArtisanExileEffect extends OneShotEffect { class ArcaneArtisanExileEffect extends OneShotEffect {
ArcaneArtisanExileEffect() { public ArcaneArtisanExileEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "exile all tokens created with {this}."; this.staticText = "exile all tokens created with {this}.";
} }
ArcaneArtisanExileEffect(final ArcaneArtisanExileEffect effect) { public ArcaneArtisanExileEffect(final ArcaneArtisanExileEffect effect) {
super(effect); super(effect);
} }

View file

@ -0,0 +1,123 @@
package mage.cards.a;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.watchers.Watcher;
/**
*
* @author TheElk801
*/
public final class ArclightPhoenix extends CardImpl {
public ArclightPhoenix(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.PHOENIX);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// At the beginning of combat on your turn, if you cast 3 or more instants and/or sorceries this turn, you may return Arclight Phoenix from your graveyard to the battlefield.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new BeginningOfCombatTriggeredAbility(
Zone.GRAVEYARD,
new ReturnSourceFromGraveyardToBattlefieldEffect(),
TargetController.YOU, true, false
), ArclightPhoenixCondition.instance,
"At the beginning of combat on your turn, "
+ "if you've cast three or more instant "
+ "and sorcery spells this turn, you may return {this} "
+ "from your graveyard to the battlefield."
), new ArclightPhoenixWatcher());
}
public ArclightPhoenix(final ArclightPhoenix card) {
super(card);
}
@Override
public ArclightPhoenix copy() {
return new ArclightPhoenix(this);
}
}
enum ArclightPhoenixCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
ArclightPhoenixWatcher watcher
= (ArclightPhoenixWatcher) game.getState().getWatchers().get(
ArclightPhoenixWatcher.class.getSimpleName()
);
return watcher != null && watcher.getInstantSorceryCount(source.getControllerId()) > 2;
}
}
class ArclightPhoenixWatcher extends Watcher {
private final Map<UUID, Integer> instantSorceryCount = new HashMap();
public ArclightPhoenixWatcher() {
super(ArclightPhoenixWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public ArclightPhoenixWatcher(final ArclightPhoenixWatcher watcher) {
super(watcher);
this.instantSorceryCount.putAll(watcher.instantSorceryCount);
}
@Override
public ArclightPhoenixWatcher copy() {
return new ArclightPhoenixWatcher(this);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell == null || !spell.isInstantOrSorcery()) {
return;
}
this.instantSorceryCount.putIfAbsent(spell.getControllerId(), 0);
this.instantSorceryCount.compute(
spell.getControllerId(), (k, a) -> a + 1
);
}
}
@Override
public void reset() {
super.reset();
this.instantSorceryCount.clear();
}
public int getInstantSorceryCount(UUID playerId) {
return this.instantSorceryCount.getOrDefault(playerId, 0);
}
}

View file

@ -3,7 +3,7 @@ package mage.cards.a;
import java.util.UUID; import java.util.UUID;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.TransformSourceEffect;
@ -35,7 +35,7 @@ public final class ArlinnKord extends CardImpl {
this.transformable = true; this.transformable = true;
this.secondSideCardClazz = ArlinnEmbracedByTheMoon.class; this.secondSideCardClazz = ArlinnEmbracedByTheMoon.class;
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +1: Until end of turn, up to one target creature gets +2/+2 and gains vigilance and haste. // +1: Until end of turn, up to one target creature gets +2/+2 and gains vigilance and haste.
Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn);

View file

@ -0,0 +1,55 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class ArtfulTakedown extends CardImpl {
private static final FilterCreaturePermanent filter1
= new FilterCreaturePermanent("creature (to tap)");
private static final FilterCreaturePermanent filter2
= new FilterCreaturePermanent("creature (to shrink)");
public ArtfulTakedown(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{B}");
// Choose one or both
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(2);
// Tap target creature.
this.getSpellAbility().addEffect(
new TapTargetEffect().setText("target creature")
);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter1));
// Target creature gets -2/-4 until end of turn.
Mode mode = new Mode(
new BoostTargetEffect(-2, -4, Duration.EndOfTurn)
.setText("target creature gets -2/-4 until end of turn")
);
mode.addTarget(new TargetCreaturePermanent(filter2));
this.getSpellAbility().addMode(mode);
}
public ArtfulTakedown(final ArtfulTakedown card) {
super(card);
}
@Override
public ArtfulTakedown copy() {
return new ArtfulTakedown(this);
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID; import java.util.UUID;
@ -6,6 +5,7 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.VariableCostImpl; import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.TapTargetCost; import mage.abilities.costs.common.TapTargetCost;
@ -16,17 +16,21 @@ import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.TappedPredicate; import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.KnightToken; import mage.game.permanent.token.KnightToken;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetadjustment.TargetAdjuster;
/** /**
* *
@ -57,9 +61,8 @@ public final class AryelKnightOfWindgrace extends CardImpl {
.setText("Destroy target creature with power X or less"), new ManaCostsImpl("{B}")); .setText("Destroy target creature with power X or less"), new ManaCostsImpl("{B}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addCost(new AryelTapXTargetCost()); ability.addCost(new AryelTapXTargetCost());
ability.setTargetAdjustment(TargetAdjustment.CREATURE_POWER_X_OR_LESS); ability.setTargetAdjuster(AryelKnightOfWindgraceAdjuster.instance);
this.addAbility(ability); this.addAbility(ability);
ability.getOriginalId();
} }
public AryelKnightOfWindgrace(final AryelKnightOfWindgrace card) { public AryelKnightOfWindgrace(final AryelKnightOfWindgrace card) {
@ -106,3 +109,19 @@ class AryelTapXTargetCost extends VariableCostImpl {
return new TapTargetCost(target); return new TapTargetCost(target);
} }
} }
enum AryelKnightOfWindgraceAdjuster implements TargetAdjuster {
instance;
@Override
public void adjustTargets(Ability ability, Game game) {
int value = 0;
for (VariableCost cost : ability.getCosts().getVariableCosts()) {
value = cost.getAmount();
}
FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent("creature with power " + value + " or less");
filterCreaturePermanent.add(new PowerPredicate(ComparisonType.FEWER_THAN, value + 1));
ability.getTargets().clear();
ability.addTarget(new TargetCreaturePermanent(filterCreaturePermanent));
}
}

View file

@ -57,7 +57,7 @@ class AshesOfTheFallenEffect extends ContinuousEffectImpl {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) { if (controller != null && permanent != null) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(permanent.getId(), game); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(permanent.getId(), game);
if (subType != null) { if (subType != null) {
for (UUID cardId : controller.getGraveyard()) { for (UUID cardId : controller.getGraveyard()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);

View file

@ -5,7 +5,7 @@ import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
@ -35,7 +35,7 @@ public final class AshiokNightmareWeaver extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ASHIOK); this.subtype.add(SubType.ASHIOK);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +2: Exile the top three cards of target opponent's library. // +2: Exile the top three cards of target opponent's library.
LoyaltyAbility ability = new LoyaltyAbility(new AshiokNightmareWeaverExileEffect(), 2); LoyaltyAbility ability = new LoyaltyAbility(new AshiokNightmareWeaverExileEffect(), 2);

View file

@ -0,0 +1,91 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author TheElk801
*/
public final class AssassinsTrophy extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanent an opponent controls");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
}
public AssassinsTrophy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{G}");
// Destroy target permanent an opponent controls. Its controller may search their library for a basic land card, put it onto the battlefield, then shuffle their library.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addEffect(new AssassinsTrophyEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
}
public AssassinsTrophy(final AssassinsTrophy card) {
super(card);
}
@Override
public AssassinsTrophy copy() {
return new AssassinsTrophy(this);
}
}
class AssassinsTrophyEffect extends OneShotEffect {
public AssassinsTrophyEffect() {
super(Outcome.PutLandInPlay);
this.staticText = "Its controller may search their library "
+ "for a basic land card, put it onto the battlefield, "
+ "then shuffle their library";
}
public AssassinsTrophyEffect(final AssassinsTrophyEffect effect) {
super(effect);
}
@Override
public AssassinsTrophyEffect copy() {
return new AssassinsTrophyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
if (permanent != null) {
Player controller = game.getPlayer(permanent.getControllerId());
if (controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND);
if (controller.searchLibrary(target, game)) {
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
if (card != null) {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
}
controller.shuffleLibrary(source, game);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardSetInfo;
import mage.cards.SplitCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SpellAbilityType;
import mage.counters.CounterType;
import mage.game.permanent.token.ElfKnightToken;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class AssureAssemble extends SplitCard {
public AssureAssemble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G/W}{G/W}", "{4}{G}{W}", SpellAbilityType.SPLIT);
// Assure
// Put a +1/+1 counter on target creature. It gains indestructible until end of turn.
this.getLeftHalfCard().getSpellAbility().addEffect(
new AddCountersTargetEffect(CounterType.P1P1.createInstance())
);
this.getLeftHalfCard().getSpellAbility().addEffect(
new GainAbilityTargetEffect(
IndestructibleAbility.getInstance(),
Duration.EndOfTurn
).setText("It gains indestructible until end of turn.")
);
this.getLeftHalfCard().getSpellAbility().addTarget(
new TargetCreaturePermanent()
);
// Assemble
// Create three 2/2 green and white Elf Knight creature tokens with vigilance.
this.getRightHalfCard().getSpellAbility().addEffect(
new CreateTokenEffect(new ElfKnightToken(), 3)
);
}
public AssureAssemble(final AssureAssemble card) {
super(card);
}
@Override
public AssureAssemble copy() {
return new AssureAssemble(this);
}
}

View file

@ -0,0 +1,61 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount;
import mage.abilities.effects.common.GainLifeEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
/**
*
* @author TheElk801
*/
public final class AttendantOfVraska extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("a Vraska planeswalker");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(new CardTypePredicate(CardType.PLANESWALKER));
filter.add(new SubtypePredicate(SubType.VRASKA));
}
public AttendantOfVraska(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When Attendant of Vraska dies, if you control a Vraska planeswalker, you gain life equal to Attendant of Vraska's power.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new DiesTriggeredAbility(new GainLifeEffect(
new SourcePermanentPowerCount()
), false), new PermanentsOnTheBattlefieldCondition(filter),
"When {this} dies, if you control a Vraska planeswalker, "
+ "you gain life equal to {this}'s power."
));
}
public AttendantOfVraska(final AttendantOfVraska card) {
super(card);
}
@Override
public AttendantOfVraska copy() {
return new AttendantOfVraska(this);
}
}

View file

@ -0,0 +1,103 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.MentorAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class AureliaExemplarOfJustice extends CardImpl {
public AureliaExemplarOfJustice(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGEL);
this.power = new MageInt(2);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Mentor
this.addAbility(new MentorAbility());
// At the beginning of combat on your turn, choose up to one target creature you control. Until end of turn, that creature gets +2/+0, gains trample if it's red, and gains vigilance if it's white.
Ability ability = new BeginningOfCombatTriggeredAbility(
new AureliaExemplarOfJusticeEffect(),
TargetController.YOU, false
);
ability.addTarget(new TargetControlledCreaturePermanent(0, 1));
this.addAbility(ability);
}
public AureliaExemplarOfJustice(final AureliaExemplarOfJustice card) {
super(card);
}
@Override
public AureliaExemplarOfJustice copy() {
return new AureliaExemplarOfJustice(this);
}
}
class AureliaExemplarOfJusticeEffect extends OneShotEffect {
public AureliaExemplarOfJusticeEffect() {
super(Outcome.Benefit);
this.staticText = "choose up to one target creature you control. "
+ "Until end of turn, that creature gets +2/+0, "
+ "gains trample if it's red, "
+ "and gains vigilance if it's white.";
}
public AureliaExemplarOfJusticeEffect(final AureliaExemplarOfJusticeEffect effect) {
super(effect);
}
@Override
public AureliaExemplarOfJusticeEffect copy() {
return new AureliaExemplarOfJusticeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature == null) {
return false;
}
game.addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn), source);
if (creature.getColor(game).isRed()) {
game.addEffect(new GainAbilityTargetEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn
), source);
}
if (creature.getColor(game).isWhite()) {
game.addEffect(new GainAbilityTargetEffect(
VigilanceAbility.getInstance(), Duration.EndOfTurn
), source);
}
return true;
}
}

View file

@ -5,7 +5,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageControllerEffect; import mage.abilities.effects.common.DamageControllerEffect;
@ -37,7 +37,7 @@ public final class AurraSingBaneOfJedi extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{B}{R}"); super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{B}{R}");
this.subtype.add(SubType.AURRA); this.subtype.add(SubType.AURRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +1:You may have {this} deal 2 damage to target creature. If you don't, {this} deals 1 damage to you. // +1:You may have {this} deal 2 damage to target creature. If you don't, {this} deals 1 damage to you.
Ability ability = new LoyaltyAbility(new AurraSingBaneOfJediEffect(), +1); Ability ability = new LoyaltyAbility(new AurraSingBaneOfJediEffect(), +1);

View file

@ -0,0 +1,41 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.MentorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BargingSergeant extends CardImpl {
public BargingSergeant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.subtype.add(SubType.MINOTAUR);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// Haste
this.addAbility(HasteAbility.getInstance());
// Mentor
this.addAbility(new MentorAbility());
}
public BargingSergeant(final BargingSergeant card) {
super(card);
}
@Override
public BargingSergeant copy() {
return new BargingSergeant(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BarrierOfBones extends CardImpl {
public BarrierOfBones(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.SKELETON);
this.subtype.add(SubType.WALL);
this.power = new MageInt(0);
this.toughness = new MageInt(3);
// Defender
this.addAbility(DefenderAbility.getInstance());
// When Barrier of Bones enters the battlefield, surveil 1.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SurveilEffect(1), false
));
}
public BarrierOfBones(final BarrierOfBones card) {
super(card);
}
@Override
public BarrierOfBones copy() {
return new BarrierOfBones(this);
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BartizanBats extends CardImpl {
public BartizanBats(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.BAT);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
}
public BartizanBats(final BartizanBats card) {
super(card);
}
@Override
public BartizanBats copy() {
return new BartizanBats(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.InstantSorceryExileGraveyardCount;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.JumpStartAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author TheElk801
*/
public final class BeaconBolt extends CardImpl {
public BeaconBolt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{R}");
// Beacon Bolt deals damage to target creature equal to the total number of instant and sorcery cards you own in exile and in your graveyard.
this.getSpellAbility().addEffect(new DamageTargetEffect(
InstantSorceryExileGraveyardCount.instance
).setText("{this} deals damage to target creature equal to "
+ "the total number of instant and sorcery cards "
+ "you own in exile and in your graveyard"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Jump-start
this.addAbility(new JumpStartAbility(this));
}
public BeaconBolt(final BeaconBolt card) {
super(card);
}
@Override
public BeaconBolt copy() {
return new BeaconBolt(this);
}
}

View file

@ -0,0 +1,226 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author TheElk801
*/
public final class BeamsplitterMage extends CardImpl {
public BeamsplitterMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{R}");
this.subtype.add(SubType.VEDALKEN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever you cast an instant or sorcery spell that targets only Beamsplitter Mage, if you control one or more creatures that spell could target, choose one of those creatures. Copy that spell. The copy targets the chosen creature.
this.addAbility(new BeamsplitterMageTriggeredAbility());
}
public BeamsplitterMage(final BeamsplitterMage card) {
super(card);
}
@Override
public BeamsplitterMage copy() {
return new BeamsplitterMage(this);
}
}
class BeamsplitterMageTriggeredAbility extends TriggeredAbilityImpl {
public BeamsplitterMageTriggeredAbility() {
super(Zone.BATTLEFIELD, new BeamsplitterMageEffect(), false);
}
public BeamsplitterMageTriggeredAbility(final BeamsplitterMageTriggeredAbility ability) {
super(ability);
}
@Override
public BeamsplitterMageTriggeredAbility copy() {
return new BeamsplitterMageTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getPlayerId().equals(this.getControllerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (!isControlledInstantOrSorcery(spell)) {
return false;
}
boolean targetsSource = false;
for (Ability ability : spell.getSpellAbilities()) {
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (!target.isNotTarget()) {
for (UUID targetId : target.getTargets()) {
if (targetId.equals(getSourceId())) {
targetsSource = true;
} else {
return false;
}
}
}
}
}
}
if (targetsSource) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId()));
return true;
}
}
return false;
}
private boolean isControlledInstantOrSorcery(Spell spell) {
return spell != null
&& (spell.isControlledBy(this.getControllerId()))
&& (spell.isInstant() || spell.isSorcery());
}
@Override
public String getRule() {
return "Whenever you cast an instant or sorcery spell that targets "
+ "only {this}, if you control one or more creatures "
+ "that spell could target, choose one of those creatures. "
+ "Copy that spell. The copy targets the chosen creature.";
}
}
class BeamsplitterMageEffect extends OneShotEffect {
public BeamsplitterMageEffect() {
super(Outcome.Detriment);
}
public BeamsplitterMageEffect(final BeamsplitterMageEffect effect) {
super(effect);
}
@Override
public BeamsplitterMageEffect copy() {
return new BeamsplitterMageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (spell != null && controller != null) {
// search the target that targets source
Target usedTarget = null;
setUsedTarget:
for (Ability ability : spell.getSpellAbilities()) {
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (!target.isNotTarget() && target.getFirstTarget().equals(source.getSourceId())) {
usedTarget = target.copy();
usedTarget.clearChosen();
break setUsedTarget;
}
}
}
}
if (usedTarget == null) {
return false;
}
FilterPermanent filter = new BeamsplitterMageFilter(usedTarget, source.getSourceId());
Target target1 = new TargetPermanent(filter);
target1.setNotTarget(true);
if (controller.choose(outcome, target1, source.getSourceId(), game)) {
Permanent creature = game.getPermanent(target1.getFirstTarget());
if (creature == null) {
return false;
}
Spell copy = spell.copySpell(source.getControllerId());
game.getStack().push(copy);
setTarget:
for (UUID modeId : copy.getSpellAbility().getModes().getSelectedModes()) {
Mode mode = copy.getSpellAbility().getModes().get(modeId);
for (Target target : mode.getTargets()) {
if (target.getClass().equals(usedTarget.getClass())) {
target.clearChosen(); // For targets with Max > 1 we need to clear before the text is comapred
if (target.getMessage().equals(usedTarget.getMessage())) {
target.addTarget(creature.getId(), copy.getSpellAbility(), game, false);
break setTarget;
}
}
}
}
game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, copy.getId(), spell.getId(), source.getControllerId()));
String activateMessage = copy.getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6);
}
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + activateMessage);
}
}
return true;
}
return false;
}
}
class BeamsplitterMageFilter extends FilterControlledPermanent {
private final Target target;
private final UUID notId;
public BeamsplitterMageFilter(Target target, UUID notId) {
super("creature this spell could target");
this.target = target;
this.notId = notId;
}
public BeamsplitterMageFilter(final BeamsplitterMageFilter filter) {
super(filter);
this.target = filter.target;
this.notId = filter.notId;
}
@Override
public BeamsplitterMageFilter copy() {
return new BeamsplitterMageFilter(this);
}
@Override
public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
return super.match(permanent, game)
&& permanent.isCreature()
&& !permanent.getId().equals(notId)
&& target.canTarget(permanent.getId(), game);
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
/**
*
* @author TheElk801
*/
public final class BeastWhisperer extends CardImpl {
public BeastWhisperer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}");
this.subtype.add(SubType.ELF);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever you cast a creature spell, draw a card.
this.addAbility(new SpellCastControllerTriggeredAbility(
new DrawCardSourceControllerEffect(1),
StaticFilters.FILTER_SPELL_A_CREATURE, false
));
}
public BeastWhisperer(final BeastWhisperer card) {
super(card);
}
@Override
public BeastWhisperer copy() {
return new BeastWhisperer(this);
}
}

View file

@ -171,7 +171,7 @@ class BerserkDelayedDestroyEffect extends OneShotEffect {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) { if (permanent != null) {
Watcher watcher = game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName()); Watcher watcher = game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName());
if (watcher != null && watcher instanceof AttackedThisTurnWatcher) { if (watcher instanceof AttackedThisTurnWatcher) {
if (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) { if (((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures().contains(new MageObjectReference(permanent, game))) {
return permanent.destroy(source.getSourceId(), game, false); return permanent.destroy(source.getSourceId(), game, false);
} }

View file

@ -0,0 +1,39 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.keyword.MentorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
* @author jmharmon
*/
public final class BladeInstructor extends CardImpl {
public BladeInstructor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// Mentor
this.addAbility(new MentorAbility());
}
public BladeInstructor(final BladeInstructor card) {
super(card);
}
@Override
public BladeInstructor copy() {
return new BladeInstructor(this);
}
}

View file

@ -1,9 +1,7 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -13,12 +11,8 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
/** /**
@ -28,7 +22,7 @@ import mage.game.permanent.Permanent;
public final class BladeOfTheBloodchief extends CardImpl { public final class BladeOfTheBloodchief extends CardImpl {
public BladeOfTheBloodchief(UUID ownerId, CardSetInfo setInfo) { public BladeOfTheBloodchief(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// Whenever a creature dies, put a +1/+1 counter on equipped creature. If equipped creature is a Vampire, put two +1/+1 counters on it instead. // Whenever a creature dies, put a +1/+1 counter on equipped creature. If equipped creature is a Vampire, put two +1/+1 counters on it instead.
@ -50,11 +44,14 @@ public final class BladeOfTheBloodchief extends CardImpl {
class BladeOfTheBloodchiefEffect extends OneShotEffect { class BladeOfTheBloodchiefEffect extends OneShotEffect {
BladeOfTheBloodchiefEffect() { public BladeOfTheBloodchiefEffect() {
super(Outcome.BoostCreature); super(Outcome.BoostCreature);
staticText = "put a +1/+1 counter on equipped creature. "
+ "If equipped creature is a Vampire, "
+ "put two +1/+1 counters on it instead.";
} }
BladeOfTheBloodchiefEffect(final BladeOfTheBloodchiefEffect ability) { public BladeOfTheBloodchiefEffect(final BladeOfTheBloodchiefEffect ability) {
super(ability); super(ability);
} }

View file

@ -0,0 +1,97 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
/**
*
* @author LevelX2
*/
public final class BloodOperative extends CardImpl {
public BloodOperative(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.ASSASSIN);
this.power = new MageInt(3);
this.toughness = new MageInt(1);
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// When Blood Operative enters the battlefield, you may exile target card from a graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect(), true);
ability.addTarget(new TargetCardInGraveyard());
this.addAbility(ability);
// Whenever you surveil, if Blood Operative is in your graveyard, you may pay 3 life. If you do, return Blood Operative to your hand.
this.addAbility(new BloodOperativeTriggeredAbility());
}
public BloodOperative(final BloodOperative card) {
super(card);
}
@Override
public BloodOperative copy() {
return new BloodOperative(this);
}
}
class BloodOperativeTriggeredAbility extends TriggeredAbilityImpl {
public BloodOperativeTriggeredAbility() {
super(Zone.GRAVEYARD, new DoIfCostPaid(new ReturnSourceFromGraveyardToHandEffect(), new PayLifeCost(3)), false);
}
public BloodOperativeTriggeredAbility(final BloodOperativeTriggeredAbility ability) {
super(ability);
}
@Override
public BloodOperativeTriggeredAbility copy() {
return new BloodOperativeTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SURVEILED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(getControllerId());
}
@Override
public boolean checkInterveningIfClause(Game game) {
Player controller = game.getPlayer(getControllerId());
if (controller != null && controller.getGraveyard().contains(getSourceId())) {
return super.checkInterveningIfClause(game);
}
return false;
}
@Override
public String getRule() {
return "Whenever you surveil, if {this} is in your graveyard, you may pay 3 life. If you do, return {this} to your hand.";
}
}

View file

@ -55,7 +55,7 @@ public final class BlowflyInfestation extends CardImpl {
class BlowflyInfestationCondition implements Condition { class BlowflyInfestationCondition implements Condition {
private static Permanent permanent; private Permanent permanent;
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {

View file

@ -0,0 +1,45 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.common.discard.DiscardHandDrawSameNumberSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BookDevourer extends CardImpl {
public BookDevourer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Book Devourer deals combat damage to a player, you may discard all the cards in your hand. If you do, draw that many cards.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new DiscardHandDrawSameNumberSourceEffect()
.setText("discard all the cards in your hand. "
+ "If you do, draw that many cards"), true
));
}
public BookDevourer(final BookDevourer card) {
super(card);
}
@Override
public BookDevourer copy() {
return new BookDevourer(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.MentorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public final class BorosChallenger extends CardImpl {
public BorosChallenger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Mentor
this.addAbility(new MentorAbility());
// {2}{R}{W}: Boros Challenger gets +1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new BoostSourceEffect(1, 1, Duration.EndOfTurn),
new ManaCostsImpl("{2}{R}{W}")
));
}
public BorosChallenger(final BorosChallenger card) {
super(card);
}
@Override
public BorosChallenger copy() {
return new BorosChallenger(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author TheElk801
*/
public final class BorosLocket extends CardImpl {
public BorosLocket(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {T}: Add {R} or {W}.
this.addAbility(new RedManaAbility());
this.addAbility(new WhiteManaAbility());
// {R/W}{R/W}{R/W}{R/W}, {T}, Sacrifice Boros Locket: Draw two cards.
Ability ability = new SimpleActivatedAbility(
new DrawCardSourceControllerEffect(2),
new ManaCostsImpl("{R/W}{R/W}{R/W}{R/W}")
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
public BorosLocket(final BorosLocket card) {
super(card);
}
@Override
public BorosLocket copy() {
return new BorosLocket(this);
}
}

View file

@ -0,0 +1,70 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.constants.SubType;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.target.TargetPermanent;
/**
*
* @author TheElk801
*/
public final class BountyAgent extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("legendary permanent that's an artifact, creature, or enchantment");
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.ENCHANTMENT)
));
}
public BountyAgent(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// {T}, Sacrifice Bounty Agent: Destroy target legendary permanent that's an artifact, creature, or enchantment.
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new DestroyTargetEffect(),
new TapSourceCost()
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
public BountyAgent(final BountyAgent card) {
super(card);
}
@Override
public BountyAgent copy() {
return new BountyAgent(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import mage.target.targetpointer.ThirdTargetPointer;
/**
*
* @author Ryan-Saklad
*/
public final class BountyOfMight extends CardImpl {
public BountyOfMight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{G}{G}");
// Target creature gets +3/+3 until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(3, 3, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (1st)")));
// Target creature gets +3/+3 until end of turn.
Effect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn).setText("<br>Target creature gets +3/+3 until end of turn.");
effect.setTargetPointer(new SecondTargetPointer());
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (2nd)")));
// Target creature gets +3/+3 until end of turn.
effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn).setText("<br>Target creature gets +3/+3 until end of turn.");
effect.setTargetPointer(new ThirdTargetPointer());
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (3rd)")));
}
public BountyOfMight(final BountyOfMight card) {
super(card);
}
@Override
public BountyOfMight copy() {
return new BountyOfMight(this);
}
}

View file

@ -55,7 +55,7 @@ class BroodingSaurianControlEffect extends ContinuousEffectImpl {
public BroodingSaurianControlEffect() { public BroodingSaurianControlEffect() {
super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.staticText = "each player gains control of all nontoken permanents he or she owns"; this.staticText = "each player gains control of all nontoken permanents they own";
} }
public BroodingSaurianControlEffect(final BroodingSaurianControlEffect effect) { public BroodingSaurianControlEffect(final BroodingSaurianControlEffect effect) {

View file

@ -1,6 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility; import mage.abilities.common.BeginningOfCombatTriggeredAbility;
@ -11,13 +10,7 @@ import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TokenPredicate; import mage.filter.predicate.permanent.TokenPredicate;
@ -28,8 +21,9 @@ import mage.players.Player;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyApplyToPermanent;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class BrudicladTelchorEngineer extends CardImpl { public final class BrudicladTelchorEngineer extends CardImpl {
@ -52,7 +46,7 @@ public final class BrudicladTelchorEngineer extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true)));
// At the beginning of combat on your turn, create a 2/1 blue Myr artifact creature token. Then you may choose a token you control. If you do, each other token you control becomes a copy of that token. // At the beginning of combat on your turn, create a 2/1 blue Myr artifact creature token. Then you may choose a token you control. If you do, each other token you control becomes a copy of that token.
this.addAbility(new BeginningOfCombatTriggeredAbility(new BrudicladTelchorCombatffect(), TargetController.YOU, false)); this.addAbility(new BeginningOfCombatTriggeredAbility(new BrudicladTelchorEngineerEffect(), TargetController.YOU, false));
} }
public BrudicladTelchorEngineer(final BrudicladTelchorEngineer card) { public BrudicladTelchorEngineer(final BrudicladTelchorEngineer card) {
@ -65,26 +59,26 @@ public final class BrudicladTelchorEngineer extends CardImpl {
} }
} }
class BrudicladTelchorCombatffect extends OneShotEffect { class BrudicladTelchorEngineerEffect extends OneShotEffect {
private static final FilterControlledPermanent filter = new FilterControlledPermanent(" token you control. If you do, each other token you control becomes a copy of that token"); private static final FilterControlledPermanent filter = new FilterControlledPermanent("token you control");
static { static {
filter.add(new TokenPredicate()); filter.add(new TokenPredicate());
} }
public BrudicladTelchorCombatffect() { public BrudicladTelchorEngineerEffect() {
super(Outcome.Sacrifice); super(Outcome.Sacrifice);
this.staticText = " you may choose a token you control. If you do, each other token you control becomes a copy of that token"; this.staticText = " create a 2/1 blue Myr artifact creature token. Then you may choose a token you control. If you do, each other token you control becomes a copy of that token";
} }
public BrudicladTelchorCombatffect(final BrudicladTelchorCombatffect effect) { public BrudicladTelchorEngineerEffect(final BrudicladTelchorEngineerEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public BrudicladTelchorCombatffect copy() { public BrudicladTelchorEngineerEffect copy() {
return new BrudicladTelchorCombatffect(this); return new BrudicladTelchorEngineerEffect(this);
} }
@Override @Override
@ -95,7 +89,8 @@ class BrudicladTelchorCombatffect extends OneShotEffect {
if (effect.apply(game, source)) { if (effect.apply(game, source)) {
TargetControlledPermanent target = new TargetControlledPermanent(0, 1, filter, true); TargetControlledPermanent target = new TargetControlledPermanent(0, 1, filter, true);
target.setNotTarget(true); target.setNotTarget(true);
if (controller.choose(Outcome.Neutral, target, source.getSourceId(), game)) { if (controller.chooseUse(outcome, "Select a token to copy?", source, game)
&& controller.choose(Outcome.Neutral, target, source.getSourceId(), game)) {
Permanent toCopyFromPermanent = game.getPermanent(target.getFirstTarget()); Permanent toCopyFromPermanent = game.getPermanent(target.getFirstTarget());
if (toCopyFromPermanent != null) { if (toCopyFromPermanent != null) {

View file

@ -0,0 +1,44 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.discard.DiscardEachPlayerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
/**
*
* @author TheElk801
*/
public final class BurglarRat extends CardImpl {
public BurglarRat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.RAT);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When Burglar Rat enters the battlefield, each opponent discards a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DiscardEachPlayerEffect(
new StaticValue(1), false,
TargetController.OPPONENT
)
));
}
public BurglarRat(final BurglarRat card) {
super(card);
}
@Override
public BurglarRat copy() {
return new BurglarRat(this);
}
}

View file

@ -0,0 +1,226 @@
package mage.cards.b;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher;
/**
*
* @author L_J
*/
public final class BurningCinderFuryOfCrimsonChaosFire extends CardImpl {
public BurningCinderFuryOfCrimsonChaosFire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// Whenever any player taps a permanent, that player choose one of their opponents. The chosen player gains control of that permanent at the beginning of the next end step.
this.addAbility(new BurningCinderFuryOfCrimsonChaosFireAbility());
// At the beginning of each players end step, if that player didnt tap any nonland permanents that turn, Burning Cinder Fury of Crimson Chaos Fire deals 3 damage to that player.
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3).setText("{this} deals 3 damage to that player"),
TargetController.ANY, new BurningCinderFuryOfCrimsonChaosFireCondition(), false), new BurningCinderFuryOfCrimsonChaosFireWatcher());
}
public BurningCinderFuryOfCrimsonChaosFire(final BurningCinderFuryOfCrimsonChaosFire card) {
super(card);
}
@Override
public BurningCinderFuryOfCrimsonChaosFire copy() {
return new BurningCinderFuryOfCrimsonChaosFire(this);
}
}
class BurningCinderFuryOfCrimsonChaosFireAbility extends TriggeredAbilityImpl {
public BurningCinderFuryOfCrimsonChaosFireAbility() {
super(Zone.BATTLEFIELD, new BurningCinderFuryOfCrimsonChaosFireEffect(), false);
}
public BurningCinderFuryOfCrimsonChaosFireAbility(BurningCinderFuryOfCrimsonChaosFireAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TAPPED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
BurningCinderFuryOfCrimsonChaosFireEffect effect = (BurningCinderFuryOfCrimsonChaosFireEffect) this.getEffects().get(0);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.setFirstController(permanent.getControllerId()); // it's necessary to remember the original controller, as the controller might change by the time the trigger resolves
return true;
}
return false;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireAbility copy() {
return new BurningCinderFuryOfCrimsonChaosFireAbility(this);
}
@Override
public String getRule() {
return "Whenever any player taps a permanent, " + super.getRule();
}
}
class BurningCinderFuryOfCrimsonChaosFireEffect extends OneShotEffect {
private UUID firstController = null;
public BurningCinderFuryOfCrimsonChaosFireEffect() {
super(Outcome.Detriment);
this.staticText = "that player choose one of their opponents. The chosen player gains control of that permanent at the beginning of the next end step";
}
public BurningCinderFuryOfCrimsonChaosFireEffect(final BurningCinderFuryOfCrimsonChaosFireEffect effect) {
super(effect);
this.firstController = effect.firstController;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireEffect copy() {
return new BurningCinderFuryOfCrimsonChaosFireEffect(this);
}
public void setFirstController(UUID newId) {
this.firstController = newId;
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(firstController);
if (player != null) {
Target target = new TargetOpponent(true);
if (target.canChoose(player.getId(), game)) {
while (!target.isChosen() && target.canChoose(player.getId(), game) && player.canRespond()) {
player.chooseTarget(outcome, target, source, game);
}
}
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
Player chosenOpponent = game.getPlayer(target.getFirstTarget());
if (permanent != null && chosenOpponent != null) {
game.informPlayers(player.getLogName() + " chose " + chosenOpponent.getLogName() + " to gain control of " + permanent.getLogName() + " at the beginning of the next end step");
ContinuousEffect effect = new BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(Duration.Custom, chosenOpponent.getId());
effect.setTargetPointer(new FixedTarget(permanent.getId()));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}
return false;
}
}
class BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect extends ContinuousEffectImpl {
private UUID controller;
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(Duration duration, UUID controller) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.controller = controller;
this.staticText = "the chosen player gains control of that permanent";
}
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(final BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect effect) {
super(effect);
this.controller = effect.controller;
}
@Override
public BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect copy() {
return new BurningCinderFuryOfCrimsonChaosFireCreatureGainControlEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (targetPointer != null) {
permanent = game.getPermanent(targetPointer.getFirst(game, source));
}
if (permanent != null && controller != null) {
return permanent.changeControllerId(controller, game);
}
return false;
}
}
class BurningCinderFuryOfCrimsonChaosFireCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
BurningCinderFuryOfCrimsonChaosFireWatcher watcher = (BurningCinderFuryOfCrimsonChaosFireWatcher) game.getState().getWatchers().get(BurningCinderFuryOfCrimsonChaosFireWatcher.class.getSimpleName());
if (watcher != null) {
return !watcher.tappedNonlandThisTurn(game.getActivePlayerId());
}
return false;
}
public String toString() {
return "if that player didnt tap any nonland permanents that turn";
}
}
class BurningCinderFuryOfCrimsonChaosFireWatcher extends Watcher {
private final Set<UUID> tappedActivePlayerIds = new HashSet<>();
public BurningCinderFuryOfCrimsonChaosFireWatcher() {
super(BurningCinderFuryOfCrimsonChaosFireWatcher.class.getSimpleName(), WatcherScope.GAME);
}
public BurningCinderFuryOfCrimsonChaosFireWatcher(final BurningCinderFuryOfCrimsonChaosFireWatcher watcher) {
super(watcher);
this.tappedActivePlayerIds.addAll(watcher.tappedActivePlayerIds);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TAPPED) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && !permanent.isLand()) {
tappedActivePlayerIds.add(permanent.getControllerId());
}
}
}
public boolean tappedNonlandThisTurn(UUID playerId) {
return tappedActivePlayerIds.contains(playerId);
}
@Override
public void reset() {
tappedActivePlayerIds.clear();
}
@Override
public BurningCinderFuryOfCrimsonChaosFireWatcher copy() {
return new BurningCinderFuryOfCrimsonChaosFireWatcher(this);
}
}

View file

@ -136,7 +136,7 @@ class WhackCondition extends IntCompareCondition {
@Override @Override
protected int getInputValue(Game game, Ability source) { protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("whack" + source.getSourceId()); Object object = game.getState().getValue("whack" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) { if (object instanceof Boolean && (Boolean) object) {
return 1; return 1;
} }
return 0; return 0;
@ -157,7 +157,7 @@ class DoodleCondition extends IntCompareCondition {
@Override @Override
protected int getInputValue(Game game, Ability source) { protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("doodle" + source.getSourceId()); Object object = game.getState().getValue("doodle" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) { if (object instanceof Boolean && (Boolean) object) {
return 1; return 1;
} }
return 0; return 0;
@ -178,7 +178,7 @@ class BuzzCondition extends IntCompareCondition {
@Override @Override
protected int getInputValue(Game game, Ability source) { protected int getInputValue(Game game, Ability source) {
Object object = game.getState().getValue("buzz" + source.getSourceId()); Object object = game.getState().getValue("buzz" + source.getSourceId());
if (object != null && object instanceof Boolean && (Boolean) object) { if (object instanceof Boolean && (Boolean) object) {
return 1; return 1;
} }
return 0; return 0;

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
@ -41,19 +40,22 @@ public final class CallToArms extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
// As Call to Arms enters the battlefield, choose a color and an opponent. // As Call to Arms enters the battlefield, choose a color and an opponent.
Effect effect = new ChooseColorEffect(Outcome.Detriment); Ability ability = new AsEntersBattlefieldAbility(
// effect.setText("choose a color and an opponent"); new ChooseColorEffect(Outcome.Detriment)
Ability ability = new AsEntersBattlefieldAbility(effect); );
effect = new ChooseOpponentEffect(Outcome.Benefit); ability.addEffect(new ChooseOpponentEffect(
effect.setText("then choose an opponent"); Outcome.Benefit
ability.addEffect(effect); ).setText("and an opponent"));
this.addAbility(ability); this.addAbility(ability);
// White creatures get +1/+1 as long as the chosen color is the most common color among nontoken permanents the chosen player controls but isn't tied for most common. // White creatures get +1/+1 as long as the chosen color is the most common color among nontoken permanents the chosen player controls but isn't tied for most common.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CallToArmsEffect())); this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new CallToArmsEffect()
));
// When the chosen color isn't the most common color among nontoken permanents the chosen player controls or is tied for most common, sacrifice Call to Arms. // When the chosen color isn't the most common color among nontoken permanents the chosen player controls or is tied for most common, sacrifice Call to Arms.
this.addAbility(new SacAbility()); this.addAbility(new CallToArmsStateTriggeredAbility());
} }
public CallToArms(final CallToArms card) { public CallToArms(final CallToArms card) {
@ -76,7 +78,9 @@ class CallToArmsEffect extends ContinuousEffectImpl {
public CallToArmsEffect() { public CallToArmsEffect() {
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.Benefit); super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.Benefit);
staticText = "The chosen player's maximum hand size is four"; staticText = "White creatures get +1/+1 as long as the chosen color "
+ "is the most common color among nontoken permanents "
+ "the chosen player controls but isn't tied for most common.";
} }
public CallToArmsEffect(final CallToArmsEffect effect) { public CallToArmsEffect(final CallToArmsEffect effect) {
@ -107,19 +111,19 @@ class CallToArmsEffect extends ContinuousEffectImpl {
} }
} }
class SacAbility extends StateTriggeredAbility { class CallToArmsStateTriggeredAbility extends StateTriggeredAbility {
public SacAbility() { public CallToArmsStateTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeSourceEffect()); super(Zone.BATTLEFIELD, new SacrificeSourceEffect());
} }
public SacAbility(final SacAbility ability) { public CallToArmsStateTriggeredAbility(final CallToArmsStateTriggeredAbility ability) {
super(ability); super(ability);
} }
@Override @Override
public SacAbility copy() { public CallToArmsStateTriggeredAbility copy() {
return new SacAbility(this); return new CallToArmsStateTriggeredAbility(this);
} }
@Override @Override
@ -139,7 +143,9 @@ class SacAbility extends StateTriggeredAbility {
@Override @Override
public String getRule() { public String getRule() {
return "When the chosen color isn't the most common color among nontoken permanents the chosen player controls or is tied for most common, sacrifice {this}"; return "When the chosen color isn't the most common color "
+ "among nontoken permanents the chosen player controls "
+ "or is tied for most common, sacrifice {this}";
} }
} }

View file

@ -0,0 +1,72 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author TheElk801
*/
public final class Camaraderie extends CardImpl {
public Camaraderie(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{W}");
// You gain X life and draw X cards, where X is the number of creatures you control. Creatures you control get +1/+1 until end of turn.
this.getSpellAbility().addEffect(new CamaraderieEffect());
}
public Camaraderie(final Camaraderie card) {
super(card);
}
@Override
public Camaraderie copy() {
return new Camaraderie(this);
}
}
class CamaraderieEffect extends OneShotEffect {
public CamaraderieEffect() {
super(Outcome.Benefit);
this.staticText = "You gain X life and draw X cards, "
+ "where X is the number of creatures you control. "
+ "Creatures you control get +1/+1 until end of turn.";
}
public CamaraderieEffect(final CamaraderieEffect effect) {
super(effect);
}
@Override
public CamaraderieEffect copy() {
return new CamaraderieEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
int xValue = game.getBattlefield().count(
StaticFilters.FILTER_CONTROLLED_CREATURE,
source.getSourceId(), source.getControllerId(), game
);
player.gainLife(xValue, game, source);
player.drawCards(xValue, game);
game.addEffect(new BoostControlledEffect(1, 1, Duration.EndOfTurn), source);
return true;
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
@ -11,10 +10,10 @@ import mage.abilities.effects.common.UntapTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.TargetAdjustment;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.targetadjustment.XTargetsAdjuster;
/** /**
* *
@ -31,7 +30,7 @@ public final class CandelabraOfTawnos extends CardImpl {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_LANDS));
ability.setTargetAdjustment(TargetAdjustment.X_TARGETS); ability.setTargetAdjuster(XTargetsAdjuster.instance);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -0,0 +1,59 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Ryan-Saklad
*/
public final class CandlelightVigil extends CardImpl {
public CandlelightVigil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature gets +3/+2 and has vigilance.
Effect effect = new BoostEnchantedEffect(3, 2, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature gets +3/+2");
SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
effect = new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.AURA);
effect.setText("and has vigilance");
ability2.addEffect(effect);
this.addAbility(ability2);
}
public CandlelightVigil(final CandlelightVigil card) {
super(card);
}
@Override
public CandlelightVigil copy() {
return new CandlelightVigil(this);
}
}

View file

@ -1,11 +1,10 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.abilities.condition.LockedInCondition; import mage.abilities.Ability;
import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -13,8 +12,13 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ColoredManaSymbol; import mage.constants.ColoredManaSymbol;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer; import mage.target.targetpointer.FixedTarget;
import mage.watchers.common.ManaSpentToCastWatcher; import mage.watchers.common.ManaSpentToCastWatcher;
/** /**
@ -28,19 +32,9 @@ public final class CankerousThirst extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B/G}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B/G}");
// If {B} was spent to cast Cankerous Thirst, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast Cankerous Thirst, you may have target creature get +3/+3 until end of turn. // If {B} was spent to cast Cankerous Thirst, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast Cankerous Thirst, you may have target creature get +3/+3 until end of turn.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect( this.getSpellAbility().addEffect(new CankerousThirstEffect());
new BoostTargetEffect(-3, -3, Duration.EndOfTurn), this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (1th effect -3/-3)")));
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.B)), this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature (2nd effect +3/+3)")));
"If {B} was spent to cast {this}, you may have target creature get -3/-3 until end of turn"));
ContinuousEffect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn);
effect.setTargetPointer(new SecondTargetPointer());
this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
effect,
new LockedInCondition(new ManaWasSpentCondition(ColoredManaSymbol.G)),
"If {G} was spent to cast {this}, you may have target creature get +3/+3 until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {B}{G} was spent.)</i>")); this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {B}{G} was spent.)</i>"));
this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher()); this.getSpellAbility().addWatcher(new ManaSpentToCastWatcher());
} }
@ -55,3 +49,45 @@ public final class CankerousThirst extends CardImpl {
} }
} }
class CankerousThirstEffect extends OneShotEffect {
public CankerousThirstEffect() {
super(Outcome.Benefit);
this.staticText = "If {B} was spent to cast {this}, you may have target creature get -3/-3 until end of turn. If {G} was spent to cast {this}, you may have target creature get +3/+3 until end of turn";
}
public CankerousThirstEffect(final CankerousThirstEffect effect) {
super(effect);
}
@Override
public CankerousThirstEffect copy() {
return new CankerousThirstEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (new ManaWasSpentCondition(ColoredManaSymbol.B).apply(game, source)) {
Permanent targetCreature1 = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature1 != null && controller.chooseUse(Outcome.UnboostCreature, "Let " + targetCreature1.getIdName() + " get -3/-3 until end of turn?", source, game)) {
ContinuousEffect effect = new BoostTargetEffect(-3, -3, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(targetCreature1, game));
game.addEffect(effect, source);
}
}
if (new ManaWasSpentCondition(ColoredManaSymbol.G).apply(game, source)) {
Permanent targetCreature2 = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (targetCreature2 != null && controller.chooseUse(Outcome.UnboostCreature, "Let " + targetCreature2.getIdName() + " get +3/+3 until end of turn?", source, game)) {
ContinuousEffect effect = new BoostTargetEffect(+3, +3, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(targetCreature2, game));
game.addEffect(effect, source);
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,57 @@
package mage.cards.c;
import java.util.UUID;
import mage.constants.SubType;
import mage.abilities.keyword.FlashAbility;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
import mage.abilities.effects.common.TapEnchantedEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public final class CaptureSphere extends CardImpl {
public CaptureSphere(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
this.subtype.add(SubType.AURA);
// Flash
this.addAbility(FlashAbility.getInstance());
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When Capture Sphere enters the battlefield, tap enchanted creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect()));
// Enchanted creature doesn't untap during its controller's untap step.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect()));
}
public CaptureSphere(final CaptureSphere card) {
super(card);
}
@Override
public CaptureSphere copy() {
return new CaptureSphere(this);
}
}

View file

@ -64,7 +64,7 @@ class CavernOfSoulsManaBuilder extends ConditionalManaBuilder {
@Override @Override
public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) { public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) {
SubType subType = ChooseCreatureTypeEffect.getChoosenCreatureType(source.getSourceId(), game); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (subType != null) { if (subType != null) {
creatureType = subType; creatureType = subType;
} }

View file

@ -0,0 +1,73 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
/**
*
* @author TheElk801
*/
public final class CentaurPeacemaker extends CardImpl {
public CentaurPeacemaker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
this.subtype.add(SubType.CENTAUR);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When Centaur Mediator enters the battlefield, each player gains 4 life.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new CentaurMediatorEffect()
));
}
public CentaurPeacemaker(final CentaurPeacemaker card) {
super(card);
}
@Override
public CentaurPeacemaker copy() {
return new CentaurPeacemaker(this);
}
}
class CentaurMediatorEffect extends OneShotEffect {
public CentaurMediatorEffect() {
super(Outcome.GainLife);
staticText = "each player gains 4 life.";
}
public CentaurMediatorEffect(final CentaurMediatorEffect effect) {
super(effect);
}
@Override
public CentaurMediatorEffect copy() {
return new CentaurMediatorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.getState().getPlayersInRange(
source.getControllerId(), game
).stream().map((playerId) -> game.getPlayer(playerId)).filter(
(player) -> (player != null)
).forEachOrdered((player) -> {
player.gainLife(4, game, source);
});
return true;
}
}

View file

@ -81,7 +81,7 @@ class ChainOfSilenceEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId()); Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) { if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true); StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) { if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game); String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) { if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6); activateMessage = activateMessage.substring(6);

View file

@ -78,7 +78,7 @@ class ChainOfVaporEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId()); Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) { if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true); StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) { if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game); String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) { if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6); activateMessage = activateMessage.substring(6);

View file

@ -80,7 +80,7 @@ class ChainStasisEffect extends OneShotEffect {
Spell spell = game.getStack().getSpell(source.getSourceId()); Spell spell = game.getStack().getSpell(source.getSourceId());
if (spell != null) { if (spell != null) {
StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true); StackObject newStackObject = spell.createCopyOnStack(game, source, player.getId(), true);
if (newStackObject != null && newStackObject instanceof Spell) { if (newStackObject instanceof Spell) {
String activateMessage = ((Spell) newStackObject).getActivatedMessage(game); String activateMessage = ((Spell) newStackObject).getActivatedMessage(game);
if (activateMessage.startsWith(" casts ")) { if (activateMessage.startsWith(" casts ")) {
activateMessage = activateMessage.substring(6); activateMessage = activateMessage.substring(6);

View file

@ -0,0 +1,132 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.VariableCostImpl;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.ColorsOfManaSpentToCastCount;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetAnyTarget;
/**
*
* @author jmharmon
*/
public final class ChamberSentry extends CardImpl {
public ChamberSentry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{X}");
this.subtype.add(SubType.CONSTRUCT);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Chamber Sentry enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true),
"with a +1/+1 counter on it for each color of mana spent to cast it"));
// {X}, {T}, Remove X +1/+1 counters from Chamber Sentry: It deals X damage to any target.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue())
.setText("It deals X damage to any target"),
new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
ability.addCost(new ChamberSentryRemoveVariableCountersSourceCost(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
// {W}{U}{B}{R}{G}: Return Chamber Sentry from your graveyard to your hand.
this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}")));
}
public ChamberSentry(final ChamberSentry card) {
super(card);
}
@Override
public ChamberSentry copy() {
return new ChamberSentry(this);
}
}
class ChamberSentryRemoveVariableCountersSourceCost extends VariableCostImpl {
protected int minimalCountersToPay = 0;
private String counterName;
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter) {
this(counter, 0);
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, String text) {
this(counter, 0, text);
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, int minimalCountersToPay) {
this(counter, minimalCountersToPay, "");
}
public ChamberSentryRemoveVariableCountersSourceCost(Counter counter, int minimalCountersToPay, String text) {
super(counter.getName() + " counters to remove");
this.minimalCountersToPay = minimalCountersToPay;
this.counterName = counter.getName();
if (text == null || text.isEmpty()) {
this.text = "Remove X " + counterName + " counters from {this}";
} else {
this.text = text;
}
}
public ChamberSentryRemoveVariableCountersSourceCost(final ChamberSentryRemoveVariableCountersSourceCost cost) {
super(cost);
this.minimalCountersToPay = cost.minimalCountersToPay;
this.counterName = cost.counterName;
}
@Override
public ChamberSentryRemoveVariableCountersSourceCost copy() {
return new ChamberSentryRemoveVariableCountersSourceCost(this);
}
@Override
public Cost getFixedCostsFromAnnouncedValue(int xValue) {
return new RemoveCountersSourceCost(new Counter(counterName, xValue));
}
@Override
public int getMinValue(Ability source, Game game) {
return minimalCountersToPay;
}
@Override
public int getMaxValue(Ability source, Game game) {
int maxValue = 0;
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
maxValue = permanent.getCounters(game).getCount(counterName);
}
return maxValue;
}
@Override
public int announceXValue(Ability source, Game game) {
return source.getManaCostsToPay().getX();
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
/**
*
* @author TheElk801
*/
public final class ChanceForGlory extends CardImpl {
public ChanceForGlory(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}");
// Creatures you control gain indestructible. Take an extra turn after this one. At the beginning of that turn's end step, you lose the game.
this.getSpellAbility().addEffect(new GainAbilityControlledEffect(
IndestructibleAbility.getInstance(), Duration.EndOfGame
).setText("Creatures you control gain indestructible"));
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect(true));
}
public ChanceForGlory(final ChanceForGlory card) {
super(card);
}
@Override
public ChanceForGlory copy() {
return new ChanceForGlory(this);
}
}

View file

@ -7,7 +7,7 @@ import mage.MageObjectReference;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.DrawCardAllEffect;
@ -41,7 +41,7 @@ public final class ChandraAblaze extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target. // +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1); LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1);

View file

@ -5,7 +5,7 @@ import java.util.UUID;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@ -30,7 +30,7 @@ public final class ChandraBoldPyromancer extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +1: Add {R}{R}. Chandra, Bold Pyromancer deals 2 damage to target player. // +1: Add {R}{R}. Chandra, Bold Pyromancer deals 2 damage to target player.
Ability ability = new LoyaltyAbility(new BasicManaEffect(Mana.RedMana(2)), +1); Ability ability = new LoyaltyAbility(new BasicManaEffect(Mana.RedMana(2)), +1);

View file

@ -5,7 +5,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
@ -36,7 +36,7 @@ public final class ChandraFlamecaller extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Create two 3/1 red Elemental creature tokens with haste. Exile them at the beginning of the next end step. // +1: Create two 3/1 red Elemental creature tokens with haste. Exile them at the beginning of the next end step.
this.addAbility(new LoyaltyAbility(new ChandraElementalEffect(), 1)); this.addAbility(new LoyaltyAbility(new ChandraElementalEffect(), 1));

View file

@ -4,7 +4,7 @@ package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
@ -33,7 +33,7 @@ public final class ChandraNalaar extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(6));
// +1: Chandra Nalaar deals 1 damage to target player or planeswalker. // +1: Chandra Nalaar deals 1 damage to target player or planeswalker.
LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1);

View file

@ -3,7 +3,7 @@ package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageAllControlledTargetEffect;
@ -31,7 +31,7 @@ public final class ChandraPyrogenius extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +2: Chandra, Pyrogenius deals 2 damage to each opponent. // +2: Chandra, Pyrogenius deals 2 damage to each opponent.
this.addAbility(new LoyaltyAbility(new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT), 2)); this.addAbility(new LoyaltyAbility(new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT), 2));

View file

@ -8,7 +8,7 @@ import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -38,7 +38,7 @@ public final class ChandraPyromaster extends CardImpl {
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn. // +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn.
LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1); LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1);

View file

@ -6,7 +6,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -36,7 +36,7 @@ public final class ChandraRoaringFlame extends CardImpl {
this.nightCard = true; this.nightCard = true;
this.transformable = true; this.transformable = true;
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// +1: Chandra, Roaring Flame deals 2 damage to target player. // +1: Chandra, Roaring Flame deals 2 damage to target player.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1); LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1);

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