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 945bcbfed82..8ac61b8732c 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
@@ -274,8 +274,8 @@ public class GuiDisplayUtil {
// legal = legal.replaceAll("#([^#]+)#", "$1");
// legal = legal.replaceAll("\\s*//\\s*", "
");
// legal = legal.replace("\r\n", "");
- legal = legal.replaceAll("\\{this\\}", card.getName());
- legal = legal.replaceAll("\\{source\\}", card.getName());
+ legal = legal.replaceAll("\\{this\\}", card.getName().isEmpty() ? "this":card.getName());
+ legal = legal.replaceAll("\\{source\\}", card.getName().isEmpty() ? "this":card.getName());
buffer.append(ManaSymbols.replaceSymbolsWithHTML(legal, ManaSymbols.Type.CARD));
}
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 0d1b11f2ade..bef960db73e 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
@@ -50,9 +50,7 @@ import org.apache.log4j.Logger;
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
-import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.ImageCache;
-import org.mage.plugins.card.utils.CardImageUtils;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
/**
@@ -306,18 +304,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
BufferedImage srcImage;
if (gameCard.isFaceDown()) {
- boolean morphedCard = false;
- for (String rule:gameCard.getRules()) {
- if (rule.startsWith("Morph ") ||
- rule.equals("You may cast this card as a 2/2 face-down creature, with no text, no name, no subtypes, and no mana cost by paying {3} rather than paying its mana cost.")) {
- morphedCard = true;
- }
- }
- if (morphedCard) {
+ if (gameCard.isMorphCard()) {
srcImage = ImageCache.getMorphImage();
}else {
- TFile file = new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename);
- srcImage = ImageCache.loadImage(file);
+ srcImage = ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename));
}
} else {
srcImage = ImageCache.getImage(gameCard, getCardWidth(), getCardHeight());
@@ -909,11 +899,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public boolean contains(int x, int y) {
- if (containsThis(x, y, true)) {
- return true;
- }
-
- return false;
+ return containsThis(x, y, true);
}
public boolean containsThis(int x, int y, boolean root) {
@@ -929,10 +915,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
cw = getCardHeight();
}
- if (x >= cx && x <= cx + cw && y >= cy && y <= cy + ch) {
- return true;
- }
- return false;
+ return x >= cx && x <= cx + cw && y >= cy && y <= cy + ch;
}
@Override
@@ -943,7 +926,11 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public Image getImage() {
if (this.hasImage) {
- return ImageCache.getImageOriginal(gameCard);
+ if (gameCard.isMorphCard() && gameCard.isFaceDown()) {
+ return ImageCache.getMorphImage();
+ } else {
+ return ImageCache.getImageOriginal(gameCard);
+ }
}
return null;
}
diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java
index 4147a8019bf..ccb8bf7a729 100644
--- a/Mage.Common/src/mage/view/CardView.java
+++ b/Mage.Common/src/mage/view/CardView.java
@@ -50,6 +50,7 @@ import mage.target.Targets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import mage.game.permanent.PermanentCard;
/**
* @author BetaSteward_at_googlemail.com
@@ -86,7 +87,8 @@ public class CardView extends SimpleCardView {
protected boolean transformed;
protected boolean flipCard;
-
+ protected boolean morphCard;
+
protected String alternateName;
protected String originalName;
@@ -130,14 +132,14 @@ public class CardView extends SimpleCardView {
*/
public CardView(Card card, UUID cardId, boolean controlled) {
super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.isFaceDown(), card.getUsesVariousArt(), card.getTokenSetCode());
-
+ this.morphCard = card.isMorphCard();
// 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.isMorphCard()) {
// special handling for Morph cards
this.fillEmpty(card, controlled);
- if (card instanceof Spell) {
+ if (card instanceof Spell /*|| card instanceof Card*/) {
if (controlled) {
this.name = card.getName();
this.displayName = card.getName();
@@ -214,6 +216,7 @@ public class CardView extends SimpleCardView {
this.canTransform = card.canTransform();
this.flipCard = card.isFlipCard();
+
if (card instanceof PermanentToken) {
this.isToken = true;
this.mageObjectType = MageObjectType.TOKEN;
@@ -670,6 +673,10 @@ 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/PermanentView.java b/Mage.Common/src/mage/view/PermanentView.java
index 870409e30bd..b58852ac5ec 100644
--- a/Mage.Common/src/mage/view/PermanentView.java
+++ b/Mage.Common/src/mage/view/PermanentView.java
@@ -30,7 +30,6 @@ package mage.view;
import mage.abilities.Ability;
import mage.abilities.common.TurnFaceUpAbility;
-import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
import mage.cards.Card;
import mage.constants.Rarity;
import mage.game.Game;
@@ -59,7 +58,7 @@ public class PermanentView extends CardView {
private final boolean copy;
private final String nameOwner; // only filled if != controller
private final boolean controlled;
- private UUID attachedTo;
+ private final UUID attachedTo;
public PermanentView(Permanent permanent, Card card, UUID createdForPlayerId, Game game) {
super(permanent, null, permanent.getControllerId().equals(createdForPlayerId));
@@ -79,8 +78,7 @@ public class PermanentView extends CardView {
original = new CardView(((PermanentToken)permanent).getToken());
original.expansionSetCode = permanent.getExpansionSetCode();
tokenSetCode = original.getTokenSetCode();
- }
- else {
+ } else {
if (card != null) {
original = new CardView(card);
} else {
@@ -96,8 +94,10 @@ public class PermanentView extends CardView {
this.alternateName = permanent.getFlipCardName();
this.originalName = this.getName();
} else {
- this.alternateName = original.getName();
- this.originalName = this.getName();
+ if (!this.isMorphCard() || controlled) {
+ this.alternateName = original.getName();
+ this.originalName = this.getName();
+ }
}
}
if (!permanent.getOwnerId().equals(permanent.getControllerId())) {
@@ -130,7 +130,6 @@ public class PermanentView extends CardView {
this.rules.add("If the controller has priority, he or she may turn this permanent face up." +
" This is a special action; it doesnt use the stack. To do this he or she pays the morph costs," +
" then turns this permanent face up.");
- this.rarity = Rarity.COMMON;
}
}
diff --git a/Mage.Common/src/mage/view/StackAbilityView.java b/Mage.Common/src/mage/view/StackAbilityView.java
index 6cd9f456cf5..9872f9eaf92 100644
--- a/Mage.Common/src/mage/view/StackAbilityView.java
+++ b/Mage.Common/src/mage/view/StackAbilityView.java
@@ -35,6 +35,7 @@ import mage.MageObject;
import mage.abilities.Modes;
import mage.abilities.effects.Effect;
import mage.constants.AbilityType;
+import mage.constants.CardType;
import mage.constants.MageObjectType;
import mage.game.Game;
import mage.game.stack.StackAbility;
@@ -58,16 +59,37 @@ public class StackAbilityView extends CardView {
this.sourceCard = sourceCard;
this.sourceCard.setMageObjectType(mageObjectType);
this.name = "Ability";
- this.rules = new ArrayList<>();
- rules.add(ability.getRule(sourceName));
- this.power = ability.getPower().toString();
- this.toughness = ability.getToughness().toString();
this.loyalty = "";
+
this.cardTypes = ability.getCardType();
this.subTypes = ability.getSubtype();
this.superTypes = ability.getSupertype();
this.color = ability.getColor();
this.manaCost = ability.getManaCost().getSymbols();
+ this.cardTypes = ability.getCardType();
+ this.subTypes = ability.getSubtype();
+ this.superTypes = ability.getSupertype();
+ this.color = ability.getColor();
+ this.manaCost = ability.getManaCost().getSymbols();
+ this.power = ability.getPower().toString();
+ this.toughness = ability.getToughness().toString();
+ String nameToShow;
+ if (sourceCard.isMorphCard() && sourceCard.isFaceDown()) {
+ CardView tmpSourceCard = this.getSourceCard();
+ tmpSourceCard.displayName = "Face Down";
+ tmpSourceCard.superTypes.clear();
+ tmpSourceCard.subTypes.clear();
+ tmpSourceCard.cardTypes.clear();
+ tmpSourceCard.cardTypes.add(CardType.CREATURE);
+ tmpSourceCard.manaCost.clear();
+ tmpSourceCard.power = "2";
+ tmpSourceCard.toughness = "2";
+ nameToShow = "creature without name";
+ } else {
+ nameToShow = sourceName;
+ }
+ this.rules = new ArrayList<>();
+ rules.add(ability.getRule(nameToShow));
this.counters = sourceCard.getCounters();
updateTargets(game, ability);
@@ -117,6 +139,7 @@ public class StackAbilityView extends CardView {
return this.sourceCard;
}
+ @Override
public AbilityType getAbilityType() {
return abilityType;
}
diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java
index 200e01e074b..2bd38d50249 100644
--- a/Mage/src/mage/game/permanent/PermanentCard.java
+++ b/Mage/src/mage/game/permanent/PermanentCard.java
@@ -129,10 +129,10 @@ public class PermanentCard extends PermanentImpl {
@Override
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, ArrayList appliedEffects) {
- Zone fromZone = game.getState().getZone(objectId);
+ Zone fromZone = game.getState().getZone(objectId);
Player controller = game.getPlayer(controllerId);
if (controller != null && controller.removeFromBattlefield(this, game)) {
- if (isFaceDown()) {
+ if (isFaceDown() && isMorphCard()) {
setFaceDown(false);
game.getCard(this.getId()).setFaceDown(false); //TODO: Do this in a better way
}
@@ -183,6 +183,10 @@ 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);
diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java
index 7e757cc4e39..a42d3a5a35c 100644
--- a/Mage/src/mage/players/PlayerImpl.java
+++ b/Mage/src/mage/players/PlayerImpl.java
@@ -2469,6 +2469,9 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToHandWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
boolean result = false;
if (card.moveToZone(Zone.HAND, sourceId, game, false)) {
+ if (card instanceof Permanent) {
+ card = game.getCard(card.getId());
+ }
game.informPlayers(new StringBuilder(this.getName())
.append(" puts ").append(card.isFaceDown() ? " a face down card":card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
@@ -2482,6 +2485,9 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
boolean result = false;
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone.equals(Zone.BATTLEFIELD) : false)) {
+ if (card instanceof Permanent) {
+ card = game.getCard(card.getId());
+ }
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"");
@@ -2500,6 +2506,9 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) {
boolean result = false;
if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) {
+ if (card instanceof Permanent) {
+ card = game.getCard(card.getId());
+ }
StringBuilder sb = new StringBuilder(this.getName())
.append(" puts ").append(withName ? card.getLogName():"a card").append(" ");
if (fromZone != null) {
@@ -2528,6 +2537,9 @@ public abstract class PlayerImpl implements Player, Serializable {
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, Game game, Zone fromZone) {
boolean result = false;
if (card.moveToExile(exileId, exileName, sourceId, game)) {
+ if (card instanceof Permanent) {
+ card = game.getCard(card.getId());
+ }
game.informPlayers(new StringBuilder(this.getName())
.append(" moves ").append(card.getLogName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")