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.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 1211594b2e1..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; @@ -138,13 +138,12 @@ public class CardView extends SimpleCardView { * @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(); @@ -242,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; @@ -299,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) { @@ -343,7 +342,7 @@ public class CardView extends SimpleCardView { } protected CardView() { - super(null, "", 0, false, false, ""); + super(null, "", 0, false, ""); } public CardView(EmblemView emblem) { @@ -359,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."); } @@ -417,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(); @@ -581,7 +580,6 @@ public class CardView extends SimpleCardView { return getName() + " [" + getId() + "]"; } - @Override public boolean isFaceDown() { return faceDown; } @@ -696,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/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/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.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/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/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/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/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/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/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/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/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/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/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/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.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 5cb26d59356..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 @@ -247,7 +247,7 @@ public class ManifestTest extends CardTestPlayerBase { 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()); + 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/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/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 810125a6c37..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 @@ -341,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: @@ -477,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); @@ -487,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) { @@ -514,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: @@ -543,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(); @@ -553,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); @@ -583,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; } @@ -638,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; @@ -713,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/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 19541ff2ee0..d50f8adc3ee 100644 --- a/Mage/src/mage/game/GameCommanderImpl.java +++ b/Mage/src/mage/game/GameCommanderImpl.java @@ -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){ 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/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index 8de01c60e34..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 (isFaceDown() && fromZone.equals(Zone.BATTLEFIELD) && (isMorphed() || isManifested())) { - 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/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(" ")