diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 827b1dbbd61..fb8ab7cab91 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -30,14 +30,14 @@ jspf-core 0.9.1 - - org.slf4j - slf4j-log4j12 - log4j log4j + + org.slf4j + slf4j-log4j12 + net.sf.trove4j trove4j diff --git a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java index d13da77a3ff..51be991cda3 100644 --- a/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java +++ b/Mage.Client/src/main/java/mage/client/util/gui/GuiDisplayUtil.java @@ -14,6 +14,7 @@ import javax.swing.*; import java.awt.*; import java.net.URL; import java.util.ArrayList; +import mage.constants.Rarity; import org.mage.plugins.card.utils.impl.ImageManagerImpl; public class GuiDisplayUtil { @@ -221,21 +222,27 @@ public class GuiDisplayUtil { } buffer.append(getTypes(card)); buffer.append(""); - switch (card.getRarity()) { - case RARE: - buffer.append(""); - break; - case UNCOMMON: - buffer.append(""); - break; - case COMMON: - buffer.append(""); - break; - case MYTHIC: - buffer.append(""); - break; + String rarity ; + if (card.getRarity() == null) { + rarity = Rarity.COMMON.getCode(); + buffer.append(""); + }else { + switch (card.getRarity()) { + case RARE: + buffer.append(""); + break; + case UNCOMMON: + buffer.append(""); + break; + case COMMON: + buffer.append(""); + break; + case MYTHIC: + buffer.append(""); + break; + } + rarity = card.getRarity().getCode(); } - String rarity = card.getRarity().getCode(); if (card.getExpansionSetCode() != null) { buffer.append(ManaSymbols.replaceSetCodeWithHTML(card.getExpansionSetCode().toUpperCase(), rarity)); } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index 19fdbedb73c..f6a60065d1b 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -721,13 +721,13 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private BufferedImage getFaceDownImage() { if (isPermanent) { - if (gameCard.isMorphCard() && ((PermanentView) gameCard).isMorphed()) { + if (((PermanentView) gameCard).isMorphed()) { return ImageCache.getMorphImage(); } else { return ImageCache.getManifestImage(); } } else { - if (gameCard.isMorphCard() && this.gameCard instanceof StackAbilityView) { + if (this.gameCard instanceof StackAbilityView) { return ImageCache.getMorphImage(); } else { return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename)); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java index 4ced3318ab7..937caff535e 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -90,7 +90,7 @@ public class CardPluginImpl implements CardPlugin { @Override public MagePermanent getMageCard(CardView permanent, Dimension dimension, UUID gameId, ActionCallback callback, boolean canBeFoil, boolean loadImage) { CardPanel cardPanel = new CardPanel(permanent, gameId, loadImage, callback, false, dimension); - boolean implemented = !permanent.getRarity().equals(Rarity.NA); + boolean implemented = permanent.getRarity() != null && !permanent.getRarity().equals(Rarity.NA); cardPanel.setShowCastingCost(implemented); return cardPanel; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgImageSource.java index 0898c54bb33..b89656dbb05 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgImageSource.java @@ -31,7 +31,11 @@ package org.mage.plugins.card.dl.sources; import org.mage.plugins.card.images.CardDownloadData; /** - * + * Site was shutdown by wizards Feb. 2015 + * + * + * + * * @author LevelX2 */ diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 0f586066f7f..3fe998d1bdd 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -140,7 +140,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab p0.add(jLabel1); p0.add(Box.createVerticalStrut(5)); - ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "magiccards.info", "wizards.com", "mtgimage.com (HQ)" /*, "mtgathering.ru HQ", "mtgathering.ru MQ", "mtgathering.ru LQ"*/}); + ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "magiccards.info", "wizards.com"/*, "mtgimage.com (HQ)" , "mtgathering.ru HQ", "mtgathering.ru MQ", "mtgathering.ru LQ"*/}); jComboBox1 = new JComboBox(); cardImageSource = MagicCardsImageSource.getInstance(); @@ -158,9 +158,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab case 1: cardImageSource = WizardCardsImageSource.getInstance(); break; - case 2: - cardImageSource = MtgImageSource.getInstance(); - break; } int count = DownloadPictures.this.cards.size(); float mb = (count * cardImageSource.getAverageSize()) / 1024; diff --git a/Mage.Client/src/main/resources/card-pictures-tok.txt b/Mage.Client/src/main/resources/card-pictures-tok.txt index 922b47bb0e6..c5af8128237 100644 --- a/Mage.Client/src/main/resources/card-pictures-tok.txt +++ b/Mage.Client/src/main/resources/card-pictures-tok.txt @@ -11,9 +11,14 @@ #|Generate|TOK:PTC|Wolf| #|Generate|TOK:PTC|Wurm| -$|Generate|TOK:DTK|Djinn Monk| -$|Generate|TOK:DTK|Goblin| -$|Generate|TOK:DTK|Zombie| +#|Generate|TOK:DTK|Djinn Monk| +#|Generate|TOK:DTK|Dragon| +#|Generate|TOK:DTK|Goblin| +#|Generate|TOK:DTK|Morph| +#|Generate|TOK:DTK|Warrior| +#|Generate|TOK:DTK|Zombie| +#|Generate|TOK:DTK|Zombie Horror| +#|Generate|EMBLEM!:DTK|Emblem Narset Transcendent| #|Generate|TOK:GRC|Bird| #|Generate|TOK:GRC|Golem| @@ -28,7 +33,7 @@ $|Generate|TOK:DTK|Zombie| #|Generate|TOK:MBP|Goblin| #|Generate|TOK:MBP|Zombie| -$|Generate|TOK:MLP|Thopter| +#|Generate|TOK:MLP|Thopter| #|Generate|TOK:WMCQ|Angel| @@ -46,6 +51,8 @@ $|Generate|TOK:MLP|Thopter| #|Generate|TOK:MGDC|Sliver| #|Generate|TOK:FNMP|Centaur| +|Generate|TOK:FNMP|Human| +|Generate|TOK:FNMP|Wolf| #|Generate|TOK:FNMP|Wurm| |Generate|TOK:DDN|Goblin| @@ -175,6 +182,7 @@ $|Generate|TOK:MLP|Thopter| |Generate|TOK:RTR|Assassin| |Generate|TOK:RTR|Dragon| |Generate|TOK:RTR|Goblin| +|Generate|TOK:RTR|Centaur 1| |Generate|TOK:RTR|Ooze| |Generate|TOK:RTR|Rhino| |Generate|TOK:RTR|Saproling| diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index fafd5af104f..52abf75f4e9 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -87,7 +87,7 @@ public class CardView extends SimpleCardView { protected boolean transformed; protected boolean flipCard; - protected boolean morphCard; + protected boolean faceDown; protected String alternateName; protected String originalName; @@ -134,17 +134,16 @@ public class CardView extends SimpleCardView { * * @param card * @param game - * @param cardId + * @param cardId not used? * @param controlled is the card view created for the card controller - used for morph / face down cards to know which player may see information for the card */ public CardView(Card card, Game game, UUID cardId, boolean controlled) { - super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.isFaceDown(), card.getUsesVariousArt(), card.getTokenSetCode()); - this.morphCard = card.isMorphCard(); + super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode()); // no information available for face down cards as long it's not a controlled face down morph card // TODO: Better handle this in Framework (but currently I'm not sure how to do it there) LevelX2 - if (card.isFaceDown()) { + if (card.isFaceDown(game)) { this.fillEmpty(card, controlled); - if (card.isMorphCard() && card instanceof Spell) { + if (card instanceof Spell) { // special handling for casting of Morph cards if (controlled) { this.name = card.getName(); @@ -198,7 +197,11 @@ public class CardView extends SimpleCardView { this.name = card.getImageName(); this.displayName = card.getName(); - this.rules = card.getRules(game); + if (game == null) { + this.rules = card.getRules(); + } else { + this.rules = card.getRules(game); + } this.manaCost = card.getManaCost().getSymbols(); this.convertedManaCost = card.getManaCost().convertedManaCost(); @@ -238,7 +241,7 @@ public class CardView extends SimpleCardView { this.color = card.getColor(); this.canTransform = card.canTransform(); this.flipCard = card.isFlipCard(); - + this.faceDown = game != null ? card.isFaceDown(game) : false; if (card instanceof PermanentToken) { this.isToken = true; @@ -295,7 +298,7 @@ public class CardView extends SimpleCardView { } public CardView(MageObject object) { - super(object.getId(), "", 0, false, false, ""); + super(object.getId(), "", 0, false, ""); this.name = object.getName(); this.displayName = object.getName(); if (object instanceof Permanent) { @@ -339,7 +342,7 @@ public class CardView extends SimpleCardView { } protected CardView() { - super(null, "", 0, false, false, ""); + super(null, "", 0, false, ""); } public CardView(EmblemView emblem) { @@ -355,7 +358,7 @@ public class CardView extends SimpleCardView { } public CardView(boolean empty) { - super(null, "", 0, false, false, ""); + super(null, "", 0, false, ""); if (!empty) { throw new IllegalArgumentException("Not supported."); } @@ -413,7 +416,7 @@ public class CardView extends SimpleCardView { } CardView(Token token) { - super(token.getId(), "", 0, false, false, ""); + super(token.getId(), "", 0, false, ""); this.isToken = true; this.id = token.getId(); this.name = token.getName(); @@ -577,7 +580,6 @@ public class CardView extends SimpleCardView { return getName() + " [" + getId() + "]"; } - @Override public boolean isFaceDown() { return faceDown; } @@ -692,10 +694,6 @@ public class CardView extends SimpleCardView { return flipCard; } - public boolean isMorphCard() { - return morphCard; - } - public boolean isToRotate() { return rotate; } diff --git a/Mage.Common/src/mage/view/CommanderView.java b/Mage.Common/src/mage/view/CommanderView.java index b104d9a4962..46e012b374c 100644 --- a/Mage.Common/src/mage/view/CommanderView.java +++ b/Mage.Common/src/mage/view/CommanderView.java @@ -27,22 +27,20 @@ */ package mage.view; +import java.io.Serializable; import mage.cards.Card; import mage.constants.MageObjectType; +import mage.game.Game; import mage.game.command.Commander; -import java.io.Serializable; - /** * * @author Plopman */ public class CommanderView extends CardView implements CommandObjectView, Serializable{ - public CommanderView(Commander commander, Card sourceCard) { - super(sourceCard); + public CommanderView(Commander commander, Card sourceCard, Game game) { + super(sourceCard, game, null, false); this.mageObjectType = MageObjectType.COMMANDER; - } - - + } } diff --git a/Mage.Common/src/mage/view/LookedAtView.java b/Mage.Common/src/mage/view/LookedAtView.java index 109d81fb0dc..a7485e7120f 100644 --- a/Mage.Common/src/mage/view/LookedAtView.java +++ b/Mage.Common/src/mage/view/LookedAtView.java @@ -46,7 +46,7 @@ public class LookedAtView implements Serializable { public LookedAtView(String name, Cards cards, Game game) { this.name = name; for (Card card: cards.getCards(game)) { - this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.isFaceDown(), card.getTokenSetCode())); + this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode())); } } diff --git a/Mage.Common/src/mage/view/PermanentView.java b/Mage.Common/src/mage/view/PermanentView.java index 376e63e69a6..4ce0246ea05 100644 --- a/Mage.Common/src/mage/view/PermanentView.java +++ b/Mage.Common/src/mage/view/PermanentView.java @@ -84,10 +84,7 @@ public class PermanentView extends CardView { } else { if (card != null) { // original may not be face down - boolean wasfaceDown = card.isFaceDown(); - card.setFaceDown(false); original = new CardView(card); - card.setFaceDown(wasfaceDown); } else { original = null; } @@ -119,7 +116,7 @@ public class PermanentView extends CardView { this.nameOwner = ""; } - if (permanent.isFaceDown() && card != null) { + if (permanent.isFaceDown(game) && card != null) { if (controlled){ // must be a morphed or manifested card for (Ability permanentAbility : permanent.getAbilities()) { diff --git a/Mage.Common/src/mage/view/PlayerView.java b/Mage.Common/src/mage/view/PlayerView.java index 67379692644..b843c768231 100644 --- a/Mage.Common/src/mage/view/PlayerView.java +++ b/Mage.Common/src/mage/view/PlayerView.java @@ -132,7 +132,7 @@ public class PlayerView implements Serializable { if(commander.getControllerId().equals(this.playerId)){ Card sourceCard = game.getCard(commander.getSourceId()); if(sourceCard != null){ - commandList.add(new CommanderView(commander, sourceCard)); + commandList.add(new CommanderView(commander, sourceCard, game)); } } } diff --git a/Mage.Common/src/mage/view/RevealedView.java b/Mage.Common/src/mage/view/RevealedView.java index 2d573ef89f8..3f067267cda 100644 --- a/Mage.Common/src/mage/view/RevealedView.java +++ b/Mage.Common/src/mage/view/RevealedView.java @@ -45,7 +45,7 @@ public class RevealedView implements Serializable { public RevealedView(String name, Cards cards, Game game) { this.name = name; for (Card card: cards.getCards(game)) { - this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.isFaceDown(), card.getTokenSetCode())); + this.cards.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode())); } } diff --git a/Mage.Common/src/mage/view/SimpleCardView.java b/Mage.Common/src/mage/view/SimpleCardView.java index 5678cdef2b0..daf216d72cc 100644 --- a/Mage.Common/src/mage/view/SimpleCardView.java +++ b/Mage.Common/src/mage/view/SimpleCardView.java @@ -40,14 +40,12 @@ public class SimpleCardView implements Serializable { protected String expansionSetCode; protected String tokenSetCode; protected int cardNumber; - protected boolean faceDown; protected boolean usesVariousArt; - public SimpleCardView(UUID id, String expansionSetCode, int cardNumber, boolean faceDown, boolean usesVariousArt, String tokenSetCode) { + public SimpleCardView(UUID id, String expansionSetCode, int cardNumber, boolean usesVariousArt, String tokenSetCode) { this.id = id; this.expansionSetCode = expansionSetCode; this.cardNumber = cardNumber; - this.faceDown = faceDown; this.usesVariousArt = usesVariousArt; this.tokenSetCode = tokenSetCode; } @@ -64,10 +62,6 @@ public class SimpleCardView implements Serializable { return cardNumber; } - public boolean isFaceDown() { - return faceDown; - } - public boolean getUsesVariousArt() { return usesVariousArt; } diff --git a/Mage.Common/src/mage/view/SimpleCardsView.java b/Mage.Common/src/mage/view/SimpleCardsView.java index e01c69f7aa9..d3763e4eedd 100644 --- a/Mage.Common/src/mage/view/SimpleCardsView.java +++ b/Mage.Common/src/mage/view/SimpleCardsView.java @@ -44,7 +44,7 @@ public class SimpleCardsView extends LinkedHashMap { public SimpleCardsView(Collection cards) { for (Card card: cards) { - this.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.isFaceDown(), card.getUsesVariousArt(), card.getTokenSetCode())); + this.put(card.getId(), new SimpleCardView(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), card.getTokenSetCode())); } } diff --git a/Mage.Common/src/mage/view/StackAbilityView.java b/Mage.Common/src/mage/view/StackAbilityView.java index 9872f9eaf92..8a5dae7d003 100644 --- a/Mage.Common/src/mage/view/StackAbilityView.java +++ b/Mage.Common/src/mage/view/StackAbilityView.java @@ -74,7 +74,7 @@ public class StackAbilityView extends CardView { this.power = ability.getPower().toString(); this.toughness = ability.getToughness().toString(); String nameToShow; - if (sourceCard.isMorphCard() && sourceCard.isFaceDown()) { + if (sourceCard.isFaceDown()) { CardView tmpSourceCard = this.getSourceCard(); tmpSourceCard.displayName = "Face Down"; tmpSourceCard.superTypes.clear(); diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java index d425a8bf318..471ccaedf2f 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/TinyLeaders.java @@ -38,6 +38,7 @@ import mage.cards.decks.Deck; import mage.cards.decks.DeckValidator; import mage.constants.CardType; import mage.filter.FilterMana; +import mage.game.GameTinyLeadersImpl; import mage.util.CardUtil; /** @@ -121,6 +122,7 @@ public class TinyLeaders extends DeckValidator { List basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Snow-Covered Forest", "Snow-Covered Island", "Snow-Covered Mountain", "Snow-Covered Swamp", "Snow-Covered Plains")); Map counts = new HashMap<>(); + counts.put(deck.getName(), 1); // add the commander to the counts, so it can't be in the deck or sideboard again countCards(counts, deck.getCards()); countCards(counts, deck.getSideboard()); for (Map.Entry entry : counts.entrySet()) { @@ -139,15 +141,8 @@ public class TinyLeaders extends DeckValidator { } } - if (deck.getSideboard().size() <= 11) { - Card commander = null; - - for (Card card : deck.getSideboard()) { - if (card.getName().equalsIgnoreCase(deck.getName())) { - commander = card; - } - } - + if (deck.getSideboard().size() <= 10) { + Card commander = GameTinyLeadersImpl.getCommanderCard(deck.getName(), null); /** * 905.5b - Each card must have a converted mana cost of three of less. * Cards with {X} in their mana cost count X as zero. @@ -156,10 +151,10 @@ public class TinyLeaders extends DeckValidator { if (commander == null || commander.getManaCost().convertedManaCost() > 3) { if (commander == null) { - invalid.put("Leader", "Please be sure to set your leader in the NAME field in the DECK EDITOR"); + invalid.put("Leader", "Please be sure to set your leader in the NAME field in the DECK EDITOR (use the names Mardu, Sultai or Jeskai as default Commanders)"); } if (commander != null && commander.getManaCost().convertedManaCost() > 3) { - invalid.put("Leader", "Commander CMC is Greater than 3"); + invalid.put("Leader", "Commanders converted mana cost is greater than 3"); } return false; } @@ -188,7 +183,7 @@ public class TinyLeaders extends DeckValidator { valid = false; } } else { - invalid.put("Commander", "Sideboard must contain only the commander and a maximum of 10 sideboard cards"); + invalid.put("Commander", "Sideboard must contain only a maximum of 10 sideboard cards (the Tiny Leader name must be written to the deck name)"); valid = false; } diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index b29ea9d02d9..ecc476e085d 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -575,7 +575,7 @@ public class HumanPlayer extends PlayerImpl { if (object != null) { Zone zone = game.getState().getZone(object.getId()); if (zone != null) { - if (object instanceof Card && ((Card) object).isFaceDown()) { + if (object instanceof Card && ((Card) object).isFaceDown(game)) { revealFaceDownCard((Card) object, game); result = true; } diff --git a/Mage.Sets/src/mage/sets/antiquities/PowerArtifact.java b/Mage.Sets/src/mage/sets/antiquities/PowerArtifact.java new file mode 100644 index 00000000000..64ac7fd00bf --- /dev/null +++ b/Mage.Sets/src/mage/sets/antiquities/PowerArtifact.java @@ -0,0 +1,110 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.sets.antiquities; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; +import mage.util.CardUtil; + +/** + * + * @author nick.myers + */ +public class PowerArtifact extends CardImpl { + + public PowerArtifact(UUID ownerId) { + super(ownerId, 55, "Power Artifact", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}"); + this.expansionSetCode = "ATQ"; + this.subtype.add("Aura"); + + // Enchant artifact + TargetPermanent auraTarget = new TargetArtifactPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // The activation cost of target artifact is reduced by {2}. If this would reduce target + // artifact's activation cost below {1}, target artifact's activation cost becomes {1}. + // Power Artifact has no effect on artifacts that have no activation cost or whose activation + // cost is {0}. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PowerArtifactCostModificationEffect())); + } + + public PowerArtifact(final PowerArtifact card) { + super(card); + } + + @Override + public PowerArtifact copy() { + return new PowerArtifact(this); + } +} + +class PowerArtifactCostModificationEffect extends CostModificationEffectImpl { + + PowerArtifactCostModificationEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "The activation cost of target artifact is reduced by {2}. If this would reduce target artifact's activation cost below {1}, target artifact's activation cost becomes {1}. Power artifact has no effect on artifacts that have no activation cost or whose activation cost is {0}."; + + } + + PowerArtifactCostModificationEffect(PowerArtifactCostModificationEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + Player controller = game.getPlayer(abilityToModify.getControllerId()); + if (controller != null) { + Mana mana = abilityToModify.getManaCostsToPay().getMana(); + int reduce = mana.getColorless(); + if (reduce > 0 && mana.count() == mana.getColorless()) { + reduce--; + } + if (reduce > 2) { + reduce = 2; + } + CardUtil.reduceCost(abilityToModify, reduce); + } + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + Permanent artifact = game.getPermanent(abilityToModify.getSourceId()); + if (artifact != null && artifact.getAttachments().contains(source.getSourceId())) { + if (abilityToModify.getAbilityType().equals(AbilityType.ACTIVATED)) { + return true; + } + } + return false; + } + + @Override + public PowerArtifactCostModificationEffect copy() { + return new PowerArtifactCostModificationEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/arabiannights/OldManOfTheSea.java b/Mage.Sets/src/mage/sets/arabiannights/OldManOfTheSea.java index 3642431cf2b..a8e39b12b17 100644 --- a/Mage.Sets/src/mage/sets/arabiannights/OldManOfTheSea.java +++ b/Mage.Sets/src/mage/sets/arabiannights/OldManOfTheSea.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.StateTriggeredAbility; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SkipUntapOptionalAbility; import mage.abilities.condition.CompoundCondition; @@ -39,6 +38,7 @@ import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceTappedCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -126,7 +126,7 @@ result is save to a state value to be available for the condition of the continu class OldManOfTheSeaStateBasedTriggeredAbility extends StateTriggeredAbility { public OldManOfTheSeaStateBasedTriggeredAbility() { - super(Zone.BATTLEFIELD, new EmptyEffect("")); + super(Zone.BATTLEFIELD, new InfoEffect("")); this.setRuleVisible(false); this.usesStack = false; } diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java index 200e9dadc36..e40a0a35633 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/UmezawasJitte.java @@ -65,7 +65,10 @@ public class UmezawasJitte extends CardImpl { this.addAbility(new UmezawasJitteAbility()); // Remove a charge counter from Umezawa's Jitte: Choose one Equipped creature gets +2/+2 until end of turn; or target creature gets -1/-1 until end of turn; or you gain 2 life. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2, Duration.EndOfTurn), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostEquippedEffect(2, 2, Duration.EndOfTurn), + new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())); Mode mode = new Mode(); mode.getEffects().add(new BoostTargetEffect(-1, -1, Duration.EndOfTurn)); mode.getTargets().add(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java b/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java index dc2035a028c..251f4c4d820 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java @@ -31,9 +31,9 @@ package mage.sets.championsofkamigawa; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; @@ -69,7 +69,7 @@ public class KondasBanner extends CardImpl { this.subtype.add("Equipment"); // Konda's Banner can be attached only to a legendary creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect("{this} can be attached only to a legendary creature"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("{this} can be attached only to a legendary creature"))); // Creatures that share a color with equipped creature get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KondasBannerColorBoostEffect())); diff --git a/Mage.Sets/src/mage/sets/coldsnap/LightningStorm.java b/Mage.Sets/src/mage/sets/coldsnap/LightningStorm.java index f537e0031be..601693ea440 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/LightningStorm.java +++ b/Mage.Sets/src/mage/sets/coldsnap/LightningStorm.java @@ -29,13 +29,13 @@ package mage.sets.coldsnap; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -71,7 +71,7 @@ public class LightningStorm extends CardImpl { new LightningStormAddCounterEffect() , new DiscardTargetCost(new TargetCardInHand(new FilterLandCard()))); ability.setMayActivate(TargetController.ANY); - ability.addEffect(new EmptyEffect("Any player may activate this ability but only if {this} is on the stack")); + ability.addEffect(new InfoEffect("Any player may activate this ability but only if {this} is on the stack")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java index 739b8749bdc..609212f2dfb 100644 --- a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java +++ b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java @@ -30,21 +30,15 @@ package mage.sets.commander2013; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import mage.Mana; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.ManaEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.abilities.mana.CommanderColorIdentityManaAbility; -import mage.abilities.mana.ManaAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; diff --git a/Mage.Sets/src/mage/sets/commander2014/LifebloodHydra.java b/Mage.Sets/src/mage/sets/commander2014/LifebloodHydra.java index ff27e65a733..1f167e226a3 100644 --- a/Mage.Sets/src/mage/sets/commander2014/LifebloodHydra.java +++ b/Mage.Sets/src/mage/sets/commander2014/LifebloodHydra.java @@ -94,7 +94,7 @@ class LifebloodHydraComesIntoPlayEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && !permanent.isFaceDown()) { + if (permanent != null && !permanent.isFaceDown(game)) { Object obj = getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (obj != null && obj instanceof SpellAbility) { int amount = ((SpellAbility) obj).getManaCostsToPay().getX(); diff --git a/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java b/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java index 1e12d81a55c..4a0cd73206e 100644 --- a/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java +++ b/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java @@ -27,23 +27,24 @@ */ package mage.sets.darkascension; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import java.util.UUID; + /** * @@ -70,7 +71,7 @@ public class RavagerOfTheFells extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect(rule))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(rule))); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ravager of the Fells. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); diff --git a/Mage.Sets/src/mage/sets/darkascension/WerewolfRansacker.java b/Mage.Sets/src/mage/sets/darkascension/WerewolfRansacker.java index 02677b58c6a..452b74d0faa 100644 --- a/Mage.Sets/src/mage/sets/darkascension/WerewolfRansacker.java +++ b/Mage.Sets/src/mage/sets/darkascension/WerewolfRansacker.java @@ -35,11 +35,11 @@ import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; @@ -72,7 +72,7 @@ public class WerewolfRansacker extends CardImpl { this.toughness = new MageInt(4); // Whenever this creature transforms into Werewolf Ransacker, you may destroy target artifact. If that artifact is put into a graveyard this way, Werewolf Ransacker deals 3 damage to that artifact's controller. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect(WerewolfRansackerAbility.RULE_TEXT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(WerewolfRansackerAbility.RULE_TEXT))); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Werewolf Ransacker. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false); diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkaMonument.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkaMonument.java new file mode 100644 index 00000000000..4cea32a2e49 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/AtarkaMonument.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class AtarkaMonument extends CardImpl { + + public AtarkaMonument(UUID ownerId) { + super(ownerId, 235, "Atarka Monument", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "DTK"; + + // {T}: Add {R} or {G} to your mana pool. + this.addAbility(new RedManaAbility()); + this.addAbility(new GreenManaAbility()); + + // {4}{R}{G}: Atarka Monument becomes a 4/4 red and green Dragon artifact creature with flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect + (new AtarkaMonumentToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{4}{R}{G}"))); + } + + public AtarkaMonument(final AtarkaMonument card) { + super(card); + } + + @Override + public AtarkaMonument copy() { + return new AtarkaMonument(this); + } + + private class AtarkaMonumentToken extends Token { + AtarkaMonumentToken() { + super("", "a 4/4 red and green Dragon artifact creature with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + color.setRed(true); + color.setGreen(true); + this.subtype.add("Dragon"); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/AvatarOfTheResolute.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/AvatarOfTheResolute.java new file mode 100644 index 00000000000..d1de1ad6ad2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/AvatarOfTheResolute.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.CounterPredicate; + +/** + * + * @author jeffwadsworth + */ +public class AvatarOfTheResolute extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other creature you control with a +1/+1 counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.P1P1)); + filter.add(new AnotherPredicate()); + } + + public AvatarOfTheResolute(UUID ownerId) { + super(ownerId, 175, "Avatar of the Resolute", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{G}{G}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Avatar"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Avatar of the Resolute enters the battlefield with a +1/+1 counter on it for each other creature you control with a +1/+1 counter on it. + DynamicValue numberCounters = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), numberCounters, true))); + + } + + public AvatarOfTheResolute(final AvatarOfTheResolute card) { + super(card); + } + + @Override + public AvatarOfTheResolute copy() { + return new AvatarOfTheResolute(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/BelltollDragon.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/BelltollDragon.java new file mode 100644 index 00000000000..ffcd6157581 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/BelltollDragon.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author fireshoes + */ +public class BelltollDragon extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("each other Dragon creature you control"); + + static { + filter.add(new AnotherPredicate()); + filter.add(new SubtypePredicate("Dragon")); + } + + public BelltollDragon(UUID ownerId) { + super(ownerId, 46, "Belltoll Dragon", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Hexproof + this.addAbility(HexproofAbility.getInstance()); + // Megamorph {5}{U}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{5}{U}{U}"), true)); + + // When Belltoll Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control. + this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, false)); + } + + public BelltollDragon(final BelltollDragon card) { + super(card); + } + + @Override + public BelltollDragon copy() { + return new BelltollDragon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CloneLegion.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CloneLegion.java new file mode 100644 index 00000000000..1ab5b09da0b --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CloneLegion.java @@ -0,0 +1,102 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.EmptyToken; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.util.CardUtil; + +/** + * + * @author jeffwadsworth + */ +public class CloneLegion extends CardImpl { + + public CloneLegion(UUID ownerId) { + super(ownerId, 48, "Clone Legion", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{7}{U}{U}"); + this.expansionSetCode = "DTK"; + + // For each creature target player controls, put a token onto the the battlefield that's a copy of that creature. + this.getSpellAbility().addEffect(new CloneLegionEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + + } + + public CloneLegion(final CloneLegion card) { + super(card); + } + + @Override + public CloneLegion copy() { + return new CloneLegion(this); + } +} + +class CloneLegionEffect extends OneShotEffect { + + public CloneLegionEffect() { + super(Outcome.Benefit); + this.staticText = "For each creature target player controls, put a token onto the the battlefield that's a copy of that creature"; + } + + public CloneLegionEffect(final CloneLegionEffect effect) { + super(effect); + } + + @Override + public CloneLegionEffect copy() { + return new CloneLegionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetPlayer != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), targetPlayer.getId(), game)) { + if (permanent != null) { + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(permanent); + token.putOntoBattlefield(1, game, source.getSourceId(), targetPlayer.getId()); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java new file mode 100644 index 00000000000..244a7c9a2fe --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CommuneWithLava.java @@ -0,0 +1,152 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author jeffwadsworth + */ +public class CommuneWithLava extends CardImpl { + + public CommuneWithLava(UUID ownerId) { + super(ownerId, 131, "Commune with Lava", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{R}{R}"); + this.expansionSetCode = "DTK"; + + // Exile the top X cards of your library. Until the end of your next turn, you may play those cards. + this.getSpellAbility().addEffect(new CommuneWithLavaEffect()); + + } + + public CommuneWithLava(final CommuneWithLava card) { + super(card); + } + + @Override + public CommuneWithLava copy() { + return new CommuneWithLava(this); + } +} + +class CommuneWithLavaEffect extends OneShotEffect { + + public CommuneWithLavaEffect() { + super(Outcome.PlayForFree); + this.staticText = "Exile the top X cards of your library. Until the end of your next turn, you may play those cards"; + } + + public CommuneWithLavaEffect(final CommuneWithLavaEffect effect) { + super(effect); + } + + @Override + public CommuneWithLavaEffect copy() { + return new CommuneWithLavaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Card sourceCard = game.getCard(source.getSourceId()); + if (controller != null) { + int amount = source.getManaCostsToPay().getX(); + List cards = controller.getLibrary().getTopCards(game, amount); + for (Card card : cards) { + if (card != null) { + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourceCard.getName(), source.getSourceId(), game, Zone.LIBRARY); + ContinuousEffect effect = new CommuneWithLavaMayPlayEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + } + + return true; + } + return false; + } +} + +class CommuneWithLavaMayPlayEffect extends AsThoughEffectImpl { + + public CommuneWithLavaMayPlayEffect() { + super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, Duration.Custom, Outcome.Benefit); + this.staticText = "Until the end of your next turn, you may play that card."; + } + + public CommuneWithLavaMayPlayEffect(final CommuneWithLavaMayPlayEffect effect) { + super(effect); + } + + @Override + public CommuneWithLavaMayPlayEffect copy() { + return new CommuneWithLavaMayPlayEffect(this); + } + + @Override + public boolean isInactive(Ability source, Game game) { + if (game.getPhase().getStep().getType() == PhaseStep.END_TURN) { + if (game.getActivePlayerId().equals(source.getControllerId())) { + return true; + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + if (targetPointer.getTargets(game, source).contains(sourceId)) { + return game.getState().getZone(sourceId).equals(Zone.EXILED); + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/CustodianOfTheTrove.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/CustodianOfTheTrove.java new file mode 100644 index 00000000000..9948041f17f --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/CustodianOfTheTrove.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.keyword.DefenderAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ +public class CustodianOfTheTrove extends CardImpl { + + public CustodianOfTheTrove(UUID ownerId) { + super(ownerId, 236, "Custodian of the Trove", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Golem"); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + + // Custodian of the Trove enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + } + + public CustodianOfTheTrove(final CustodianOfTheTrove card) { + super(card); + } + + @Override + public CustodianOfTheTrove copy() { + return new CustodianOfTheTrove(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonTempest.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonTempest.java new file mode 100644 index 00000000000..a4680796326 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DragonTempest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class DragonTempest extends CardImpl { + + private static final FilterCreaturePermanent filterFlying = new FilterCreaturePermanent("a creature with flying"); + + static { + filterFlying.add(new AbilityPredicate(FlyingAbility.class)); + } + + public DragonTempest(UUID ownerId) { + super(ownerId, 136, "Dragon Tempest", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + this.expansionSetCode = "DTK"; + + // Whenever a creature with flying enters the battlefield under your control, it gains haste until the end of turn. + Effect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); + effect.setText("it gains haste until the end of turn"); + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filterFlying, false, SetTargetPointer.PERMANENT, "")); + + // Whenever a Dragon enters the battlefield under your control, it deals X damage to target creature or player, where X is the number of Dragons you control. + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, + new DragonTempestDamageEffect(), + new FilterCreaturePermanent("Dragon", "a Dragon"), + false, + SetTargetPointer.PERMANENT, + "" + ); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + + } + + public DragonTempest(final DragonTempest card) { + super(card); + } + + @Override + public DragonTempest copy() { + return new DragonTempest(this); + } +} + +class DragonTempestDamageEffect extends OneShotEffect { + + private static final FilterControlledPermanent dragonFilter = new FilterControlledPermanent(); + + static { + dragonFilter.add(new SubtypePredicate("Dragon")); + } + + public DragonTempestDamageEffect() { + super(Outcome.Damage); + staticText = "it deals X damage to target creature or player, where X is the number of Dragons you control"; + } + + public DragonTempestDamageEffect(final DragonTempestDamageEffect effect) { + super(effect); + } + + @Override + public DragonTempestDamageEffect copy() { + return new DragonTempestDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int amount = game.getBattlefield().countAll(dragonFilter, controller.getId(), game); + if (amount > 0) { + Permanent targetCreature = game.getPermanent(source.getTargets().getFirstTarget()); + if (targetCreature != null) { + targetCreature.damage(amount, getTargetPointer().getFirst(game, source), game, false, true); + } else { + Player player = game.getPlayer(source.getTargets().getFirstTarget()); + if (player != null) { + player.damage(amount, getTargetPointer().getFirst(game, source), game, false, true); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokaMonument.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokaMonument.java new file mode 100644 index 00000000000..eba91177521 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokaMonument.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class DromokaMonument extends CardImpl { + + public DromokaMonument(UUID ownerId) { + super(ownerId, 238, "Dromoka Monument", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "DTK"; + + // {T}: Add {G} or {W} to your mana pool. + this.addAbility(new GreenManaAbility()); + this.addAbility(new WhiteManaAbility()); + + // {4}{G}{W}: Dromoka Monument becomes a 4/4 green and white Dragon artifact creature with flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect + (new DromokaMonumentToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{4}{G}{W}"))); + } + + public DromokaMonument(final DromokaMonument card) { + super(card); + } + + @Override + public DromokaMonument copy() { + return new DromokaMonument(this); + } + + private class DromokaMonumentToken extends Token { + DromokaMonumentToken() { + super("", "a 4/4 green and white Dragon artifact creature with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + color.setGreen(true); + color.setWhite(true); + this.subtype.add("Dragon"); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + } + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokasCommand.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokasCommand.java new file mode 100644 index 00000000000..070a1dc56ab --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DromokasCommand.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.PreventDamageByTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.FilterStackObject; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPlayer; +import mage.target.TargetStackObject; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public class DromokasCommand extends CardImpl { + + private static final FilterStackObject filterInstantOrSorcery = new FilterStackObject("instant or sorcery spell"); + private static final FilterPermanent filterEnchantment = new FilterPermanent("enchantment"); + private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature to put the +1/+1 counter on"); + private static final FilterCreaturePermanent filterUncontrolledCreature = new FilterCreaturePermanent("creature you don't control"); + + static { + filterInstantOrSorcery.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); + filterUncontrolledCreature.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public DromokasCommand(UUID ownerId) { + super(ownerId, 221, "Dromoka's Command", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{G}{W}"); + this.expansionSetCode = "DTK"; + + // Choose two - Prevent all damage target instant or sorcery spell would deal this turn; Target player sacrifices an enchantment; Put a +1/+1 counter on target creature; or Target creature you control fights target creature you don't control. + this.getSpellAbility().getModes().setMinModes(2); + this.getSpellAbility().getModes().setMaxModes(2); + + // Prevent all damage target instant or sorcery spell would deal this turn; + this.getSpellAbility().getEffects().add(new PreventDamageByTargetEffect(Duration.EndOfTurn)); + this.getSpellAbility().getTargets().add(new TargetStackObject(filterInstantOrSorcery)); + + // or Target player sacrifices an enchantment; + Mode mode = new Mode(); + mode.getEffects().add(new SacrificeEffect(filterEnchantment, 1, "target player")); + mode.getTargets().add(new TargetPlayer()); + this.getSpellAbility().getModes().addMode(mode); + + // Put a +1/+1 counter on target creature; + mode = new Mode(); + mode.getEffects().add(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + mode.getTargets().add(new TargetCreaturePermanent(filterCreature)); + this.getSpellAbility().getModes().addMode(mode); + + // or Target creature you control fights target creature you don't control. + mode = new Mode(); + Effect effect = new FightTargetsEffect(); + effect.setText("Target creature you control fights target creature you don't control"); + mode.getEffects().add(effect); + mode.getTargets().add(new TargetControlledCreaturePermanent()); + mode.getTargets().add(new TargetCreaturePermanent(filterUncontrolledCreature)); + this.getSpellAbility().getModes().addMode(mode); + + } + + public DromokasCommand(final DromokasCommand card) { + super(card); + } + + @Override + public DromokasCommand copy() { + return new DromokasCommand(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Duress.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Duress.java new file mode 100644 index 00000000000..f722c04e80b --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Duress.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Duress extends mage.sets.magic2010.Duress { + + public Duress(UUID ownerId) { + super(ownerId); + this.cardNumber = 98; + this.expansionSetCode = "DTK"; + } + + public Duress(final Duress card) { + super(card); + } + + @Override + public Duress copy() { + return new Duress(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest1.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest1.java new file mode 100644 index 00000000000..c6a116f669a --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest1.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Forest1 extends mage.cards.basiclands.Forest { + + public Forest1(UUID ownerId) { + super(ownerId, 262); + this.expansionSetCode = "DTK"; + } + + public Forest1(final Forest1 card) { + super(card); + } + + @Override + public Forest1 copy() { + return new Forest1(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest2.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest2.java new file mode 100644 index 00000000000..44d6742fd1e --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest2.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Forest2 extends mage.cards.basiclands.Forest { + + public Forest2(UUID ownerId) { + super(ownerId, 263); + this.expansionSetCode = "DTK"; + } + + public Forest2(final Forest2 card) { + super(card); + } + + @Override + public Forest2 copy() { + return new Forest2(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest3.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest3.java new file mode 100644 index 00000000000..d99f8fb4b75 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Forest3.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Forest3 extends mage.cards.basiclands.Forest { + + public Forest3(UUID ownerId) { + super(ownerId, 264); + this.expansionSetCode = "DTK"; + } + + public Forest3(final Forest3 card) { + super(card); + } + + @Override + public Forest3 copy() { + return new Forest3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/HavenOfTheSpiritDragon.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/HavenOfTheSpiritDragon.java new file mode 100644 index 00000000000..b8f4ce26ffa --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/HavenOfTheSpiritDragon.java @@ -0,0 +1,167 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +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.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.abilities.mana.conditional.CreatureCastManaCondition; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author jeffwadsworth + */ +public class HavenOfTheSpiritDragon extends CardImpl { + + private static final FilterCard filter = new FilterCard("Dragon creature card or Ugin planeswalker card from your graveyard"); + + static { + filter.add(Predicates.or(new DragonCreatureCardPredicate(), + new UginPlaneswalkerCardPredicate())); + } + + public HavenOfTheSpiritDragon(UUID ownerId) { + super(ownerId, 249, "Haven of the Spirit Dragon", Rarity.RARE, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "DTK"; + + // {T}: Add {1} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {T}: add one mana of any color to your mana pool. Spend this mana only to cast a Dragon creature spell. + this.addAbility(new ConditionalAnyColorManaAbility(new TapSourceCost(), 1, new HavenOfTheSpiritManaBuilder(), true)); + + // {2}, {T}, Sacrifice Haven of the Spirit Dragon: Return target Dragon creature card or Ugin planeswalker card from your graveyard to your hand. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{2}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + + } + + public HavenOfTheSpiritDragon(final HavenOfTheSpiritDragon card) { + super(card); + } + + @Override + public HavenOfTheSpiritDragon copy() { + return new HavenOfTheSpiritDragon(this); + } +} + +class HavenOfTheSpiritManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + this.mana.setFlag(true); // indicates that the mana is from second ability + return new HavenOfTheSpiritConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast a Dragon creature spell."; + } +} + +class HavenOfTheSpiritConditionalMana extends ConditionalMana { + + HavenOfTheSpiritConditionalMana(Mana mana) { + super(mana); + staticText = "Spend this mana only to cast a Dragon creature spell."; + addCondition(new HavenOfTheSpiritManaCondition()); + } +} + +class HavenOfTheSpiritManaCondition extends CreatureCastManaCondition { + + @Override + public boolean apply(Game game, Ability source, UUID manaProducer) { + if (super.apply(game, source)) { + MageObject object = game.getObject(source.getSourceId()); + if (object.hasSubtype("Dragon") + && object.getCardType().contains(CardType.CREATURE)) { + return true; + } + } + return false; + } +} + +class DragonCreatureCardPredicate implements Predicate { + + public DragonCreatureCardPredicate() { + } + + @Override + public boolean apply(Card input, Game game) { + return input.getCardType().contains(CardType.CREATURE) + && input.getSubtype().contains("Dragon"); + } + + @Override + public String toString() { + return ""; + } +} + +class UginPlaneswalkerCardPredicate implements Predicate { + + public UginPlaneswalkerCardPredicate() { + } + + @Override + public boolean apply(Card input, Game game) { + return input.getCardType().contains(CardType.PLANESWALKER) + && input.getName().contains("Ugin, the Spirit Dragon"); + } + + @Override + public String toString() { + return ""; + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java new file mode 100644 index 00000000000..3da5dcad708 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/IcefallRegent.java @@ -0,0 +1,239 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import static mage.filter.predicate.permanent.ControllerControlsIslandPredicate.filter; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; +import mage.watchers.Watcher; + +/** + * + * @author fireshoes + */ +public class IcefallRegent extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public IcefallRegent(UUID ownerId) { + super(ownerId, 58, "Icefall Regent", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Icefall Regent enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's untap step for as long as you control Icefall Regent. + Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false); + ability.addEffect(new IcefallRegentEffect()); + Target target = new TargetCreaturePermanent(filter); + ability.addTarget(target); + this.addAbility(ability, new IcefallRegentWatcher()); + + // Spells your opponents cast that target Icefall Regent cost {2} more to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IcefallRegentCostIncreaseEffect())); + + } + + public IcefallRegent(final IcefallRegent card) { + super(card); + } + + @Override + public IcefallRegent copy() { + return new IcefallRegent(this); + } +} + +class IcefallRegentEffect extends ContinuousRuleModifyingEffectImpl { + + public IcefallRegentEffect() { + super(Duration.Custom, Outcome.Detriment, false, false); + this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}"; + } + + public IcefallRegentEffect(final IcefallRegentEffect effect) { + super(effect); + } + + @Override + public IcefallRegentEffect copy() { + return new IcefallRegentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + // Source must be on the battlefield (it's neccessary to check here because if as response to the enter + // the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL + // event will happen before this effect is applied ever) + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { + this.used = true; + return false; + } + if (event.getType() == GameEvent.EventType.LOST_CONTROL) { + if (event.getTargetId().equals(source.getSourceId())) { + discard(); + return false; + } + } + if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent)event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + discard(); + return false; + } + } + + if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { + if (event.getTargetId().equals(targetPointer.getFirst(game, source))) { + return true; + } + } + + return false; + } +} + +class IcefallRegentWatcher extends Watcher { + + IcefallRegentWatcher () { + super("ControlLost", WatcherScope.CARD); + } + + IcefallRegentWatcher(IcefallRegentWatcher watcher) { + super(watcher); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.LOST_CONTROL && event.getPlayerId().equals(controllerId) && event.getTargetId().equals(sourceId)) { + condition = true; + game.replaceEvent(event); + return; + } + if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) { + ZoneChangeEvent zEvent = (ZoneChangeEvent)event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + condition = true; + game.replaceEvent(event); + } + } + } + + @Override + public void reset() { + //don't reset condition each turn - only when this leaves the battlefield + } + + @Override + public IcefallRegentWatcher copy() { + return new IcefallRegentWatcher(this); + } +} + +class IcefallRegentCostIncreaseEffect extends CostModificationEffectImpl { + + private static final String effectText = "Spells your opponents cast that target Icefall Regent cost {2} more to cast"; + + IcefallRegentCostIncreaseEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = effectText; + } + + IcefallRegentCostIncreaseEffect(IcefallRegentCostIncreaseEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + SpellAbility spellAbility = (SpellAbility) abilityToModify; + CardUtil.adjustCost(spellAbility, -2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify instanceof SpellAbility) { + if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { + for (Target target :abilityToModify.getTargets()) { + for (UUID targetUUID :target.getTargets()) { + if (targetUUID.equals(source.getSourceId())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public IcefallRegentCostIncreaseEffect copy() { + return new IcefallRegentCostIncreaseEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Island1.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island1.java new file mode 100644 index 00000000000..3d280423186 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island1.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Island1 extends mage.cards.basiclands.Island { + + public Island1(UUID ownerId) { + super(ownerId, 253); + this.expansionSetCode = "DTK"; + } + + public Island1(final Island1 card) { + super(card); + } + + @Override + public Island1 copy() { + return new Island1(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Island2.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island2.java new file mode 100644 index 00000000000..ce5253ed0d0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island2.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Island2 extends mage.cards.basiclands.Island { + + public Island2(UUID ownerId) { + super(ownerId, 254); + this.expansionSetCode = "DTK"; + } + + public Island2(final Island2 card) { + super(card); + } + + @Override + public Island2 copy() { + return new Island2(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Island3.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island3.java new file mode 100644 index 00000000000..e1a28667f0c --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Island3.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Island3 extends mage.cards.basiclands.Island { + + public Island3(UUID ownerId) { + super(ownerId, 255); + this.expansionSetCode = "DTK"; + } + + public Island3(final Island3 card) { + super(card); + } + + @Override + public Island3 copy() { + return new Island3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/KolaghanMonument.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/KolaghanMonument.java new file mode 100644 index 00000000000..11f07ce8320 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/KolaghanMonument.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class KolaghanMonument extends CardImpl { + + public KolaghanMonument(UUID ownerId) { + super(ownerId, 241, "Kolaghan Monument", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "DTK"; + + // {T}: Add {B} or {R} to your mana pool. + this.addAbility(new BlackManaAbility()); + this.addAbility(new RedManaAbility()); + + // {4}{B}{R}: Kolaghan Monument becomes a 4/4 black and red Dragon artifact creature with flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect + (new KolaghanMonumentToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{4}{B}{R}"))); + } + + public KolaghanMonument(final KolaghanMonument card) { + super(card); + } + + @Override + public KolaghanMonument copy() { + return new KolaghanMonument(this); + } + + private class KolaghanMonumentToken extends Token { + KolaghanMonumentToken() { + super("", "a 4/4 black and red Dragon artifact creature with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + color.setBlack(true); + color.setRed(true); + this.subtype.add("Dragon"); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + } + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain1.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain1.java new file mode 100644 index 00000000000..8cfcca781e8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain1.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Mountain1 extends mage.cards.basiclands.Mountain { + + public Mountain1(UUID ownerId) { + super(ownerId, 259); + this.expansionSetCode = "DTK"; + } + + public Mountain1(final Mountain1 card) { + super(card); + } + + @Override + public Mountain1 copy() { + return new Mountain1(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain2.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain2.java new file mode 100644 index 00000000000..def97c37f27 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain2.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Mountain2 extends mage.cards.basiclands.Mountain { + + public Mountain2(UUID ownerId) { + super(ownerId, 260); + this.expansionSetCode = "DTK"; + } + + public Mountain2(final Mountain2 card) { + super(card); + } + + @Override + public Mountain2 copy() { + return new Mountain2(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain3.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain3.java new file mode 100644 index 00000000000..434fa1f98c6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Mountain3.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Mountain3 extends mage.cards.basiclands.Mountain { + + public Mountain3(UUID ownerId) { + super(ownerId, 261); + this.expansionSetCode = "DTK"; + } + + public Mountain3(final Mountain3 card) { + super(card); + } + + @Override + public Mountain3 copy() { + return new Mountain3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiMonument.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiMonument.java new file mode 100644 index 00000000000..26e8659b811 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/OjutaiMonument.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class OjutaiMonument extends CardImpl { + + public OjutaiMonument(UUID ownerId) { + super(ownerId, 242, "Ojutai Monument", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "DTK"; + + // {T}: Add {W} or {U} to your mana pool. + this.addAbility(new WhiteManaAbility()); + this.addAbility(new BlueManaAbility()); + + // {4}{W}{U}: Ojutai Monument becomes a 4/4 white and blue Dragon artifact creature with flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect + (new OjutaiMonumentToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{4}{W}{U}"))); + } + + public OjutaiMonument(final OjutaiMonument card) { + super(card); + } + + @Override + public OjutaiMonument copy() { + return new OjutaiMonument(this); + } + + private class OjutaiMonumentToken extends Token { + OjutaiMonumentToken() { + super("", "a 4/4 white and blue Dragon artifact creature with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + color.setWhite(true); + color.setBlue(true); + this.subtype.add("Dragon"); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + } + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains1.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains1.java new file mode 100644 index 00000000000..323667257ae --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains1.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Plains1 extends mage.cards.basiclands.Plains { + + public Plains1(UUID ownerId) { + super(ownerId, 250); + this.expansionSetCode = "DTK"; + } + + public Plains1(final Plains1 card) { + super(card); + } + + @Override + public Plains1 copy() { + return new Plains1(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains2.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains2.java new file mode 100644 index 00000000000..dd2a5aeab47 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains2.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Plains2 extends mage.cards.basiclands.Plains { + + public Plains2(UUID ownerId) { + super(ownerId, 251); + this.expansionSetCode = "DTK"; + } + + public Plains2(final Plains2 card) { + super(card); + } + + @Override + public Plains2 copy() { + return new Plains2(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains3.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains3.java new file mode 100644 index 00000000000..d9fcab8e7fc --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Plains3.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Plains3 extends mage.cards.basiclands.Plains { + + public Plains3(UUID ownerId) { + super(ownerId, 252); + this.expansionSetCode = "DTK"; + } + + public Plains3(final Plains3 card) { + super(card); + } + + @Override + public Plains3 copy() { + return new Plains3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ScionOfUgin.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ScionOfUgin.java new file mode 100644 index 00000000000..594c68346c4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ScionOfUgin.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ +public class ScionOfUgin extends CardImpl { + + public ScionOfUgin(UUID ownerId) { + super(ownerId, 1, "Scion of Ugin", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{6}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Dragon"); + this.subtype.add("Spirit"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + } + + public ScionOfUgin(final ScionOfUgin card) { + super(card); + } + + @Override + public ScionOfUgin copy() { + return new ScionOfUgin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/ShorecrasherElemental.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/ShorecrasherElemental.java index ddd21920b5a..a5a297bcab9 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/ShorecrasherElemental.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/ShorecrasherElemental.java @@ -107,8 +107,7 @@ class ShorecrasherElementalEffect extends OneShotEffect { if (shorecrasherElemental.moveToExile(source.getSourceId(), "Shorecrasher Elemental", source.getSourceId(), game)) { Card card = game.getExile().getCard(source.getSourceId(), game); if (card != null) { - card.setFaceDown(true); - return card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false); + return card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), card.getOwnerId(), false, true); } } } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarMonument.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarMonument.java new file mode 100644 index 00000000000..3436a43eff7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SilumgarMonument.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.permanent.token.Token; + +/** + * + * @author fireshoes + */ +public class SilumgarMonument extends CardImpl { + + public SilumgarMonument(UUID ownerId) { + super(ownerId, 243, "Silumgar Monument", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "DTK"; + + // {T}: Add {U} or {B} to your mana pool. + this.addAbility(new BlueManaAbility()); + this.addAbility(new BlackManaAbility()); + + // {4}{U}{B}: Silumgar Monument becomes a 4/4 blue and black Dragon artifact creature with flying until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect + (new OjutaiMonumentToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{4}{U}{B}"))); + } + + public SilumgarMonument(final SilumgarMonument card) { + super(card); + } + + @Override + public SilumgarMonument copy() { + return new SilumgarMonument(this); + } + +private class OjutaiMonumentToken extends Token { + OjutaiMonumentToken() { + super("", "a 4/4 blue and black Dragon artifact creature with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + color.setBlue(true); + color.setBlack(true); + this.subtype.add("Dragon"); + power = new MageInt(4); + toughness = new MageInt(4); + this.addAbility(FlyingAbility.getInstance()); + } + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SurrakTheHuntCaller.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SurrakTheHuntCaller.java new file mode 100644 index 00000000000..7e08f5bb3d7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SurrakTheHuntCaller.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.condition.common.FormidableCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author fireshoes + */ +public class SurrakTheHuntCaller extends CardImpl { + + public SurrakTheHuntCaller(UUID ownerId) { + super(ownerId, 210, "Surrak, the Hunt Caller", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "DTK"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Warrior"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Formidable - At the beginning of combat on your turn, if creatures you control have total power 8 or greater, target creature you control gains haste until end of turn. + Ability ability = new ConditionalTriggeredAbility( + new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), TargetController.YOU, false), + FormidableCondition.getInstance(), + "Formidable — Whenever {this} attacks, if creatures you control have total power 8 or greater, creatures you control gain trample until end of turn."); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + } + + public SurrakTheHuntCaller(final SurrakTheHuntCaller card) { + super(card); + } + + @Override + public SurrakTheHuntCaller copy() { + return new SurrakTheHuntCaller(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp1.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp1.java new file mode 100644 index 00000000000..08121a8a729 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp1.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Swamp1 extends mage.cards.basiclands.Swamp { + + public Swamp1(UUID ownerId) { + super(ownerId, 256); + this.expansionSetCode = "DTK"; + } + + public Swamp1(final Swamp1 card) { + super(card); + } + + @Override + public Swamp1 copy() { + return new Swamp1(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp2.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp2.java new file mode 100644 index 00000000000..68e30e2d267 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp2.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Swamp2 extends mage.cards.basiclands.Swamp { + + public Swamp2(UUID ownerId) { + super(ownerId, 257); + this.expansionSetCode = "DTK"; + } + + public Swamp2(final Swamp2 card) { + super(card); + } + + @Override + public Swamp2 copy() { + return new Swamp2(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp3.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp3.java new file mode 100644 index 00000000000..a9400ba83bc --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/Swamp3.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; + +/** + * + * @author fireshoes + */ +public class Swamp3 extends mage.cards.basiclands.Swamp { + + public Swamp3(UUID ownerId) { + super(ownerId, 258); + this.expansionSetCode = "DTK"; + } + + public Swamp3(final Swamp3 card) { + super(card); + } + + @Override + public Swamp3 copy() { + return new Swamp3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/WanderingTombshell.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/WanderingTombshell.java new file mode 100644 index 00000000000..cdbaab82c18 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/WanderingTombshell.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.dragonsoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ +public class WanderingTombshell extends CardImpl { + + public WanderingTombshell(UUID ownerId) { + super(ownerId, 127, "Wandering Tombshell", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.expansionSetCode = "DTK"; + this.subtype.add("Zombie"); + this.subtype.add("Turtle"); + this.power = new MageInt(1); + this.toughness = new MageInt(6); + } + + public WanderingTombshell(final WanderingTombshell card) { + super(card); + } + + @Override + public WanderingTombshell copy() { + return new WanderingTombshell(this); + } +} diff --git a/Mage.Sets/src/mage/sets/exodus/CursedFlesh.java b/Mage.Sets/src/mage/sets/exodus/CursedFlesh.java new file mode 100644 index 00000000000..90d3427bb91 --- /dev/null +++ b/Mage.Sets/src/mage/sets/exodus/CursedFlesh.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.exodus; + +import java.util.UUID; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class CursedFlesh extends mage.sets.invasion.CursedFlesh { + + public CursedFlesh(UUID ownerId) { + super(ownerId); + this.cardNumber = 56; + this.expansionSetCode = "EXO"; + } + + public CursedFlesh(final CursedFlesh card) { + super(card); + } + + @Override + public CursedFlesh copy() { + return new CursedFlesh(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java b/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java index 34f0260ba11..5f8d251556c 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java +++ b/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java @@ -99,14 +99,12 @@ class GhastlyConscriptionEffect extends OneShotEffect { for(Card card: targetPlayer.getGraveyard().getCards(new FilterCreatureCard(), game)) { cardsToManifest.add(card); controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD); - card.setFaceDown(true); } Collections.shuffle(cardsToManifest); game.informPlayers(controller.getName() + " shuffles the face-down pile"); Ability newSource = source.copy(); newSource.setWorksFaceDown(true); for (Card card: cardsToManifest) { - card.setFaceDown(true); ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -116,7 +114,7 @@ class GhastlyConscriptionEffect extends OneShotEffect { } MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId())) { + if (controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), false, true)) { game.informPlayers(new StringBuilder(controller.getName()) .append(" puts facedown card from exile onto the battlefield").toString()); } diff --git a/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java b/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java index 30aea7685ea..b1e7ad2abdf 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java +++ b/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java @@ -114,12 +114,10 @@ class JeskaiInfiltratorEffect extends OneShotEffect { Card sourceCard = game.getCard(source.getSourceId()); if (sourcePermanent != null && sourceCard != null) { player.moveCardToExileWithInfo(sourcePermanent, sourcePermanent.getId(), sourcePermanent.getName(), source.getSourceId(), game, Zone.BATTLEFIELD); - sourceCard.setFaceDown(true); cardsToManifest.add(sourceCard); } if (sourcePermanent!= null && player.getLibrary().size() > 0) { Card cardFromLibrary = player.getLibrary().removeFromTop(game); - cardFromLibrary.setFaceDown(true); player.moveCardToExileWithInfo(cardFromLibrary, sourcePermanent.getId(), sourcePermanent.getName(), source.getSourceId(), game, Zone.LIBRARY); cardsToManifest.add(cardFromLibrary); } @@ -128,7 +126,6 @@ class JeskaiInfiltratorEffect extends OneShotEffect { Ability newSource = source.copy(); newSource.setWorksFaceDown(true); for (Card card : cardsToManifest) { - card.setFaceDown(true); ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -138,7 +135,7 @@ class JeskaiInfiltratorEffect extends OneShotEffect { } MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - if (card.moveToZone(Zone.BATTLEFIELD, newSource.getSourceId(), game, false)) { + if (player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), false, true)) { game.informPlayers(new StringBuilder(player.getName()) .append(" puts facedown card from exile onto the battlefield").toString()); } diff --git a/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java b/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java index ecb14fc5433..80d44e24226 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/SummonersEgg.java @@ -97,8 +97,8 @@ class SummonersEggImprintEffect extends OneShotEffect { && controller.choose(Outcome.Benefit, controller.getHand(), target, game)) { Card card = controller.getHand().get(target.getFirstTarget(), game); if (card != null) { - card.setFaceDown(true); controller.moveCardToExileWithInfo(card, source.getSourceId(), sourcePermanent.getLogName() +" (Imprint)", source.getSourceId(), game, Zone.HAND); + card.setFaceDown(true, game); Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); diff --git a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java index 86e783c8e38..a1db6a6bace 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java +++ b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java @@ -105,7 +105,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/gatecrash/BaneAlleyBroker.java b/Mage.Sets/src/mage/sets/gatecrash/BaneAlleyBroker.java index a4ec98fd2ec..bff58c49db1 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/BaneAlleyBroker.java +++ b/Mage.Sets/src/mage/sets/gatecrash/BaneAlleyBroker.java @@ -146,8 +146,10 @@ class BaneAlleyBrokerDrawExileEffect extends OneShotEffect { Card card = game.getCard(target.getFirstTarget()); MageObject sourceObject = game.getObject(source.getSourceId()); if (card != null && sourceObject != null) { - card.setFaceDown(true); - return card.moveToExile(CardUtil.getCardExileZoneId(game, source), new StringBuilder(sourceObject.getLogName()).toString(), source.getSourceId(), game); + if (card.moveToExile(CardUtil.getCardExileZoneId(game, source), new StringBuilder(sourceObject.getLogName()).toString(), source.getSourceId(), game)) { + card.setFaceDown(true, game); + return true; + } } } } diff --git a/Mage.Sets/src/mage/sets/iceage/Necropotence.java b/Mage.Sets/src/mage/sets/iceage/Necropotence.java index 4780c1fc638..fea8b3cfd25 100644 --- a/Mage.Sets/src/mage/sets/iceage/Necropotence.java +++ b/Mage.Sets/src/mage/sets/iceage/Necropotence.java @@ -136,8 +136,8 @@ class NecropotenceEffect extends OneShotEffect { if (controller != null) { if (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); - card.setFaceDown(true); if (controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY)) { + card.setFaceDown(true, game); Effect returnToHandeffect = new ReturnToHandTargetEffect(); returnToHandeffect.setText("put that face down card into your hand"); returnToHandeffect.setTargetPointer(new FixedTarget(card.getId())); diff --git a/Mage.Sets/src/mage/sets/invasion/CursedFlesh.java b/Mage.Sets/src/mage/sets/invasion/CursedFlesh.java new file mode 100644 index 00000000000..33ff2ca394e --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/CursedFlesh.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +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.FearAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class CursedFlesh extends CardImpl { + + public CursedFlesh(UUID ownerId) { + super(ownerId, 98, "Cursed Flesh", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature gets -1/-1 and has fear. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(-1, -1, Duration.WhileOnBattlefield)); + ability.addEffect(new GainAbilityAttachedEffect(FearAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield, "and has fear")); + this.addAbility(ability); + } + + public CursedFlesh(final CursedFlesh card) { + super(card); + } + + @Override + public CursedFlesh copy() { + return new CursedFlesh(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/SunscapeMaster.java b/Mage.Sets/src/mage/sets/invasion/SunscapeMaster.java new file mode 100644 index 00000000000..d89037c0b5d --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/SunscapeMaster.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class SunscapeMaster extends CardImpl { + + public SunscapeMaster(UUID ownerId) { + super(ownerId, 42, "Sunscape Master", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {G}{G}, {tap}: Creatures you control get +2/+2 until end of turn. + Effect effect1 = new BoostControlledEffect(2, 2, Duration.EndOfTurn); + effect1.setText("Creatures you control get +2/+2 until end of turn"); + Ability ability1 = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect1, new ManaCostsImpl("{G}{G}")); + ability1.addCost(new TapSourceCost()); + this.addAbility(ability1); + + // {U}{U}, {tap}: Return target creature to its owner's hand. + Effect effect2 = new ReturnToHandTargetEffect(); + effect2.setText("Return target creature to its owner's hand."); + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect2, new ManaCostsImpl("{U}{U}")); + ability2.addTarget(new TargetCreaturePermanent()); + ability2.addCost(new TapSourceCost()); + this.addAbility(ability2); + } + + public SunscapeMaster(final SunscapeMaster card) { + super(card); + } + + @Override + public SunscapeMaster copy() { + return new SunscapeMaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/VodalianMerchant.java b/Mage.Sets/src/mage/sets/invasion/VodalianMerchant.java new file mode 100644 index 00000000000..a2fadce6676 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/VodalianMerchant.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class VodalianMerchant extends CardImpl { + + public VodalianMerchant(UUID ownerId) { + super(ownerId, 85, "Vodalian Merchant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Merfolk"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // When Vodalian Merchant enters the battlefield, draw a card, then discard a card. + this.addAbility(new EntersBattlefieldAbility(new DrawDiscardControllerEffect(1, 1, false))); + } + + public VodalianMerchant(final VodalianMerchant card) { + super(card); + } + + @Override + public VodalianMerchant copy() { + return new VodalianMerchant(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/YavimayaKavu.java b/Mage.Sets/src/mage/sets/invasion/YavimayaKavu.java new file mode 100644 index 00000000000..c6246778f3d --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/YavimayaKavu.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.SetPowerSourceEffect; +import mage.abilities.effects.common.continuous.SetToughnessSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author michael.napoleon@gmail.com + */ +public class YavimayaKavu extends CardImpl { + + private static final FilterCreaturePermanent filterGreenCreature = new FilterCreaturePermanent("green creatures on the battlefield"); + private static final FilterCreaturePermanent filterRedCreature = new FilterCreaturePermanent("red creatures on the battlefield"); + + static { + filterGreenCreature.add(new ColorPredicate(ObjectColor.GREEN)); + filterRedCreature.add(new ColorPredicate(ObjectColor.RED)); + } + + public YavimayaKavu(UUID ownerId) { + super(ownerId, 291, "Yavimaya Kavu", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{G}"); + this.expansionSetCode = "INV"; + this.subtype.add("Kavu"); + this.power = new MageInt(0); + this.toughness = new MageInt(0); + + + // Yavimaya Kavu's power is equal to the number of red creatures on the battlefield. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerSourceEffect(new PermanentsOnBattlefieldCount(filterRedCreature), Duration.EndOfGame))); + // Yavimaya Kavu's toughness is equal to the number of green creatures on the battlefield. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetToughnessSourceEffect(new PermanentsOnBattlefieldCount(filterGreenCreature), Duration.EndOfGame))); + } + + public YavimayaKavu(final YavimayaKavu card) { + super(card); + } + + @Override + public YavimayaKavu copy() { + return new YavimayaKavu(this); + } +} diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java b/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java index 7be5d08eee1..5cf4a82c50c 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/KeranosGodOfStorms.java @@ -30,12 +30,12 @@ package mage.sets.journeyintonyx; import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.DevotionCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.Card; @@ -99,7 +99,7 @@ class KeranosGodOfStormsTriggeredAbility extends TriggeredAbilityImpl { private int lastTriggeredTurn; KeranosGodOfStormsTriggeredAbility() { - super(Zone.BATTLEFIELD, new EmptyEffect(""), false); + super(Zone.BATTLEFIELD, new InfoEffect(""), false); } KeranosGodOfStormsTriggeredAbility(final KeranosGodOfStormsTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java b/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java index fadc4cae4ce..5a03885f3d5 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java @@ -112,8 +112,7 @@ class AshcloudPhoenixEffect extends OneShotEffect { if (card != null) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null && owner.getGraveyard().contains(card.getId())) { - card.setFaceDown(true); - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), false, true); } } return true; diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java b/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java index 3a41006dd84..cae5e775c3f 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java @@ -120,7 +120,7 @@ class EfreetWeaponmasterAbility extends TriggeredAbilityImpl { } if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/GhostfireBlade.java b/Mage.Sets/src/mage/sets/khansoftarkir/GhostfireBlade.java index fada6189792..9d62871250a 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/GhostfireBlade.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/GhostfireBlade.java @@ -29,9 +29,9 @@ package mage.sets.khansoftarkir; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; @@ -61,7 +61,7 @@ public class GhostfireBlade extends CardImpl { this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(3))); // Ghostfire Blade's equip ability costs {2} less to activate if it targets a colorless creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect("{this}'s equip ability costs {2} less to activate if it targets a colorless creature"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("{this}'s equip ability costs {2} less to activate if it targets a colorless creature"))); } @Override public void adjustCosts(Ability ability, Game game) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/HoodedHydra.java b/Mage.Sets/src/mage/sets/khansoftarkir/HoodedHydra.java index d5e3ab1d6aa..c4762f87199 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/HoodedHydra.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/HoodedHydra.java @@ -111,7 +111,7 @@ class HoodedHydraEffect1 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && !permanent.isFaceDown()) { + if (permanent != null && !permanent.isFaceDown(game)) { Object obj = getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (obj != null && obj instanceof SpellAbility) { int amount = ((SpellAbility) obj).getManaCostsToPay().getX(); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java b/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java index 3546d190a32..e20963a0d1e 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java @@ -184,7 +184,7 @@ class LensOfClarityLookFaceDownEffect extends OneShotEffect { Permanent faceDownCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (faceDownCreature != null) { Permanent copyFaceDown = faceDownCreature.copy(); - copyFaceDown.setFaceDown(false); + copyFaceDown.setFaceDown(false, game); Cards cards = new CardsImpl(); cards.add(copyFaceDown); Player player = game.getPlayer(faceDownCreature.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java b/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java index 8fa63732235..d81f97c68fd 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java @@ -107,7 +107,7 @@ class PonybackBrigadeAbility extends TriggeredAbilityImpl { } if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SmokeTeller.java b/Mage.Sets/src/mage/sets/khansoftarkir/SmokeTeller.java index 2cffd937136..7c00d2fb3f9 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SmokeTeller.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SmokeTeller.java @@ -112,7 +112,7 @@ class SmokeTellerLookFaceDownEffect extends OneShotEffect { Permanent faceDownCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); if (faceDownCreature != null) { Permanent copyFaceDown = faceDownCreature.copy(); - copyFaceDown.setFaceDown(false); + copyFaceDown.setFaceDown(false, game); Cards cards = new CardsImpl(); cards.add(copyFaceDown); player.lookAtCards("face down card - " + mageObject.getLogName(), cards, game); diff --git a/Mage.Sets/src/mage/sets/lorwyn/OonasProwler.java b/Mage.Sets/src/mage/sets/lorwyn/OonasProwler.java index e47bd78610b..6f557bd7294 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/OonasProwler.java +++ b/Mage.Sets/src/mage/sets/lorwyn/OonasProwler.java @@ -29,10 +29,9 @@ package mage.sets.lorwyn; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardCardCost; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -41,7 +40,6 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; /** * @@ -64,7 +62,7 @@ public class OonasProwler extends CardImpl { // Discard a card: Oona's Prowler gets -2/-0 until end of turn. Any player may activate this ability. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(-2,-0, Duration.EndOfTurn) , new DiscardCardCost()); ability.setMayActivate(TargetController.ANY); - ability.addEffect(new EmptyEffect("Any player may activate this ability")); + ability.addEffect(new InfoEffect("Any player may activate this ability")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java b/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java index 03b18ddd4dc..501a3d8bafa 100644 --- a/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java +++ b/Mage.Sets/src/mage/sets/magic2010/MirrorOfFate.java @@ -136,7 +136,7 @@ class FaceUpPredicate implements Predicate { @Override public boolean apply(Card input, Game game) { - return !input.isFaceDown(); + return !input.isFaceDown(game); } @Override diff --git a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java index d398fbcdc7b..2bf3c7107d1 100644 --- a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java +++ b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java @@ -28,12 +28,13 @@ package mage.sets.nemesis; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.keyword.FadingAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -46,6 +47,7 @@ import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; /** * @@ -63,7 +65,7 @@ public class ParallaxWave extends CardImpl { this.addAbility(new FadingAbility(5, this)); // Remove a fade counter from Parallax Wave: Exile target creature. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(this.getId(), this.getName()), new RemoveCountersSourceCost(CounterType.FADE.createInstance())); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new RemoveCountersSourceCost(CounterType.FADE.createInstance())); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -100,16 +102,22 @@ class ParallaxWaveEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - ExileZone exileZone = game.getExile().getExileZone(source.getSourceId()); - if (exileZone != null) { - for (Card card: exileZone.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null) { + UUID exileZoneId = CardUtil.getObjectExileZoneId(game, sourceObject); + if (exileZoneId != null) { + ExileZone exileZone = game.getExile().getExileZone(exileZoneId); + if (exileZone != null) { + for (Card card: exileZone.getCards(game)) { + Player player = game.getPlayer(card.getOwnerId()); + if (player != null) { + player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + } + } + exileZone.clear(); } + return true; } - exileZone.clear(); - return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java b/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java index 156ebe3ed29..ca58c5fd1cd 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/PraetorsGrasp.java @@ -105,9 +105,9 @@ class PraetorsGraspEffect extends OneShotEffect { Card card = opponent.getLibrary().getCard(targetId, game); UUID exileId = CardUtil.getObjectExileZoneId(game, sourceObject); if (card != null && exileId != null) { - card.setFaceDown(true); game.informPlayers(controller.getName() + " moves the searched card face down to exile"); card.moveToExile(exileId, sourceObject.getName(), source.getSourceId(), game); + card.setFaceDown(true, game); game.addEffect(new PraetorsGraspPlayEffect(card.getId()), source); game.addEffect(new PraetorsGraspRevealEffect(card.getId()), source); } diff --git a/Mage.Sets/src/mage/sets/odyssey/DiligentFarmhand.java b/Mage.Sets/src/mage/sets/odyssey/DiligentFarmhand.java index 3b65c8fbf2e..46adc620e8f 100644 --- a/Mage.Sets/src/mage/sets/odyssey/DiligentFarmhand.java +++ b/Mage.Sets/src/mage/sets/odyssey/DiligentFarmhand.java @@ -30,12 +30,11 @@ package mage.sets.odyssey; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -65,7 +64,7 @@ public class DiligentFarmhand extends CardImpl { ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); // If Diligent Farmhand is in a graveyard, effects from spells named Muscle Burst count it as a card named Muscle Burst. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EmptyEffect("If Diligent Farmhand is in a graveyard, effects from spells named Muscle Burst count it as a card named Muscle Burst"))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("If Diligent Farmhand is in a graveyard, effects from spells named Muscle Burst count it as a card named Muscle Burst"))); } public DiligentFarmhand(final DiligentFarmhand card) { diff --git a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java index 5c737db700a..f448b9501c5 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java +++ b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java @@ -106,7 +106,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/ravnica/BottledCloister.java b/Mage.Sets/src/mage/sets/ravnica/BottledCloister.java index 403f5334efc..1abbb400e61 100644 --- a/Mage.Sets/src/mage/sets/ravnica/BottledCloister.java +++ b/Mage.Sets/src/mage/sets/ravnica/BottledCloister.java @@ -101,8 +101,8 @@ class BottledCloisterExileEffect extends OneShotEffect { if (numberOfCards > 0) { UUID exileId = CardUtil.getCardExileZoneId(game, source); for (Card card: controller.getHand().getCards(game)) { - card.setFaceDown(true); card.moveToExile(exileId, sourcePermanent.getName(), source.getSourceId(), game); + card.setFaceDown(true, game); } game.informPlayers(sourcePermanent.getName() + ": " + controller.getName() + " exiles his or her hand face down (" + numberOfCards + "card" + (numberOfCards > 1 ?"s":"") +")"); } @@ -140,8 +140,8 @@ class BottledCloisterReturnEffect extends OneShotEffect { for (Card card: exileZone.getCards(game)) { if (card.getOwnerId().equals(controller.getId())) { numberOfCards++; - card.setFaceDown(false); card.moveToZone(Zone.HAND, source.getSourceId(), game, true); + card.setFaceDown(false, game); } } } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/Evermind.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/Evermind.java index 9422b4d68c5..4167bd3a717 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/Evermind.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/Evermind.java @@ -29,9 +29,9 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.keyword.SpliceOntoArcaneAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -52,7 +52,7 @@ public class Evermind extends CardImpl { this.color.setBlue(true); // (Nonexistent mana costs can't be paid.) - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect("(Nonexistent mana costs can't be paid.)")); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("(Nonexistent mana costs can't be paid.)")); ability.setRuleAtTheTop(true); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ONaginata.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ONaginata.java index 72268365fa7..f2cf811ac4f 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/ONaginata.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/ONaginata.java @@ -29,10 +29,10 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EquipAbility; @@ -66,7 +66,7 @@ public class ONaginata extends CardImpl { this.subtype.add("Equipment"); // O-Naginata can be attached only to a creature with 3 or more power. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EmptyEffect("{this} can be attached only to a creature with 3 or more power"))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("{this} can be attached only to a creature with 3 or more power"))); // Equipped creature gets +3/+0 and has trample. Effect effect = new BoostEquippedEffect(3, 0); diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java index 135cf640a83..b200bd833ea 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/CloneShell.java @@ -113,8 +113,8 @@ class CloneShellEffect extends OneShotEffect { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.setFaceDown(true); card.moveToExile(getId(), "Clone Shell (Imprint)", source.getSourceId(), game); + card.setFaceDown(true, game); Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent != null) { permanent.imprint(card.getId(), game); @@ -166,7 +166,7 @@ class CloneShellDiesEffect extends OneShotEffect { List imprinted = permanent.getImprinted(); if (imprinted.size() > 0) { Card imprintedCard = game.getCard(imprinted.get(0)); - imprintedCard.setFaceDown(false); + imprintedCard.setFaceDown(false, game); if (imprintedCard.getCardType().contains(CardType.CREATURE)) { imprintedCard.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), source.getControllerId()); } diff --git a/Mage.Sets/src/mage/sets/seventhedition/Rowen.java b/Mage.Sets/src/mage/sets/seventhedition/Rowen.java index 19cb2baf863..03abdd1b40d 100644 --- a/Mage.Sets/src/mage/sets/seventhedition/Rowen.java +++ b/Mage.Sets/src/mage/sets/seventhedition/Rowen.java @@ -29,8 +29,8 @@ package mage.sets.seventhedition; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EmptyEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; @@ -73,7 +73,7 @@ class RowenAbility extends TriggeredAbilityImpl { private int lastTriggeredTurn; RowenAbility() { - super(Zone.BATTLEFIELD, new EmptyEffect(""), false); + super(Zone.BATTLEFIELD, new InfoEffect(""), false); } RowenAbility(final RowenAbility ability) { diff --git a/Mage.Sets/src/mage/sets/shardsofalara/FeralHydra.java b/Mage.Sets/src/mage/sets/shardsofalara/FeralHydra.java index 9b0731dd14d..6b4d3404d72 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/FeralHydra.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/FeralHydra.java @@ -28,18 +28,22 @@ package mage.sets.shardsofalara; import java.util.UUID; - -import mage.constants.*; +import static javax.xml.bind.JAXBIntrospector.getValue; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.SpellAbility; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -65,7 +69,7 @@ public class FeralHydra extends CardImpl { // {3}: Put a +1/+1 counter on Feral Hydra. Any player may activate this ability. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()) , new ManaCostsImpl("{3}")); ability.setMayActivate(TargetController.ANY); - ability.addEffect(new EmptyEffect("Any player may activate this ability")); + ability.addEffect(new InfoEffect("Any player may activate this ability")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/Manaplasm.java b/Mage.Sets/src/mage/sets/shardsofalara/Manaplasm.java index 15a3a80d7fd..eb742a84040 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/Manaplasm.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/Manaplasm.java @@ -33,7 +33,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EmptyEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.constants.Duration; @@ -77,7 +77,7 @@ public class Manaplasm extends CardImpl { class ManaplasmAbility extends TriggeredAbilityImpl { public ManaplasmAbility() { - super(Zone.BATTLEFIELD, new EmptyEffect("{this} gets +X/+X until end of turn, where X is that spell's converted mana cost"), false); + super(Zone.BATTLEFIELD, new InfoEffect("{this} gets +X/+X until end of turn, where X is that spell's converted mana cost"), false); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/OblivionRing.java b/Mage.Sets/src/mage/sets/shardsofalara/OblivionRing.java index c6b56c48d33..dfeb33c65eb 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/OblivionRing.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/OblivionRing.java @@ -29,15 +29,15 @@ package mage.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.ReturnFromExileForSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.permanent.AnotherPredicate; import mage.target.Target; @@ -58,7 +58,6 @@ public class OblivionRing extends CardImpl { public OblivionRing(UUID ownerId) { super(ownerId, 20, "Oblivion Ring", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); this.expansionSetCode = "ALA"; - this.color.setWhite(true); // When Oblivion Ring enters the battlefield, exile another target nonland permanent. Ability ability1 = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect(), false); diff --git a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java index fe236f7b99c..be0377d3d78 100644 --- a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java +++ b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java @@ -115,7 +115,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { if (event.getTargetId().equals(source.getSourceId())) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/tempest/ScrollRack.java b/Mage.Sets/src/mage/sets/tempest/ScrollRack.java index 2bc6be045d4..455dc635787 100644 --- a/Mage.Sets/src/mage/sets/tempest/ScrollRack.java +++ b/Mage.Sets/src/mage/sets/tempest/ScrollRack.java @@ -101,8 +101,8 @@ class ScrollRackEffect extends OneShotEffect { for (UUID targetId : targets) { Card card = game.getCard(targetId); if (card != null) { - card.setFaceDown(true); if (card.moveToExile(source.getSourceId(), sourceObject.getLogName(), source.getSourceId(), game)) { + card.setFaceDown(true, game); amountExiled++; } } diff --git a/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java b/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java index bf5dbd44929..4045b5f7ef5 100644 --- a/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java +++ b/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java @@ -122,10 +122,10 @@ class PyxisOfPandemoniumExileEffect extends OneShotEffect { exileId = UUID.randomUUID(); exileIds.put(exileKey, exileId); } - card.setFaceDown(true); player.moveCardToExileWithInfo(card, exileId, new StringBuilder(sourceObject.getLogName() +" (").append(player.getName()).append(")").toString(), source.getSourceId(), game, Zone.LIBRARY); + card.setFaceDown(true, game); } } } @@ -173,7 +173,7 @@ class PyxisOfPandemoniumPutOntoBattlefieldEffect extends OneShotEffect { ExileZone exileZone = game.getState().getExile().getExileZone(exileId); if (exileZone != null) { for(Card card: exileZone.getCards(game)) { - card.setFaceDown(false); +// card.setFaceDown(false, game); if (CardUtil.isPermanentCard(card)) { player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); } diff --git a/Mage.Sets/src/mage/sets/theros/RescueFromTheUnderworld.java b/Mage.Sets/src/mage/sets/theros/RescueFromTheUnderworld.java index f53eb0db14d..00e2299d9b1 100644 --- a/Mage.Sets/src/mage/sets/theros/RescueFromTheUnderworld.java +++ b/Mage.Sets/src/mage/sets/theros/RescueFromTheUnderworld.java @@ -248,7 +248,7 @@ class RescueFromTheUnderworldReturnEffect extends OneShotEffect { if (source.getTargets().get(1) != null) { for (UUID targetId: ((Target) source.getTargets().get(1)).getTargets()) { Card card = game.getCard(targetId); - if (card != null && !card.isFaceDown()) { + if (card != null && !card.isFaceDown(game)) { Player player = game.getPlayer(card.getOwnerId()); if (player != null) { Zone currentZone = game.getState().getZone(card.getId()); diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/Opalescence.java b/Mage.Sets/src/mage/sets/urzasdestiny/Opalescence.java index bb8b0448d10..f7d78f067d9 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/Opalescence.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/Opalescence.java @@ -27,9 +27,7 @@ */ package mage.sets.urzasdestiny; -import java.util.Iterator; import java.util.UUID; -import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; @@ -87,7 +85,7 @@ class OpalescenceEffect extends ContinuousEffectImpl { public OpalescenceEffect() { super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); - staticText = "Each other non-Aura enchantment is a creature with power and toughness each equal to its converted mana cost."; + staticText = "Each other non-Aura enchantment is a creature with power and toughness each equal to its converted mana cost"; } public OpalescenceEffect(final OpalescenceEffect effect) { diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/MemoryJar.java b/Mage.Sets/src/mage/sets/urzaslegacy/MemoryJar.java index aad24e856f4..1387ec50842 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/MemoryJar.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/MemoryJar.java @@ -107,8 +107,8 @@ class MemoryJarEffect extends OneShotEffect { Card card = hand.get(hand.iterator().next(), game); if(card != null) { - card.setFaceDown(true); card.moveToExile(getId(), "Memory Jar", source.getSourceId(), game); + card.setFaceDown(true, game); cards.add(card); } } diff --git a/Mage.Sets/src/mage/sets/visions/NaturalOrder.java b/Mage.Sets/src/mage/sets/visions/NaturalOrder.java index 7fe519fab0b..0e6a36aaef3 100644 --- a/Mage.Sets/src/mage/sets/visions/NaturalOrder.java +++ b/Mage.Sets/src/mage/sets/visions/NaturalOrder.java @@ -34,8 +34,8 @@ import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledCreaturePermanent; @@ -47,7 +47,7 @@ import mage.target.common.TargetControlledCreaturePermanent; public class NaturalOrder extends CardImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a green creature"); - private static final FilterCard filterCard = new FilterCard("green creature card"); + private static final FilterCreatureCard filterCard = new FilterCreatureCard("green creature card"); static { filter.add(new ColorPredicate(ObjectColor.GREEN)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java index 8ec19f6c964..7afac0cc4bd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/flicker/CloudshiftTest.java @@ -5,6 +5,7 @@ import mage.abilities.keyword.IntimidateAbility; import mage.abilities.keyword.LifelinkAbility; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import mage.game.permanent.Permanent; import org.junit.Assert; import org.junit.Test; @@ -73,7 +74,8 @@ public class CloudshiftTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); addCard(Zone.BATTLEFIELD, playerA, "Bonesplitter"); - + + // Exile target creature you control, then return that card to the battlefield under your control. addCard(Zone.HAND, playerA, "Cloudshift"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {1}", "Silvercoat Lion"); @@ -104,6 +106,8 @@ public class CloudshiftTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); addCard(Zone.HAND, playerA, "Cloudshift"); + // Haste + // When Fervent Cathar enters the battlefield, target creature can't block this turn. addCard(Zone.HAND, playerB, "Fervent Cathar"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Fervent Cathar"); @@ -147,4 +151,82 @@ public class CloudshiftTest extends CardTestPlayerBase { assertLife(playerA, 27); // 5 from the first with Giant Growth + 2 from the second bear. } + /* + I had a Stoneforge Mystic equipped with a Umesawa's Jitte. I activated Jitte 4 times to make + Stoneforge Mystic 9/10. My opponent put into play a Flickerwisp with his AEther Vial and + targeted my Stoneforge Mystic. At the end of my turn, Stoneforge Mystic came back as a 9/10, + before going down to 1/2 normally once my turn ended. + */ + @Test + public void testDontApplyEffectToNewInstanceOfPreviousEquipedPermanent() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Umezawa's Jitte"); + + // Exile target creature you control, then return that card to the battlefield under your control. + addCard(Zone.HAND, playerA, "Cloudshift"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Silvercoat Lion"); + + attack(3, playerA, "Silvercoat Lion"); + + activateAbility(3, PhaseStep.END_COMBAT, playerA, "Remove a charge counter from {this}: Choose one —
&bull Equipped creature gets"); + setModeChoice(playerA, "1"); + castSpell(3, PhaseStep.END_COMBAT, playerA, "Cloudshift", "Silvercoat Lion", "Remove a charge counter from"); + + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + Permanent Umezawa = getPermanent("Umezawa's Jitte", playerA.getId()); + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA.getId()); + + assertLife(playerA, 20); + assertLife(playerB, 18); + assertCounterCount("Umezawa's Jitte", CounterType.CHARGE, 1); + assertPermanentCount(playerA,"Silvercoat Lion", 1); + assertGraveyardCount(playerA,"Cloudshift", 1); + Assert.assertTrue(silvercoatLion.getAttachments().isEmpty()); + Assert.assertTrue("Umezawa must not be connected to Silvercoat Lion",Umezawa.getAttachedTo() == null); + assertPowerToughness(playerA, "Silvercoat Lion", 2, 2); + + } + + @Test + public void testDontApplyEffectToNewInstanceOfPreviousEquipedPermanentFlickerwisp() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Umezawa's Jitte"); + + + addCard(Zone.BATTLEFIELD, playerB, "Plains", 3); + // Flying + // When Flickerwisp enters the battlefield, exile another target permanent. Return that + // card to the battlefield under its owner's control at the beginning of the next end step. + addCard(Zone.HAND, playerB, "Flickerwisp"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Silvercoat Lion"); + + attack(3, playerA, "Silvercoat Lion"); + + activateAbility(4, PhaseStep.DRAW, playerA, "Remove a charge counter from {this}: Choose one —
&bull Equipped creature gets"); + setModeChoice(playerA, "1"); + castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Flickerwisp"); + addTarget(playerB, "Silvercoat Lion"); + + setStopAt(4, PhaseStep.END_TURN); + execute(); + + Permanent Umezawa = getPermanent("Umezawa's Jitte", playerA.getId()); + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA.getId()); + + assertLife(playerA, 20); + assertLife(playerB, 18); + assertCounterCount("Umezawa's Jitte", CounterType.CHARGE, 1); + assertPermanentCount(playerA,"Silvercoat Lion", 1); + assertPermanentCount(playerB,"Flickerwisp", 1); + Assert.assertTrue(silvercoatLion.getAttachments().isEmpty()); + Assert.assertTrue("Umezawa must not be connected to Silvercoat Lion",Umezawa.getAttachedTo() == null); + assertPowerToughness(playerA, "Silvercoat Lion", 2, 2); + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java index 57593d88f01..72766b529a5 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java @@ -90,7 +90,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath: Choose one —
&bull Put X +1/+1 counters on target creature.
&bull {source} deals X damage to target creature or player.
&bull Put an X/X green Elemental creature token onto the battlefield.
", "Archangel of Thune"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath", "Archangel of Thune"); setChoice(playerA, "X=3"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java index e83d866c42d..97f0aca9f52 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java @@ -27,8 +27,11 @@ */ package org.mage.test.cards.abilities.keywords; + +import mage.cards.Card; import mage.constants.PhaseStep; import mage.constants.Zone; +import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -204,5 +207,49 @@ public class ManifestTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Foundry Street Denizen", 1, 1); } - + /* + I casted a Silence the Believers on a manifested card. It moved to the exile zone face-down. + */ + @Test + public void testCardGetsExiledFaceUp() { + addCard(Zone.BATTLEFIELD, playerB, "Island", 2); + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4); + // Exile target creature. Its controller manifests the top card of his or her library {1}{U} + addCard(Zone.HAND, playerB, "Reality Shift"); + // Silence the Believers - Instant {2}{B}{B} + // Strive — Silence the Believers costs more to cast for each target beyond the first. + // Exile any number of target creatures and all Auras attached to them. + addCard(Zone.HAND, playerB, "Silence the Believers"); + addTarget(playerB, "face down creature"); + // Gore Swine {2}{R} + // 4/1 + addCard(Zone.LIBRARY, playerA, "Gore Swine"); + + // Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn. + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + + skipInitShuffling(); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Silence the Believers", "face down creature"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + // no life gain + assertLife(playerA, 20); + assertLife(playerB, 20); + assertGraveyardCount(playerB, "Reality Shift", 1); + assertExileCount("Silvercoat Lion" , 1); + assertExileCount("Gore Swine" , 1); + // no facedown creature is on the battlefield + assertPermanentCount(playerA, "face down creature", 0); + + for (Card card :currentGame.getExile().getAllCards(currentGame)){ + if (card.getName().equals("Gore Swine")) { + Assert.assertTrue("Gore Swine may not be face down in exile", !card.isFaceDown(currentGame)); + } + } + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/LightningBoltTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/LightningBoltTest.java index 85c4f6a9610..a698664c363 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/LightningBoltTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/LightningBoltTest.java @@ -84,7 +84,10 @@ public class LightningBoltTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.GRAVEYARD, playerB, "Forest"); + // Destroy target creature with defender. addCard(Zone.GRAVEYARD, playerB, "Clear a Path"); + // Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. + // (Artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal are card types.) addCard(Zone.BATTLEFIELD, playerB, "Tarmogoyf"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Tarmogoyf"); @@ -93,6 +96,10 @@ public class LightningBoltTest extends CardTestPlayerBase { execute(); // Tarmogoyf is a 2/3 that then takes 3 damage, then becomes a 3/4 as the // Lightning Bolt is put into the graveyard and then state base actions are checked and Tarmogoyf survives. + // First, the Tarmogoyf will receive the damage, then Lightning Bolt goes to the graveyard. + // Then the active player would receive priority - which means, that right before that happens, state-based + // effects are checked: the game sees a 3/4 creature will 3 damage on it, so nothing happens. + // Then the active player receives priority. assertPermanentCount(playerB, "Tarmogoyf", 1); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/BaneAlleyBrokerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/BaneAlleyBrokerTest.java new file mode 100644 index 00000000000..025c46e4f3f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/BaneAlleyBrokerTest.java @@ -0,0 +1,55 @@ +package org.mage.test.cards.facedown; + +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.ExileZone; +import org.junit.Assert; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author BetaSteward + */ +public class BaneAlleyBrokerTest extends CardTestPlayerBase { + + /** + * Bane Alley Broker + * Creature — Human Rogue 0/3, 1UB (3) + * {T}: Draw a card, then exile a card from your hand face down. + * You may look at cards exiled with Bane Alley Broker. + * {U}{B}, {T}: Return a card exiled with Bane Alley Broker to its owner's hand. + * + */ + + // test that cards exiled using Bane Alley Broker are face down + @Test + public void testBaneAlleyBroker() { + addCard(Zone.BATTLEFIELD, playerA, "Bane Alley Broker"); + addCard(Zone.HAND, playerA, "Goblin Roughrider"); + addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Draw a card, then exile a card from your hand face down."); + addTarget(playerA, "Goblin Roughrider"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertHandCount(playerA, 2); + assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Goblin Roughrider", 0); + + assertExileCount("Goblin Roughrider", 1); + + for (Card card :currentGame.getExile().getAllCards(currentGame)){ + if (card.getName().equals("Goblin Roughrider")) { + Assert.assertTrue("Exiled card is not face down", card.isFaceDown(currentGame)); + } + } + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/GhastlyConscriptionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/GhastlyConscriptionTest.java new file mode 100644 index 00000000000..638ac645a7a --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/GhastlyConscriptionTest.java @@ -0,0 +1,45 @@ +package org.mage.test.cards.facedown; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author BetaSteward + */ +public class GhastlyConscriptionTest extends CardTestPlayerBase { + + /** + * Ghastly Conscription + * Sorcery, 5BB (7) + * Exile all creature cards from target player's graveyard in a face-down pile, + * shuffle that pile, then manifest those cards. (To manifest a card, put it + * onto the battlefield face down as a 2/2 creature. Turn it face up any time + * for its mana cost if it's a creature card.) + * + */ + + // test that cards exiled using Ghastly Conscription return face down + @Test + public void testGhastlyConscription() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7); + addCard(Zone.HAND, playerA, "Ghastly Conscription"); + addCard(Zone.GRAVEYARD, playerA, "Ashcloud Phoenix"); + addCard(Zone.GRAVEYARD, playerA, "Goblin Roughrider"); + addCard(Zone.GRAVEYARD, playerA, "Island"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ghastly Conscription", playerA); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + assertGraveyardCount(playerA, 2); + assertPermanentCount(playerA, "face down creature", 2); + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java new file mode 100644 index 00000000000..4213b6ffb82 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/SummonersEggTest.java @@ -0,0 +1,117 @@ +package org.mage.test.cards.facedown; + +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.permanent.Permanent; +import org.junit.Assert; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author BetaSteward + */ +public class SummonersEggTest extends CardTestPlayerBase { + + /** + * Summoner's Egg + * Artifact Creature — Construct 0/4, 4 (4) + * Imprint — When Summoner's Egg enters the battlefield, you may exile a + * card from your hand face down. + * When Summoner's Egg dies, turn the exiled card face up. If it's a creature + * card, put it onto the battlefield under your control. + * + */ + + // test that cards imprinted using Summoner's Egg are face down + @Test + public void testSummonersEggImprint() { + addCard(Zone.HAND, playerA, "Summoner's Egg"); + addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Goblin Roughrider"); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertHandCount(playerA, 1); + assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Goblin Roughrider", 0); + + assertExileCount("Goblin Roughrider", 1); + for (Card card :currentGame.getExile().getAllCards(currentGame)){ + if (card.getName().equals("Goblin Roughrider")) { + Assert.assertTrue("Exiled card is not face down", card.isFaceDown(currentGame)); + } + } + + } + + // test that creature cards imprinted using Summoner's Egg are put in play face up + @Test + public void testSummonersEggDies() { + addCard(Zone.HAND, playerA, "Summoner's Egg"); + addCard(Zone.HAND, playerA, "Sejiri Merfolk"); + addCard(Zone.HAND, playerA, "Goblin Roughrider"); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.HAND, playerB, "Char"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Char", "Summoner's Egg"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertHandCount(playerA, 1); + assertHandCount(playerA, "Sejiri Merfolk", 1); + assertHandCount(playerA, "Goblin Roughrider", 0); + + assertGraveyardCount(playerA, "Summoner's Egg", 1); + + assertExileCount("Goblin Roughrider", 0); + assertPermanentCount(playerA, "Goblin Roughrider", 1); + for (Permanent p :currentGame.getBattlefield().getAllActivePermanents()){ + if (p.getName().equals("Goblin Roughrider")) { + Assert.assertTrue("Permanent is not face up", !p.isFaceDown(currentGame)); + } + } + + } + + // test that non-creature cards imprinted using Summoner's Egg are left in exile face up + @Test + public void testSummonersEggDies2() { + addCard(Zone.HAND, playerA, "Summoner's Egg"); + addCard(Zone.HAND, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.HAND, playerB, "Char"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3); + + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summoner's Egg"); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Char", "Summoner's Egg"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertHandCount(playerA, 1); + assertHandCount(playerA, "Forest", 1); + + assertGraveyardCount(playerA, "Summoner's Egg", 1); + + assertExileCount("Forest", 1); + for (Card card :currentGame.getExile().getAllCards(currentGame)){ + if (card.getName().equals("Forest")) { + Assert.assertTrue("Exiled card is not face up", !card.isFaceDown(currentGame)); + } + } + + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ParallaxWaveTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ParallaxWaveTest.java new file mode 100644 index 00000000000..9e0cf706314 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ParallaxWaveTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.single; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class ParallaxWaveTest extends CardTestPlayerBase { + + /** + * http://www.slightlymagic.net/forum/viewtopic.php?f=70&t=16732&hilit=Sharuum+the+Hegemon#p172791 + * + * While playing the AI I had put out Opalescence and Parallax Wave. + * With proper ordering of the stack I should be able to permanently exile all my + * opponents creatures. This does not happen + * + The proper sequence should work as follows + -Activate Parallax Wave to exile target enemy creature(s), + -Respond and assign Parallax Wave to target itself. + -Resolve the stack, Parallax wave targets itself for exile + -This triggers the return all exiled cards to the field effect, to the top of the stack + -Stack resolves, A "NEW unique id" parallax wave should enter the field. **this is not happening** + -The stack should finish resolution, the enemy creatures are exiled *however* the return to the + battle field effect should be tied to the ORIGINAL id Parallax Wave and thus will never trigger as + the original wave no longer exists) **this doesn't happen, as the "NEW" Parallax Wave leaves play + the cards exiled with the "previous" wave are returned to the battlefield** + + */ + @Test + public void testFirstExileHandlingOfItself() { + addCard(Zone.BATTLEFIELD, playerA, "Opalescence"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.HAND, playerA, "Parallax Wave"); + + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Parallax Wave"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Parallax Wave"); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Parallax Wave", 1); + assertCounterCount("Parallax Wave", CounterType.FADE, 5); + assertExileCount("Silvercoat Lion", 1); // The lion is still exiled + + } + + @Test + public void testFirstAndSecondExileHandlingOfItself() { + addCard(Zone.BATTLEFIELD, playerA, "Opalescence"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.HAND, playerA, "Parallax Wave"); + + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); + addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Parallax Wave"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Silvercoat Lion"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Parallax Wave"); + + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Pillarfield Ox"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Remove a fade counter from {this}: Exile target creature", "Parallax Wave"); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Parallax Wave", 1); + + assertCounterCount("Parallax Wave", CounterType.FADE, 5); + + assertExileCount("Silvercoat Lion", 1); // The Lion is exiled and never returns + assertExileCount("Pillarfield Ox", 1); // The Ox is exiled and never returns + + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/combat/PowerToughnessCalculationAfterCombatDamageTest.java b/Mage.Tests/src/test/java/org/mage/test/combat/PowerToughnessCalculationAfterCombatDamageTest.java index 3856aa46657..1cc51349f1d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/combat/PowerToughnessCalculationAfterCombatDamageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/combat/PowerToughnessCalculationAfterCombatDamageTest.java @@ -14,13 +14,17 @@ import org.mage.test.serverside.base.CardTestPlayerBase; /** * Test that calculated p/t is applied after combat damage resolution, so a 2/2 Nighthowler * dies if blocked from a 2/2 creature. - * + * All combat damage happens simultaneously. Then any abilities that trigger from combat + * damage go on the stack. In normal circumstances, the combo you're trying to construct doesn't work. * @author LevelX2 */ public class PowerToughnessCalculationAfterCombatDamageTest extends CardTestPlayerBase { @Test public void powerToughnessCalculation() { + // Pain Seer Creature - Human Wizard 2/2 + // Inspired - Whenever Pain Seer becomes untapped, reveal the top card of your library and put that card + // into your hand. You lose life equal to that card's converted mana cost. addCard(Zone.BATTLEFIELD, playerA, "Pain Seer"); addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); // Nighthowler and enchanted creature each get +X/+X, where X is the number of creature cards in all graveyards. diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index f336540ccf7..7d447091f68 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -125,7 +125,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("activate:")) { String command = action.getAction(); command = command.substring(command.indexOf("activate:") + 9); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); if (!checkSpellOnStackCondition(groups, game) || !checkSpellOnTopOfStackCondition(groups, game)) { break; } @@ -148,7 +148,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("manaActivate:")) { String command = action.getAction(); command = command.substring(command.indexOf("manaActivate:") + 13); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); List manaPerms = this.getAvailableManaProducers(game); for (Permanent perm: manaPerms) { for (Ability manaAbility: perm.getAbilities().getAvailableManaAbilities(Zone.BATTLEFIELD, game)) { @@ -176,7 +176,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getAction().startsWith("addCounters:")) { String command = action.getAction(); command = command.substring(command.indexOf("addCounters:") + 12); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { if (permanent.getName().equals(groups[0])) { Counter counter = new Counter(groups[1], Integer.parseInt(groups[2])); @@ -204,7 +204,7 @@ public class TestPlayer extends ComputerPlayer { } String command = action.getAction(); command = command.substring(command.indexOf("attack:") + 7); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); for (int i = 1; i < groups.length; i++) { String group = groups[i]; if (group.startsWith("planeswalker=")) { @@ -234,7 +234,7 @@ public class TestPlayer extends ComputerPlayer { if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("block:")) { String command = action.getAction(); command = command.substring(command.indexOf("block:") + 6); - String[] groups = command.split(";"); + String[] groups = command.split("\\$"); FilterCreatureForCombatBlock filterBlocker = new FilterCreatureForCombatBlock(); filterBlocker.add(new NamePredicate(groups[0])); filterBlocker.add(Predicates.not(new BlockingPredicate())); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index f87e3eabfde..62fd2d86d1f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -697,11 +697,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, Player target) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";targetPlayer=" + target.getName()); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$targetPlayer=" + target.getName()); } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName); } public enum StackClause { @@ -736,19 +736,19 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement */ public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, StackClause clause) { if (StackClause.WHILE_ON_STACK.equals(clause)) { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName + ";spellOnStack=" + spellOnStack); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName + "$spellOnStack=" + spellOnStack); } else { - player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName + ";!spellOnStack=" + spellOnStack); + player.addAction(turnNum, step, "activate:Cast " + cardName + "$target=" + targetName + "$!spellOnStack=" + spellOnStack); } } public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack, String spellOnTopOfStack) { - String action = "activate:Cast " + cardName + ";target=" + targetName; + String action = "activate:Cast " + cardName + "$target=" + targetName; if (spellOnStack != null && !spellOnStack.isEmpty()) { - action += ";spellOnStack=" + spellOnStack; + action += "$spellOnStack=" + spellOnStack; } if (spellOnTopOfStack != null && !spellOnTopOfStack.isEmpty()) { - action += ";spellOnTopOfStack=" + spellOnTopOfStack; + action += "$spellOnTopOfStack=" + spellOnTopOfStack; } player.addAction(turnNum, step, action); } @@ -762,26 +762,26 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, Player target) { - player.addAction(turnNum, step, "activate:" + ability + ";targetPlayer=" + target.getName()); + player.addAction(turnNum, step, "activate:" + ability + "$targetPlayer=" + target.getName()); } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName) { - player.addAction(turnNum, step, "activate:" + ability + ";target=" + targetName); + player.addAction(turnNum, step, "activate:" + ability + "$target=" + targetName); } public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) { StringBuilder sb = new StringBuilder("activate:").append(ability); if (targetName != null && !targetName.isEmpty()) { - sb.append(";target=" ).append(targetName); + sb.append("$target=" ).append(targetName); } if (spellOnStack != null && !spellOnStack.isEmpty()) { - sb.append(";spellOnStack=").append(spellOnStack); + sb.append("$spellOnStack=").append(spellOnStack); } player.addAction(turnNum, step, sb.toString()); } public void addCounters(int turnNum, PhaseStep step, TestPlayer player, String cardName, CounterType type, int count) { - player.addAction(turnNum, step, "addCounters:" + cardName + ";" + type.getName() + ";" + count); + player.addAction(turnNum, step, "addCounters:" + cardName + "$" + type.getName() + "$" + count); } public void attack(int turnNum, TestPlayer player, String attacker) { @@ -789,11 +789,11 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } public void attack(int turnNum, TestPlayer player, String attacker, String planeswalker) { - player.addAction(turnNum, PhaseStep.DECLARE_ATTACKERS, new StringBuilder("attack:").append(attacker).append(";planeswalker=").append(planeswalker).toString()); + player.addAction(turnNum, PhaseStep.DECLARE_ATTACKERS, new StringBuilder("attack:").append(attacker).append("$planeswalker=").append(planeswalker).toString()); } public void block(int turnNum, TestPlayer player, String blocker, String attacker) { - player.addAction(turnNum, PhaseStep.DECLARE_BLOCKERS, "block:"+blocker+";"+attacker); + player.addAction(turnNum, PhaseStep.DECLARE_BLOCKERS, "block:"+blocker+"$"+attacker); } /** diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index ae3f30b82f3..ea2cca50045 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -860,7 +860,7 @@ public abstract class AbilityImpl implements Ability { return false; } } else if (object instanceof PermanentCard) { - if (((PermanentCard)object).isFaceDown()&& !this.getWorksFaceDown()) { + if (((PermanentCard)object).isFaceDown(game)&& !this.getWorksFaceDown()) { return false; } } diff --git a/Mage/src/mage/abilities/TriggeredAbilities.java b/Mage/src/mage/abilities/TriggeredAbilities.java index f48a5745d64..b3b341c8abf 100644 --- a/Mage/src/mage/abilities/TriggeredAbilities.java +++ b/Mage/src/mage/abilities/TriggeredAbilities.java @@ -95,28 +95,6 @@ public class TriggeredAbilities extends ConcurrentHashMap cards = controller.getLibrary().getTopCards(game, amount); for (Card card: cards) { - card.setFaceDown(true); ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -89,7 +88,7 @@ public class ManifestEffect extends OneShotEffect { } MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId()); + controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.setManifested(true); diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java index 565f5e9f413..4f4de179351 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java @@ -83,7 +83,6 @@ public class ManifestTargetPlayerEffect extends OneShotEffect { newSource.setWorksFaceDown(true); List cards = targetPlayer.getLibrary().getTopCards(game, amount); for (Card card: cards) { - card.setFaceDown(true); ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -93,7 +92,7 @@ public class ManifestTargetPlayerEffect extends OneShotEffect { } MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter() +1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId()); + targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.setManifested(true); diff --git a/Mage/src/mage/abilities/keyword/HideawayAbility.java b/Mage/src/mage/abilities/keyword/HideawayAbility.java index f204dae0325..83809b634ef 100644 --- a/Mage/src/mage/abilities/keyword/HideawayAbility.java +++ b/Mage/src/mage/abilities/keyword/HideawayAbility.java @@ -130,10 +130,10 @@ class HideawayExileEffect extends OneShotEffect { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.setFaceDown(true); card.moveToExile(CardUtil.getCardExileZoneId(game, source), new StringBuilder("Hideaway (").append(hideawaySource.getName()).append(")").toString(), source.getSourceId(), game); + card.setFaceDown(true, game); } target1.clearChosen(); } diff --git a/Mage/src/mage/abilities/keyword/MorphAbility.java b/Mage/src/mage/abilities/keyword/MorphAbility.java index 6fe4083dbc4..ced44656612 100644 --- a/Mage/src/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/mage/abilities/keyword/MorphAbility.java @@ -122,7 +122,6 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost super(Zone.HAND, null); this.morphCosts = morphCosts; this.megamorph = megamorph; - card.setMorphCard(true); this.setWorksFaceDown(true); StringBuilder sb = new StringBuilder(); if (megamorph) { @@ -203,7 +202,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost Spell spell = game.getStack().getSpell(ability.getId()); if (player != null && spell != null) { this.resetMorph(); - spell.setFaceDown(true); // so only the back is visible + spell.setFaceDown(true, game); // so only the back is visible if (alternateCosts.canPay(ability, sourceId, controllerId, game)) { if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) { activateMorph(game); @@ -226,7 +225,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost spellColor.setWhite(false); spellColor.setBlue(false); } else { - spell.setFaceDown(false); + spell.setFaceDown(false, game); } } } diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java index 50cc60e67c0..e2fe537f0d8 100644 --- a/Mage/src/mage/cards/Card.java +++ b/Mage/src/mage/cards/Card.java @@ -54,8 +54,8 @@ public interface Card extends MageObject { List getRules(Game game); // gets card rules + in game modifications String getExpansionSetCode(); String getTokenSetCode(); - void setFaceDown(boolean value); - boolean isFaceDown(); + void setFaceDown(boolean value, Game game); + boolean isFaceDown(Game game); boolean turnFaceUp(Game game, UUID playerId); boolean turnFaceDown(Game game, UUID playerId); boolean isFlipCard(); @@ -106,12 +106,12 @@ public interface Card extends MageObject { boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId); boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId); boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped); - boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList appliedEffects); + boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown); + boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList appliedEffects); List getMana(); void build(); - void setUsesVariousArt(boolean usesVariousArt); /** * * @return true if there exists various art images for this card @@ -127,9 +127,6 @@ public interface Card extends MageObject { void removeCounters(String name, int amount, Game game); void removeCounters(Counter counter, Game game); - void setMorphCard(boolean morphCard); - boolean isMorphCard(); - @Override Card copy(); diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index ca42ecaaf89..ece52408259 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -39,6 +39,7 @@ import mage.Mana; import mage.abilities.Ability; import mage.abilities.PlayLandAbility; import mage.abilities.SpellAbility; +import mage.abilities.keyword.MorphAbility; import mage.abilities.mana.ManaAbility; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; @@ -78,7 +79,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { protected String expansionSetCode; protected String tokenSetCode; protected Rarity rarity; - protected boolean faceDown; protected boolean canTransform; protected Card secondSideCard; protected boolean nightCard; @@ -143,7 +143,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { cardNumber = card.cardNumber; expansionSetCode = card.expansionSetCode; rarity = card.rarity; - faceDown = card.faceDown; canTransform = card.canTransform; if (canTransform) { @@ -155,7 +154,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { flipCardName = card.flipCardName; splitCard = card.splitCard; usesVariousArt = card.usesVariousArt; - morphCard = card.isMorphCard(); } @Override @@ -222,9 +220,13 @@ public abstract class CardImpl extends MageObjectImpl implements Card { public List getRules(Game game) { try { List rules = getRules(); - CardState state = game.getState().getCardState(objectId); - for (String data : state.getInfo().values()) { - rules.add(data); + if (game != null) { + CardState cardState = game.getState().getCardState(objectId); + if (cardState != null) { + for (String data : cardState.getInfo().values()) { + rules.add(data); + } + } } // for (Ability ability: state.getAbilities()) { // rules.add(ability.getRule()); @@ -337,10 +339,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { game.rememberLKI(objectId, event.getFromZone(), this); } - if (isFaceDown() && !event.getToZone().equals(Zone.BATTLEFIELD)) { // to battlefield is possible because of Morph - setFaceDown(false); - game.getCard(this.getId()).setFaceDown(false); - } + setFaceDown(false, game); updateZoneChangeCounter(); switch (event.getToZone()) { case GRAVEYARD: @@ -473,6 +472,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } else { game.getExile().createZone(exileId, name).add(this); } + setFaceDown(false, game); updateZoneChangeCounter(); game.setZone(objectId, event.getToZone()); game.addSimultaneousEvent(event); @@ -483,17 +483,21 @@ public abstract class CardImpl extends MageObjectImpl implements Card { @Override public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId) { - return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, false); + return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, false, false, null); } @Override public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped){ - return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, null); + return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, false, null); + } + @Override + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown){ + return this.putOntoBattlefield(game, fromZone, sourceId, controllerId, tapped, facedown, null); } @Override - public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList appliedEffects){ + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList appliedEffects){ ZoneChangeEvent event = new ZoneChangeEvent(this.objectId, sourceId, controllerId, fromZone, Zone.BATTLEFIELD, appliedEffects, tapped); if (!game.replaceEvent(event)) { if (fromZone != null) { @@ -510,10 +514,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { break; case EXILED: game.getExile().removeCard(this, game); - if (isFaceDown()) { - // 110.6b Permanents enter the battlefield untapped, unflipped, face up, and phased in unless a spell or ability says otherwise. - this.setFaceDown(false); - } removed = true; break; case COMMAND: @@ -539,6 +539,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { setZone(Zone.BATTLEFIELD, game); game.setScopeRelevant(true); permanent.setTapped(tapped); + permanent.setFaceDown(facedown, game); permanent.entersBattlefield(sourceId, game, event.getFromZone(), true); game.setScopeRelevant(false); game.applyEffects(); @@ -549,21 +550,20 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } @Override - public void setFaceDown(boolean value) { - faceDown = value; + public void setFaceDown(boolean value, Game game) { + game.getState().getCardState(objectId).setFaceDown(value); } @Override - public boolean isFaceDown() { - return faceDown; + public boolean isFaceDown(Game game) { + return game.getState().getCardState(objectId).isFaceDown(); } @Override public boolean turnFaceUp(Game game, UUID playerId) { GameEvent event = GameEvent.getEvent(GameEvent.EventType.TURNFACEUP, getId(), playerId); if (!game.replaceEvent(event)) { - setFaceDown(false); - game.getCard(objectId).setFaceDown(false); // Another instance? + setFaceDown(false, game); for (Ability ability :abilities) { // abilities that were set to not visible face down must be set to visible again if (ability.getWorksFaceDown() && !ability.getRuleVisible()) { ability.setRuleVisible(true); @@ -579,8 +579,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card { public boolean turnFaceDown(Game game, UUID playerId) { GameEvent event = GameEvent.getEvent(GameEvent.EventType.TURNFACEDOWN, getId(), playerId); if (!game.replaceEvent(event)) { - setFaceDown(true); - game.getCard(objectId).setFaceDown(true); // Another instance? + setFaceDown(true, game); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.TURNEDFACEDOWN, getId(), playerId)); return true; } @@ -634,11 +633,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card { @Override public void build() {} - @Override - public void setUsesVariousArt(boolean usesVariousArt) { - this.usesVariousArt = usesVariousArt; - } - @Override public boolean getUsesVariousArt() { return usesVariousArt; @@ -709,21 +703,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card { removeCounters(counter.getName(), counter.getCount(), game); } - @Override - public void setMorphCard(boolean morphCard) { - this.morphCard = morphCard; - } - - @Override - public boolean isMorphCard() { - return morphCard; - } - @Override public String getLogName() { - if (this.isFaceDown()) { - return "facedown card"; - } +// if (this.isFaceDown()) { +// return "facedown card"; +// } return name; } diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index ea44f795a11..6a0c0e1c95f 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -60,7 +60,7 @@ public enum CardRepository { // raise this if db structure was changed private static final long CARD_DB_VERSION = 36; // raise this if new cards were added to the server - private static final long CARD_CONTENT_VERSION = 5; + private static final long CARD_CONTENT_VERSION = 6; private final Random random = new Random(); private Dao cardDao; diff --git a/Mage/src/mage/cards/repository/ExpansionRepository.java b/Mage/src/mage/cards/repository/ExpansionRepository.java index b9d28a623af..8ccc3bd3c56 100644 --- a/Mage/src/mage/cards/repository/ExpansionRepository.java +++ b/Mage/src/mage/cards/repository/ExpansionRepository.java @@ -24,7 +24,7 @@ public enum ExpansionRepository { private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE"; private static final String VERSION_ENTITY_NAME = "expansion"; private static final long EXPANSION_DB_VERSION = 3; - private static final long EXPANSION_CONTENT_VERSION = 1; + private static final long EXPANSION_CONTENT_VERSION = 2; private Dao expansionDao; diff --git a/Mage/src/mage/filter/predicate/other/FaceDownPredicate.java b/Mage/src/mage/filter/predicate/other/FaceDownPredicate.java index 38f180d4b2b..e05b57a9f74 100644 --- a/Mage/src/mage/filter/predicate/other/FaceDownPredicate.java +++ b/Mage/src/mage/filter/predicate/other/FaceDownPredicate.java @@ -39,7 +39,7 @@ public class FaceDownPredicate implements Predicate { @Override public boolean apply(Card input, Game game) { - return input.isFaceDown(); + return input.isFaceDown(game); } @Override diff --git a/Mage/src/mage/game/CardState.java b/Mage/src/mage/game/CardState.java index 60bc055b338..44ab1257f3e 100644 --- a/Mage/src/mage/game/CardState.java +++ b/Mage/src/mage/game/CardState.java @@ -9,6 +9,7 @@ import mage.counters.Counters; */ public class CardState { + protected boolean faceDown; protected Map info; protected Counters counters; @@ -19,6 +20,7 @@ public class CardState { } public CardState(final CardState state) { + this.faceDown = state.faceDown; if (state.info != null) { info = new HashMap<>(); info.putAll(state.info); @@ -30,6 +32,14 @@ public class CardState { return new CardState(this); } + public void setFaceDown(boolean value) { + faceDown = value; + } + + public boolean isFaceDown() { + return faceDown; + } + public Counters getCounters() { return counters; } diff --git a/Mage/src/mage/game/GameCommanderImpl.java b/Mage/src/mage/game/GameCommanderImpl.java index 8955412998b..d50f8adc3ee 100644 --- a/Mage/src/mage/game/GameCommanderImpl.java +++ b/Mage/src/mage/game/GameCommanderImpl.java @@ -34,8 +34,8 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.CommanderManaReplacementEffect; import mage.abilities.effects.common.continuous.CommanderReplacementEffect; import mage.abilities.effects.common.cost.CommanderCostModification; @@ -52,12 +52,12 @@ import mage.game.turn.TurnMod; import mage.players.Player; import mage.target.common.TargetCardInHand; import mage.util.CardUtil; -import mage.watchers.common.CommanderCombatDamageWatcher; +import mage.watchers.common.CommanderInfoWatcher; public abstract class GameCommanderImpl extends GameImpl { private final Map mulliganedCards = new HashMap<>(); - private final Set commanderCombatWatcher = new HashSet<>(); + private final Set commanderCombatWatcher = new HashSet<>(); protected boolean alsoLibrary; // replace also commander going to library protected boolean startingPlayerSkipsDraw = true; @@ -74,7 +74,7 @@ public abstract class GameCommanderImpl extends GameImpl { @Override protected void init(UUID choosingPlayerId, GameOptions gameOptions) { - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new EmptyEffect("Commander effects")); + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); //Move commander to command zone for (UUID playerId: state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); @@ -88,7 +88,7 @@ public abstract class GameCommanderImpl extends GameImpl { ability.addEffect(new CommanderCostModification(commander.getId())); ability.addEffect(new CommanderManaReplacementEffect(player.getId(), CardUtil.getColorIdentity(commander))); getState().setValue(commander.getId() + "_castCount", 0); - CommanderCombatDamageWatcher watcher = new CommanderCombatDamageWatcher(commander.getId()); + CommanderInfoWatcher watcher = new CommanderInfoWatcher(commander.getId(), true); getState().getWatchers().add(watcher); this.commanderCombatWatcher.add(watcher); watcher.addCardInfoToCommander(this); @@ -127,8 +127,8 @@ public abstract class GameCommanderImpl extends GameImpl { if(!mulliganedCards.containsKey(playerId)){ mulliganedCards.put(playerId, new CardsImpl()); } - card.setFaceDown(true); card.moveToExile(null, "", null, this); + card.setFaceDown(true, this); mulliganedCards.get(playerId).add(card); } } @@ -165,8 +165,8 @@ public abstract class GameCommanderImpl extends GameImpl { if(player != null && mulliganedCards.containsKey(playerId)){ for(Card card : mulliganedCards.get(playerId).getCards(this)){ if(card != null){ - card.setFaceDown(false); card.moveToZone(Zone.LIBRARY, null, this, false); + card.setFaceDown(false, this); } } if(mulliganedCards.get(playerId).size() > 0){ @@ -182,7 +182,7 @@ public abstract class GameCommanderImpl extends GameImpl { */ @Override protected boolean checkStateBasedActions() { - for (CommanderCombatDamageWatcher damageWatcher: commanderCombatWatcher) { + for (CommanderInfoWatcher damageWatcher: commanderCombatWatcher) { for(Map.Entry entrySet : damageWatcher.getDamageToPlayer().entrySet()){ if (entrySet.getValue() > 20) { Player player = getPlayer(entrySet.getKey()); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index a3584a11919..f93b91ced0d 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -277,7 +277,6 @@ public abstract class GameImpl implements Game, Serializable { card = ((PermanentCard)card).getCard(); } card.setOwnerId(ownerId); - card.setFaceDown(false); // can be set face down from previous game gameCards.put(card.getId(), card); state.addCard(card); if (card.isSplitCard()) { diff --git a/Mage/src/mage/game/GameTinyLeadersImpl.java b/Mage/src/mage/game/GameTinyLeadersImpl.java index 08627578905..063d38b8a81 100644 --- a/Mage/src/mage/game/GameTinyLeadersImpl.java +++ b/Mage/src/mage/game/GameTinyLeadersImpl.java @@ -31,22 +31,27 @@ package mage.game; import java.util.HashSet; import java.util.Set; import java.util.UUID; +import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.CommanderManaReplacementEffect; import mage.abilities.effects.common.continuous.CommanderReplacementEffect; import mage.abilities.effects.common.cost.CommanderCostModification; import mage.cards.Card; +import mage.cards.CardImpl; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.constants.CardType; import mage.constants.MultiplayerAttackOption; import mage.constants.PhaseStep; import mage.constants.RangeOfInfluence; +import mage.constants.Rarity; import mage.constants.Zone; import mage.game.turn.TurnMod; import mage.players.Player; import mage.util.CardUtil; +import mage.watchers.common.CommanderInfoWatcher; /** * @@ -69,27 +74,27 @@ public abstract class GameTinyLeadersImpl extends GameImpl{ @Override protected void init(UUID choosingPlayerId, GameOptions gameOptions) { - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new EmptyEffect("Commander effects")); + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new InfoEffect("Commander effects")); //Move tiny leader to command zone for (UUID playerId: state.getPlayerList(startingPlayerId)) { Player player = getPlayer(playerId); if (player != null){ - if (player.getSideboard().size() > 0){ - CardInfo cardInfo = CardRepository.instance.findCard(player.getMatchPlayer().getDeck().getName()); - if (cardInfo != null) { - Card commander = cardInfo.getCard(); - Set cards = new HashSet<>(); - cards.add(commander); - this.loadCards(cards, playerId); - if (commander != null) { - player.setCommanderId(commander.getId()); - commander.moveToZone(Zone.COMMAND, null, this, true); - ability.addEffect(new CommanderReplacementEffect(commander.getId(), alsoLibrary)); - ability.addEffect(new CommanderCostModification(commander.getId())); - ability.addEffect(new CommanderManaReplacementEffect(player.getId(), CardUtil.getColorIdentity(commander))); - getState().setValue(commander.getId() + "_castCount", 0); - } - } + Card commander = getCommanderCard(player.getMatchPlayer().getDeck().getName(), player.getId()); + if (commander != null) { + Set cards = new HashSet<>(); + cards.add(commander); + this.loadCards(cards, playerId); + player.setCommanderId(commander.getId()); + commander.moveToZone(Zone.COMMAND, null, this, true); + ability.addEffect(new CommanderReplacementEffect(commander.getId(), alsoLibrary)); + ability.addEffect(new CommanderCostModification(commander.getId())); + ability.addEffect(new CommanderManaReplacementEffect(player.getId(), CardUtil.getColorIdentity(commander))); + getState().setValue(commander.getId() + "_castCount", 0); + CommanderInfoWatcher watcher = new CommanderInfoWatcher(commander.getId(), false); + getState().getWatchers().add(watcher); + watcher.addCardInfoToCommander(this); + } else { + throw new UnknownError("Commander card could not be created"); } } @@ -101,6 +106,34 @@ public abstract class GameTinyLeadersImpl extends GameImpl{ } } + /** + * Name of Tiny Leader comes from the deck name (it's not in the sideboard) + * Additionally, it was taken into account that WOTC had missed a few color combinations + * when making Legendary Creatures at 3 CMC. There are three Commanders available to use + * for the missing color identities: + * Mardu [WBR 2/2], + * Sultai [UBG 2/2], and + * Jeskai [WUR 2/2]. + * + * @param commanderName + * @param ownerId + * @return + */ + public static Card getCommanderCard(String commanderName, UUID ownerId) { + Card commander = null; + switch (commanderName) { + case "Sultai": + commander = new DefaultCommander(ownerId, commanderName, "{U}{B}{G}"); + break; + default: + CardInfo cardInfo = CardRepository.instance.findCard(commanderName); + if (cardInfo != null) { + commander = cardInfo.getCard(); + } + } + return commander; + } + @Override public Set getOpponents(UUID playerId) { Set opponents = new HashSet<>(); @@ -122,3 +155,40 @@ public abstract class GameTinyLeadersImpl extends GameImpl{ } } + +class DefaultCommander extends CardImpl { + + public DefaultCommander(UUID ownerId, String commanderName, String manaString) { + super(ownerId, 999, commanderName, Rarity.RARE, new CardType[]{CardType.CREATURE}, manaString); + this.expansionSetCode = ""; + this.supertype.add("Legendary"); + + if (manaString.contains("{G}")) { + this.color.setGreen(true); + } + if (manaString.contains("{W}")) { + this.color.setWhite(true); + } + if (manaString.contains("{U}")) { + this.color.setBlue(true); + } + if (manaString.contains("{B}")) { + this.color.setBlack(true); + } + if (manaString.contains("{R}")) { + this.color.setRed(true); + } + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + } + + public DefaultCommander(final DefaultCommander card) { + super(card); + } + + @Override + public DefaultCommander copy() { + return new DefaultCommander(this); + } +} diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index 3db80516186..ecde8334a3f 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -88,7 +88,16 @@ public class PermanentCard extends PermanentImpl { protected void copyFromCard(Card card) { this.name = card.getName(); this.abilities.clear(); - this.abilities.addAll(card.getAbilities().copy()); + if (this.faceDown) { + for (Ability ability: card.getAbilities()) { + if (ability.getWorksFaceDown()) { + this.abilities.add(ability.copy()); + } + } + } + else { + this.abilities = card.getAbilities().copy(); + } this.abilities.setControllerId(this.controllerId); this.cardType.clear(); this.cardType.addAll(card.getCardType()); @@ -116,8 +125,6 @@ public class PermanentCard extends PermanentImpl { } this.flipCard = card.isFlipCard(); this.flipCardName = card.getFlipCardName(); - this.faceDown = card.isFaceDown(); - this.morphCard = card.isMorphCard(); } public Card getCard() { @@ -134,12 +141,6 @@ public class PermanentCard extends PermanentImpl { Player controller = game.getPlayer(controllerId); if (controller != null && controller.removeFromBattlefield(this, game)) { Card originalCard = game.getCard(this.getId()); - if (isFaceDown()) { - setFaceDown(false); - if (originalCard != null) { - originalCard.setFaceDown(false); //TODO: Do this in a better way - } - } ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone, appliedEffects); if (!game.replaceEvent(event)) { Player owner = game.getPlayer(ownerId); @@ -190,10 +191,6 @@ public class PermanentCard extends PermanentImpl { @Override public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, ArrayList appliedEffects) { Zone fromZone = game.getState().getZone(objectId); - if (isMorphCard() && isFaceDown()) { - setFaceDown(false); - game.getCard(this.getId()).setFaceDown(false); //TODO: Do this in a better way - } Player controller = game.getPlayer(controllerId); if (controller != null && controller.removeFromBattlefield(this, game)) { ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED, appliedEffects); @@ -228,16 +225,6 @@ public class PermanentCard extends PermanentImpl { if (super.turnFaceUp(game, playerId)) { setManifested(false); setMorphed(false); - card.setFaceDown(false); - return true; - } - return false; - } - - @Override - public boolean turnFaceDown(Game game, UUID playerId) { - if (super.turnFaceDown(game, playerId)) { - card.setFaceDown(true); return true; } return false; @@ -258,17 +245,9 @@ public class PermanentCard extends PermanentImpl { card.adjustChoices(ability, game); } - @Override - public void setFaceDown(boolean value) { - super.setFaceDown(value); - if (card != null) { - card.setFaceDown(value); - } - } - @Override public ManaCosts getManaCost() { - if (isFaceDown()) { // face down permanent has always {0} mana costs + if (faceDown) { // face down permanent has always {0} mana costs manaCost.clear(); return manaCost; } diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index e8f3f50d36f..bc407e2fb14 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -93,6 +93,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { protected boolean controlledFromStartOfControllerTurn; protected int turnsOnBattlefield; protected boolean phasedIn = true; + protected boolean faceDown; protected boolean attacking; protected int blocking; // number of creatures the permanent can block @@ -139,6 +140,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.controlledFromStartOfControllerTurn = permanent.controlledFromStartOfControllerTurn; this.turnsOnBattlefield = permanent.turnsOnBattlefield; this.phasedIn = permanent.phasedIn; + this.faceDown = permanent.faceDown; this.attacking = permanent.attacking; this.blocking = permanent.blocking; this.maxBlocks = permanent.maxBlocks; @@ -431,6 +433,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return false; } + @Override + public void setFaceDown(boolean value, Game game) { + this.faceDown = value; + } + + @Override + public boolean isFaceDown(Game game) { + return faceDown; + } + @Override public boolean isFlipped() { return flipped; @@ -838,7 +850,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public void entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent) { controlledFromStartOfControllerTurn = false; - if (this.isFaceDown()) { + if (this.isFaceDown(game)) { // remove some attributes here, bceause first apply effects comes later otherwise abilities (e.g. color related) will unintended trigger MorphAbility.setPermanentToFaceDownCreature(this); } @@ -1226,7 +1238,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public String getLogName() { if (name.isEmpty()) { - if (isFaceDown()) { + if (faceDown) { return "face down creature"; } else { return "a creature without name"; diff --git a/Mage/src/mage/game/permanent/token/CentaurToken.java b/Mage/src/mage/game/permanent/token/CentaurToken.java index bbf048b29ef..1fb7c07a5c4 100644 --- a/Mage/src/mage/game/permanent/token/CentaurToken.java +++ b/Mage/src/mage/game/permanent/token/CentaurToken.java @@ -28,9 +28,9 @@ package mage.game.permanent.token; +import java.util.Random; import mage.constants.CardType; import mage.MageInt; -import mage.ObjectColor; /** * @@ -41,6 +41,7 @@ public class CentaurToken extends Token { public CentaurToken() { super("Centaur", "3/3 green Centaur creature token"); cardType.add(CardType.CREATURE); + setTokenType(new Random().nextInt(2) +1); // randomly take image 1 or 2 color.setGreen(true); subtype.add("Centaur"); power = new MageInt(3); diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 23ed93bdae9..026576123d2 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -267,10 +267,7 @@ public class Spell implements StackObject, Card { } } else { updateOptionalCosts(0); - if (isFaceDown()) { - card.setFaceDown(true); - } - result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId); + result = card.putOntoBattlefield(game, fromZone, ability.getSourceId(), controllerId, false, faceDown); return result; } } @@ -628,7 +625,7 @@ public class Spell implements StackObject, Card { @Override public int getConvertedManaCost() { int cmc = 0; - if (this.isMorphCard() && this.isFaceDown()) { + if (faceDown) { return 0; } for (Ability spellAbility: spellAbilities) { @@ -717,24 +714,24 @@ public class Spell implements StackObject, Card { } @Override - public void setFaceDown(boolean value) { + public void setFaceDown(boolean value, Game game) { faceDown = value; } @Override public boolean turnFaceUp(Game game, UUID playerId) { - setFaceDown(false); + setFaceDown(false, game); return true; } @Override public boolean turnFaceDown(Game game, UUID playerId) { - setFaceDown(true); + setFaceDown(true, game); return true; } @Override - public boolean isFaceDown() { + public boolean isFaceDown(Game game) { return faceDown; } @@ -855,7 +852,12 @@ public class Spell implements StackObject, Card { } @Override - public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, ArrayList appliedEffects) { + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId, boolean tapped, boolean facedown, ArrayList appliedEffects) { throw new UnsupportedOperationException("Not supported yet."); } @@ -869,11 +871,6 @@ public class Spell implements StackObject, Card { return card.getUsesVariousArt(); } - @Override - public void setUsesVariousArt(boolean usesVariousArt) { - card.setUsesVariousArt(usesVariousArt); - } - @Override public List getMana() { return card.getMana(); @@ -973,16 +970,6 @@ public class Spell implements StackObject, Card { return card; } - @Override - public void setMorphCard(boolean morphCard) { - throw new UnsupportedOperationException("Not supported"); - } - - @Override - public boolean isMorphCard() { - return card.isMorphCard(); - } - @Override public Card getMainCard() { return card.getMainCard(); diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index cedc5c8a30a..1719996dca3 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -498,6 +498,19 @@ public interface Player extends MageItem, Copyable { * @return */ boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped); + + /** + * Uses putOntoBattlefield and posts also a info message about in the game log + * + * @param card + * @param game + * @param fromZone + * @param sourceId + * @param tapped the card enters the battlefield tapped + * @param facedown the card enters the battlefield facedown + * @return + */ + boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown); /** * Checks if the playerToCheckId is from an opponent in range diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index c311b8d567c..6349b1526a1 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -2835,13 +2835,18 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) { - return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false); + return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false, false); } @Override public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) { + return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, false); + } + + @Override + public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) { boolean result = false; - if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped)) { + if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped, facedown)) { game.informPlayers(new StringBuilder(this.getName()) .append(" puts ").append(card.getLogName()) .append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") diff --git a/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java b/Mage/src/mage/watchers/common/CommanderInfoWatcher.java similarity index 75% rename from Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java rename to Mage/src/mage/watchers/common/CommanderInfoWatcher.java index f0a0f5c9aee..eccce0af197 100644 --- a/Mage/src/mage/watchers/common/CommanderCombatDamageWatcher.java +++ b/Mage/src/mage/watchers/common/CommanderInfoWatcher.java @@ -48,29 +48,33 @@ import mage.watchers.Watcher; * * @author Plopman */ -public class CommanderCombatDamageWatcher extends Watcher { - public Map damageToPlayer = new HashMap(); +public class CommanderInfoWatcher extends Watcher { - public CommanderCombatDamageWatcher(UUID commander) { + public Map damageToPlayer = new HashMap<>(); + public boolean checkCommanderDamage; + + public CommanderInfoWatcher(UUID commander, boolean checkCommanderDamage) { super("CommanderCombatDamageWatcher", WatcherScope.CARD); this.sourceId = commander; + this.checkCommanderDamage = checkCommanderDamage; } - public CommanderCombatDamageWatcher(final CommanderCombatDamageWatcher watcher) { + public CommanderInfoWatcher(final CommanderInfoWatcher watcher) { super(watcher); this.damageToPlayer.putAll(watcher.damageToPlayer); + this.checkCommanderDamage = watcher.checkCommanderDamage; } @Override - public CommanderCombatDamageWatcher copy() { - return new CommanderCombatDamageWatcher(this); + public CommanderInfoWatcher copy() { + return new CommanderInfoWatcher(this); } @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.DAMAGED_PLAYER && event instanceof DamagedPlayerEvent) { + if (checkCommanderDamage && event.getType() == EventType.DAMAGED_PLAYER && event instanceof DamagedPlayerEvent) { if (sourceId.equals(event.getSourceId())) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; if (damageEvent.isCombatDamage()) { @@ -106,22 +110,24 @@ public class CommanderCombatDamageWatcher extends Watcher { sb.append("Commander"); Integer castCount = (Integer)game.getState().getValue(sourceId + "_castCount"); if (castCount != null) { - sb.append(" ").append(castCount).append(castCount.intValue() == 1 ? " time":" times").append(" casted from the command zone."); + sb.append(" ").append(castCount).append(castCount == 1 ? " time":" times").append(" casted from the command zone."); } this.addInfo(object, "Commander",sb.toString(), game); - for (Map.Entry entry : damageToPlayer.entrySet()) { - Player damagedPlayer = game.getPlayer(entry.getKey()); - sb.setLength(0); - sb.append("Commander did ").append(entry.getValue()).append(" combat damage to player ").append(damagedPlayer.getName()).append("."); - this.addInfo(object, new StringBuilder("Commander").append(entry.getKey()).toString(),sb.toString(), game); + + if (checkCommanderDamage) { + for (Map.Entry entry : damageToPlayer.entrySet()) { + Player damagedPlayer = game.getPlayer(entry.getKey()); + sb.setLength(0); + sb.append("Commander did ").append(entry.getValue()).append(" combat damage to player ").append(damagedPlayer.getName()).append("."); + this.addInfo(object, new StringBuilder("Commander").append(entry.getKey()).toString(),sb.toString(), game); + } } } } private void addInfo(MageObject object, String key, String value, Game game) { - if (object instanceof Card) { - ((Card) object).addInfo(key, value, game); - } else if (object instanceof Permanent) { + ((Card) object).addInfo(key, value, game); + if (object instanceof Permanent) { ((Permanent) object).addInfo(key, value, game); } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index b62acf6b675..0a599a26673 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -25667,23 +25667,29 @@ Mercurial Pretender|Prerelease Events|84|Special|{4}{U}|Creature - Shapeshifter| Indulgent Tormentor|Prerelease Events|85|Special|{3}{B}{B}|Creature - Demon|5|3|Flying$At the beginning of your upkeep, draw a card unless target opponent sacrifices a creature or pays 3 life.| Siege Dragon|Prerelease Events|86|Special|{5}{R}{R}|Creature - Dragon|5|5|Flying$When Siege Dragon enters the battlefield, destroy all Walls your opponents control.$Whenever Siege Dragon attacks, if defending player controls no Walls, it deals 2 damage to each creature without flying that player controls.| Phytotitan|Prerelease Events|87|Special|{4}{G}{G}|Creature - Plant Elemental|7|2|When Phytotitan dies, return it to the battlefield tapped under its owner's control at the beginning of his or her next upkeep.| +Scion of Ugin|Dragons of Tarkir|1|U|{6}|Creature - Dragon Spirit|4|4|Flying| Anafenza, Kin-Tree Spirit|Dragons of Tarkir|2|R|{W}{W}|Legendary Creature - Spirit Soldier|2|2|Whenever another nontoken creature enters the battlefield under your control, bolster 1. (Choose a creature with the least toughness among creatures you control and put a +1/+1 counter on it.)| Arashin Foremost|Dragons of Tarkir|3|R|{1}{W}{W}|Creature - Human Warrior|2|2|Double strike$Whenever Arashin Foremost enters the battlefield or attacks, another target Warrior creature you control gains double strike until end of turn.| Artful Maneuver|Dragons of Tarkir|4|C|{1}{W}|Instant|||Target creature gets +2/+2 until end of turn.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Aven Sunstriker|Dragons of Tarkir|5|U|{1}{W}{W}|Creature - Bird Warrior|1|1|Flying$Double strike (This creature deals both first-strike and regular combat damage.)$Megamorph {4}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)| Hidden Dragonslayer|Dragons of Tarkir|23|R|{1}{W}|Creature - Human Warrior|2|1|Lifelink$Megamorph {2}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Hidden Dragonslayer is turned face up, destroy target creature with power 4 or greater an opponent controls.| +Myth Realize|Dragons of Tarkir|26|R|Enchantment|||Whenever you cast a noncreature spell, put a lore counter on Myth Realized.${2}{W}: Put a lore counter on Myth Realized.${W}: Until end of turn, Myth Realized becomes a Monk Avatar creature in addition to its other types and gains "This creature's power and toughness are each equal to the number of lore counters on it."| Ojutai Exemplars|Dragons of Tarkir|27|M|{2}{W}{W}|Creature - Human Monk|4|4|Whenever you cast a noncreature spell, choose one - Tap target creature; Ojutai Exemplars gain first strike and lifelink until end of turn; or Exile Ojutai Exemplars, then return it to the battlefield tapped under its owner's control.| Orator of Ojutai|Dragons of Tarkir|29|U|{1}{W}|Creature - Bird Monk|0|4|Defneder, flying$As an additional cost to cast Orator of Ojutai, you may reveal a Dragon card from your hand.$When Orator of Ojutai enters the battlefield, if you revealed a Dragon card or controlled a Dragon as you cast Orator of Ojutai, draw a card.| Profound Journey|Dragons of Tarkir|30|R|{5}{W}{W}|Sorcery|||Return target permanent card from your graveyard to the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Radiant Purge|Dragons of Tarkir|31|R|{1}{W}|Instant|||Exile target multicolored creature or multicolored enchantment.| Sandcrafter Mage|Dragons of Tarkir|33|C|{2}{W}|Creature - Human Wizard|2|2|When Sandcrafter Mage enters the battlefield, bolster 1 (Choose a creature with the least toughness among the creatures you control and put a +1/+1 counter on it.)| Shieldhide Dragon|Dragons of Tarkir|37|U|{5}{W}|Creature - Dragon|3|3|Flying, lifelink$Megamorph {5}{W}{W} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Shieldhide Dragon is turned face up, put a +1/+1 counter on each other Dragon you control.| +Silkwrap|Dragons of Tarkir|38|U|{1}{W}|Enchantment|||When Silkwrap enters the battlefield, exile target creature with converted mana cost 3 or less an opponent controls until Silkwrap leaves the battlefield. (That creature returns under its owner's control.)| Sunscorch Regent|Dragons of Tarkir|41|R|{3}{W}{W}|Creature - Dragon|4|3|Flying$Whenever an opponent casts a spell, put a +1/+1 counter on Sunscorch Regent and you gain 1 life.| Surge of Righteousness|Dragons of Tarkir|42|U|{1}{W}|Instant|||Destroy target black or red creature that's attacking or blocking. You gain 2 life.| Anticipate|Dragons of Tarkir|45|C|{1}{U}|Instant|||Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| +Belltoll Dragon|Dragons of Tarkir|46|U|{5}{U}|Creature - Dragon|3|3|Flying, hexproof$Megamorph {5}{U}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Belltoll Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| +Clone Legion|Dragons of Tarkir|48|M|{7}{U}{U}|Sorcery|||For each creature target player controls, put a token onto the the battlefield that's a copy of that creature.| Dragonlord's Prerogative|Dragons of Tarkir|52|R|{4}{U}{U}|Instant||As an additional cost to cast Dragonlord's Prerogative, you may reveal a Dragon card from your hand.$If you reveal a Dragon card or controlled a Dragon as you cast Dragonlord's Prerogative, Dragonlord's Prerogative can't be countered.$Draw four cards.| Encase in Ice|Dragons of Tarkir|54|U|{1}{U}|Enchantment - Aura|||Flash$Enchant red or green creature$When Encase in Ice enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| Gudul Lurker|Dragons of Tarkir|56|U|{U}|Creature - Salamander|1|1|Gudul Lurker can't be blocked.$Megamorph {U} (You may cast this card face down as a 2/2 creature for {3}. Turn it up anytime for its megamorph cost and put a +1/+1 counter on it.)| +Icefall Regent|Dragons of Tarkir|58|R|{3}{U}{U}|Creature - Dragon|4|3|Flying$When Icefall Regent enters the battlefield, tap target creature an opponent controls. That creature doesn't untap during its controller's untap step for as long as you control Icefall Regent.$Spells your opponents cast that target Icefall Regent cost {2} more to cast.| Mirror Mockery|Dragons of Tarkir|62|R|{1}{U}|Enchantment - Aura|||Enchant creature$Whenever enchanted creature attacks, you may put a token onto the battlefield that's a copy of that creature. Exile that token at the end of combat.| Ojutai's Summons|Dragons of Tarkir|68|C|{3}{U}{U}|Sorcery|||Put a 2/2 blue Djinn Monk creature token with flying onto the battlefield.$Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)| Qarsi Deceiver|Dragons of Tarkir|71|U|{1}{U}|Creature - Naga Wizard|0|4|{T}: Add {1} to your mana pool. Spend this mana only to cast a face-down creature spell, pay a mana cost to turn a manifested creature face up, or pay a morph cost. | @@ -25692,7 +25698,9 @@ Silumgar's Scorn|Dragtons of Tarkir|78|U|{U}{U}|Instant|||As an additional cost Stratus Dancer|Dragons of Tarkir|80|R|{1}{U}|Creature - Djinn Monk|2|1|Flying$Megamorph {1}{U} You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time from its megamorph cost and put a +1/+1 counter on it.)| Acid-Spewer Dragon|Dragons of Tarkir|86|U|{5}{B}|Creature - Dragon|3|3|Flying, deathtouch$Megamorph {5}{B}{B} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Acid-Spewer Dragon is turned face up, put a +1/+1 counter on each other Dragon creature you control.| Blood-Chin Fanatic|Dragons of Tarkir|88|R|{1}{B}{B}|Creature - Orc Warrior|3|3|{1}{B}, Sacrifice another Warrior creature: Target player loses X life and you gain X life, where X is the sacrificed creature's power.| +Damnable Pact|Dragons of Tarkir|93|R|{X}{B}{B}|Sorcery|||Target player draws X cards and loses X life.| Deathbringer Regent|Dragons of Tarkir|96|R|{5}{B}{B}|Creature - Dragon|5|6|Flying$When Deathbringer Regent enters the battlefield, if you cast it from your hand and there are five or more other creatures on the battlefield, destroy all other creatures.| +Duress|Dragons of Tarkir|98|C|{B}|Sorcery|||Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.| Hedonist's Trove|Dragons of Tarkir|106|R|{5}{B}{B}|Enchantment|||When Hdeonist's Trove enters the battlefield, exile all cards in target opponent's graveyard.$You may play land cards exiled by Hedonist's Trove.$once per turn, you may cast a nonland card exiled by Hedonist's Trove.| Marang River Skeleton|Dragons of Tarkir|108|U|{1}{B}|Creature - Skeleton|1|1|{B}: Regenerate Marang River Skeleton.$Megamorph {3}{B} You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| Pitiless Horde|Dragons of Tarkir|112|R|{2}{B}|Creature - Orc Berserker|5|3|At the beginning of your upkeep, lose 2 life.$Dash {2}{B}{B} (You may cast tjos spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| @@ -25702,10 +25710,12 @@ Sidisi, Undead Vizier|Dragons of Tarkir|120|R|{3}{B}{B}|Legendary Creature - Zom Silumgar Assassin|Dragons of Tarkir|121|R|{1}{B}|Creature - Human Assassin|2|1|Creatures with power greater than Silumgar Assassin's power can't block it.$Megamorph {2}{B} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)$When Silumgar Assassin is turned face up, destroy target creature with power 3 or less an opponent controls.| Silumgar Butcher|Dragons of Tarkir|122|C|{4}{B}|Creature - Zombie Djinn|3|3|Exploit (When this creature enters the battlefield, you may sacrifice a creature.)$When Silumgar Butcher exploits a creature, target creature gets -3/-3 until end of turn.| Ultimate Price|Dragons of Tarkir|124|U|{1}{B}|Instant|||Destroy target monocolored creature.| +Wandering Tombshell|Dragons of Tarkir|127|C|{3}{B}|Creature - Zombie Turtle|1|6|| +Commune with Lava|Dragons of Tarkir|131|R|{X}{R}{R}|Instant|||Exile the top X cards of your library. Until the end of your next turn, you may play those cards.| Crater Elemental|Dragons of Tarkir|132|R|{2}{R}|Creature - Elemental|0|6|{R}, {T}, Sacrifice Crater Elemental: Crater Elemental deals 4 damage to target creature.$Formidable - {2}{R}: Crater Elemental has base power 8 until end of turn. Activate this ability only if creatures you control have total power 8 or greater.| Descent of the Dragons|Dragons of Tarkir|133|M|{4}{R}{R}|Sorcery||Destroy any number of target creatures. For each creature destroyed this way, its controller puts a 4/4 red Dragon creature token with flying onto the battlefield.| Ire Shaman|Dragons of Tarkir|141|R|{1}{R}|Creature - Orc Shaman|2|1|Ire Shaman can't be blocked except by two or more creatures.$Megamorph {R} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Ire Shaman is turned face up, exile the top card of your library. Until end of turn, you may play that card.| -Draconic Roar|Dragons of Tarkir|154|U|{1}{R}|Instant - As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand.$Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller.| +Draconic Roar|Dragons of Tarkir|154|U|{1}{R}|Instant|||As an additional cost to cast Draconic Roar, you may reveal a Dragon card from your hand.$Draconic Roar deals 3 damage to target creature. If you revealed a Dragon card or controlled a Dragon as you cast Draconic Roar, Draconic Roar deals 3 damage to that creature's controller.| Dragon Fodder|Dragons of Tarkir|135|C|{1}{R}|Sorcery|||Put two 1/1 red Goblin creature tokens onto the battlefield.| Dragon Tempest|Dragons of Tarkir|136|R|{1}{R}|Enchantment|||Whenever a creature with flying enters the battlefield under your control, it gains haste until the end of turn.$Whenever a Dragon enters the battlefield under your control, it deals X damage to target creature or player, where X is the number of Dragons you control.| Dragon Whisperer|Dragons of Tarkir|137|M|{R}{R}|Creature - Human Shaman|2|2|{R}: Dragon Whisperer gains flying until end of turn.${1}{R}: Dragon Whisperer get +1/+0 until end of turn$ - {4}{R}{R}: Put a 4/4 red Dragon creature token with flying onto the battlefield. Activate this ability only if creatures you control have total power 8 or greater.| @@ -25721,6 +25731,7 @@ Thunderbreak Regent|Dragons of Tarkir|162|R|{2}{R}{R}|Creature - Dragon|4|4|Flyi Warbringer|Dragons of Tarkir|168|U|{3}{R}|Creature - Orc Berserker|3|3|Dash costs you pay cost {2} less (as long as this creature is on the battlefield).$Dash {2}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)| Zurgo Bellstriker|Dragons of Tarkir|169|R|{R}|Legendary Creature - Orc Warrior|2|2|Zurgo Bellstriker can't block creatures with power 2 or greater.$Dash {1}{R} You may cast this creature for its dash cost. If you do, it gains haste, and it's returned to its owner's hand at the beginning of the next end step.)| Aerie Bowmasters|Dragons of Tarkir|170|C|{2}|{G}{G}|Creature - Hound Archer|Reach (This creature can block creatures with flying.)$Megamorph {5}{G} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up at any time for its megamorph cost and put a +1/+1 counter on it.)| +Ainok Survivalist|Dragons of Tarkir|172|U|{1}{G}|Creature - Hound Shaman|2|1|Megamorph {1}{G} (You may cast this card face down for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)$When Ainok Survivalist is turned face up, destroy target artifact or enchantment an opponent controls.| Assault Formation|Dragons of Tarkir|173|R|{1}{G}|Enchantment|||Each creature you control assigns combat damage equal to its toughness rather than its power.${G}: Target creature with defender can attack this turn as though it didn't have defender.${2}{G}: Creatures you control get +0/+1 until end of turn.| Avatar of the Resolute|Dragons of Tarkir|175|R|{G}{G}|Creature - Avatar|3|2|Reach, trample$Avatar of the Resolute enters the battlefield with a +1/+1 counter on it for each other creature you control with a +1/+1 counter on it.| Collected Company|Dragons of Tarkir|177|R|{3}{G}|Instant|||Look at the top six cards of your library. Put up to two creature cards with converted mana cost 3 or less from among them onto the battlefield. Put the rest on the bottom of your library in any order.| @@ -25735,6 +25746,7 @@ Scaleguard Sentinels|Dragons of Tarkir|201|U|{G}{G}|Creature - Human Soldier|2|3 Shaman of Forgotten Ways|Dragons of Tarkir|204|M|{2}G}|Creature - Human Shaman| 2|3|{T}:Add two mana in any combination of colors to your mana pool. Spend this mana only to cast creature spells.$Formidable - {9}{G}{G},{T}:Each player's life total becomes the number of creatures he or she controls. Acitave the ability only if creatures you control have total power 8 or greater.| Stampeding Elk Herd|Dragons of Tarkir|208|C|{3}{G}{G}|Creature - Elk|5|5|Formidable - Whenever Stampeding Elk Herd attacks, if creatures you control have total power 8 or greater, creatures you control gain trample until end of turn.| Sunbringer's Touch|Dragons of Tarkir|209|R|{2}{G}{G}|Sorcery|||Bolster X, where X is the number of cards in your hand. Each creature you control with a +1/+1 counter on it gains trample until end of turn. (To bolster X, choose a creature with the least toughness among creature you control and put X +1/+1 counters on it.)| +Surrak, the Hunt Caller|Dragons of Tarkir|210|R|{2}{G}{G}|Legendary Creature - Human Warrior|5|4|Formidable - At the beginning of combat on your turn, if creatures you control have total power 8 or greater, target creature you control gains haste until end of turn.| Arashin Sovereign|Dragons of Tarkir|212|R|{5}{G}{W}|Creature - Dragon|6|6|Flying$When Arashin Sovereign dies, you may put it on the top or bottom of its owner's library.|Atarka's Command|Dragons of Tarkir|213|R|{R}{G}|Instant|||Choose two - Your opponents can't gain life this turn; or Atarka's Command deals 3 damage to each opponent; or You may put a land card from your hand onto the battlefield; or Creatures you control get +1/+1 and gain reach until the end of turn.| Boltwing Marauder|Dragons of Tarkir|214|R|{3}{B}{R}|Creature - Dragon|5|4|Flying$Whenever another creature enters the battlefield under your control, target creature gets +2/+0 until end of turn.| Cunning Breezedancer|Dragons of Tarkir|215|U|{4}{W}{U}|Creature - Dragon|4|4|Flying$Whenever you cast a noncreature spell, Cunning Breezedancer gets +2/+2 until end of turn.| @@ -25743,6 +25755,7 @@ Dragonlord Dromoka|Dragons of Tarkir|217|M|{4}{G}{W}|Legendary Creature - Elder Dragonlord Kolaghan|Dragons of Tarkir|218|{4}{B}{R}|Legendary Creature - Elder Dragon|6|5|Flying$Haste$Other creatures you control have haste.$Whenever an opponent casts a creature or planeswalker spell with the same name as a card in their graveyard, that player loses 10 life.| Dragonlord Ojutai|Dragons of Tarkir|219|M|{3}{W}{U}|Legendary Creature - Elder Dragon|5|4|Flying$Dragonlord Ojutai has hexproof as long as it's untapped.$Whenever Dragonlord Ojutai deals combat damage to a player, look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.| Dragonlord Silumgar|Dragons of Tarkir|220|M|{4}{U}{B}|Legendary Creature - Elder Dragon|3|5|Flying$Deathtouch$When Dragonlord Silumgar enters the battlefield, gain control of target creature or planeswalker for as long as you control Dragonlord Silumgar.| +Dromoka's Command|Dragons of Tarkir|221|R|{G}{W}|Instant|||Choose two - Prevent all damage target instant or sorcery spell would deal this turn; Target player sacrifices an enchantment; Put a +1/+1 counter on target creature; or Target creature you control fights target creature you don't control.| Enduring Scalelord|Dragons of Tarkir|222|U|{4}{G}{W}|Creature - Dragon|4|4|Flying$Whenever one or more +1/+1 counters are place on another creature you control, you may put a +1/+1 counter on Enduring Scaleguard.| Harbinger of the Hunt|Dragons of Tarkir|223|R|{3}{R}{G}|Creature - Dragon|5|3|Flying${2}{R}: Harbinger of the Hunt deals 1 damage to each creature without flying.${2}{G}: Harbinger of the Hunt deals 1 damage to each other creature with flying.| Kolaghan's Command|Dragons of Tarkir|224|R|{1}{B}{R}|Instant|||Choose two - Return target creature card from your graveyard to your hand; or Target player discards a card; or Destroy target artifact; or Kolaghan's Command deals 2 damage to target creature or player.| @@ -25755,8 +25768,31 @@ Sarkhan Unbroken|Dragons of Tarkir|230|M|{2}{G}{U}{R}|Planeswalker - Sarkhan|||+ Savage Ventmaw|Dragons of Tarkir|231|U|{4}{R}{G}|Creature - Dragon|4|4|Flying$Whenever Savage Ventmaw attacks, add {R}{R}{R}{G}{G}{G} to your mana pool. Until end of turn, this mana doesn't empty from your mana pool as steps and phases end.| Silumgar's Command|Dragons of Tarkir|232|R|{3}{U}{B}|Instant|||Choose two - Counter target noncreature spell; or Return target permanent to its owner's hand; or Target creature gets -3/-3 until end of turn; or Destroy target planeswalker.| Swift Warkite|Dragons of Tarkir|233|U|{4}{B}{R}|Creature - Dragon|4|4|Flying$When Swift Warkite enters the battlefield, you may put a creature card with converted mana cost 3 or less from your hand or graveyard onto the battlefield. That creature gains haste. Return it to your hand at the beginning of the next end step.| +Atarka Monument|Dragons of Tarkir|235|U|{3}|Artifact|||{T}: Add {R} or {G} to your mana pool.${4}{R}{G}: Atarka Monument becomes a 4/4 red and green Dragon artifact creature with flying until end of turn.| +Custodian of the Trove|Dragons of Tarkir|236|C|{3}|Artifact Creature - Golem|2|5|Defender$Custodian of the Trove enters the battlefield tapped.| +Dromoka Monument|Dragons of Tarkir|238|U|{3}|Artifact|||{T}: Add {G} or {W} to your mana pool.${4}{G}{W}: Dromoka Monument becomes a 4/4 green and white Dragon artifact creature with flying until end of turn.| +Kolaghan Monument|Dragons of Tarkir|241|U|{3}|Artifact|||{T}: Add {B} or {R} to your mana pool.${4}{B}{R}: Kolaghan Monument becomes a 4/4 black and red Dragon artifact creature with flying until end of turn.| +Ojutai Monument|Dragons of Tarkir|242|U|{3}|Artifact|||{T}: Add {W} or {U} to your mana pool.${4}{W}{U}: Ojutai Monument becomes a 4/4 white and blue Dragon artifact creature with flying until end of turn.| +Silumgar Monument|Dragons of Tarkir|243|U|{3}|Artifact|||{T}: Add {U} or {B} to your mana pool.${4}{U}{B}: Silumgar Monument becomes a 4/4 blue and black Dragon artifact creature with flying until end of turn.| +Tapestry of the Ages|Dragons of Tarkir|246|U|Artifact|||{2}, {T}: Draw a card. Activate this ability only if you've cast a noncreature spell this turn.| +Vial of Dragonfire|Dragons of Tarkir|247|C|{2}|Artifact|||{2}, {T}, Sacrifice Vial of Dragonfire: Vial of Dragonfire deals 2 damage to target creature.| Evolving Wilds|Dragons of Tarkir|248|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.| Haven of the Spirit Dragon|Dragons of Tarkir|249|R||Land|||{T}: Add {1} to your mana pool.${T}: add one mana of any color to your mana pool. Spend this mana only to cast a Dragon creature spell.${2}, {T}, Sacrifice Haven of the Spirit Dragon: Return target Dragon creature card or Ugin planeswalker card from your graveyard to your hand.| +Plains|Dragons of Tarkir|250|L||Basic Land - Plains|||W| +Plains|Dragons of Tarkir|251|L||Basic Land - Plains|||W| +Plains|Dragons of Tarkir|252|L||Basic Land - Plains|||W| +Island|Dragons of Tarkir|253|L||Basic Land - Island|||U| +Island|Dragons of Tarkir|254|L||Basic Land - Island|||U| +Island|Dragons of Tarkir|255|L||Basic Land - Island|||U| +Swamp|Dragons of Tarkir|256|L||Basic Land - Swamp|||B| +Swamp|Dragons of Tarkir|257|L||Basic Land - Swamp|||B| +Swamp|Dragons of Tarkir|258|L||Basic Land - Swamp|||B| +Mountain|Dragons of Tarkir|259|L||Basic Land - Mountain|||R| +Mountain|Dragons of Tarkir|260|L||Basic Land - Mountain|||R| +Mountain|Dragons of Tarkir|261|L||Basic Land - Mountain|||R| +Forest|Dragons of Tarkir|262|L||Basic Land - Forest|||G| +Forest|Dragons of Tarkir|263|L||Basic Land - Forest|||G| +Forest|Dragons of Tarkir|264|L||Basic Land - Forest|||G| Emrakul, the Aeons Torn|Modern Masters 2015|3|M|{15}|Legendary Creature - Eldrazi|15|15|Emrakul, the Aeons Torn can't be countered.$When you cast Emrakul, take an extra turn after this one.$Flying, protection from colored spells, annihilator 6$When Emrakul is put into a graveyard from anywhere, its owner shuffles his or her graveyard into his or her library.| Karn Liberated|Modern Masters 2015|4|M|{7}|Planeswalker - Karn|||+4: Target player exiles a card from his or her hand.$-3: Exile target permanent.$-14: Restart the game, leaving in exile all non-Aura permanent cards exiled with Karn Liberated. Then put those cards onto the battlefield under your control.| Tarmogoyf|Modern Masters 2015|165|M|{1}{G}|Creature - Lhurgoyf|*|1+*|Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. (Artifact, creature, enchantment, instant, land, planeswalker, sorcery, and tribal are card types.)|