, IIdentifiable
this.owner = player;
}
+ public final void setMayLookAt(final Player player, final boolean mayLookAt) {
+ if (mayLookAt) {
+ this.mayLookAt.add(player);
+ } else {
+ this.mayLookAt.remove(player);
+ }
+ }
+
/**
*
* Getter for the field equippedBy.
@@ -4013,7 +4022,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable
* left and right values of a {@link Pair}, respectively. A value of -1
* means that particular property has not been set.
*/
- private final Pair getLatestPT() {
+ private final synchronized Pair getLatestPT() {
// Find latest set power
long maxPowerTimestamp = -2;
int latestPower = -1;
@@ -6336,9 +6345,13 @@ public class Card extends GameEntity implements Comparable, IIdentifiable
final SpellAbility root = sa.getRootAbility();
if (root != null && (root.getPaidList("MovedToGrave") != null)
&& !root.getPaidList("MovedToGrave").isEmpty()) {
- List list = root.getPaidList("MovedToGrave");
- for (Card card : list) {
- if (this.getName().equals(card.getName())) {
+ final List list = root.getPaidList("MovedToGrave");
+ for (final Card card : list) {
+ String name = card.getName();
+ if (StringUtils.isEmpty(name)) {
+ name = card.getPaperCard().getName();
+ }
+ if (this.getName().equals(name)) {
return true;
}
}
@@ -8933,15 +8946,9 @@ public class Card extends GameEntity implements Comparable, IIdentifiable
return true;
}
- //one last check to see if card can be shown
- final Game game = this.getGame();
- for (Card host : game.getCardsIn(ZoneType.Battlefield)) {
- final ArrayList staticAbilities = host.getStaticAbilities();
- for (final StaticAbility stAb : staticAbilities) {
- if (stAb.applyAbility("MayLookAt", this, viewer)) {
- return true;
- }
- }
+ // special viewing permissions for viewer
+ if (this.mayLookAt.contains(viewer)) {
+ return true;
}
//if viewer is controlled by another player, also check if card can be shown to that player
@@ -8959,6 +8966,12 @@ public class Card extends GameEntity implements Comparable, IIdentifiable
if (viewer.hasKeyword("CanSeeOpponentsFaceDownCards")) {
return true;
}
+
+ // special viewing permissions for viewer
+ if (this.mayLookAt.contains(viewer)) {
+ return true;
+ }
+
//if viewer is controlled by another player, also check if face can be shown to that player
if (viewer.isMindSlaved() && canCardFaceBeShownTo(viewer.getMindSlaveMaster())) {
return true;
diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java
index 7f4503c4772..2f2273285cc 100644
--- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java
+++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java
@@ -19,6 +19,7 @@ package forge.game.phase;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
import forge.card.mana.ManaCost;
import forge.game.*;
@@ -384,7 +385,7 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
givePriorityToPlayer = false;
// Rule 514.3a - state-based actions
- game.getAction().checkStateEffects();
+ game.getAction().checkStateEffects(true);
break;
default:
@@ -1001,17 +1002,19 @@ public class PhaseHandler implements java.io.Serializable, IGameStateObject {
int loopCount = 0;
do {
-
+ final Set allAffectedCards = Sets.newHashSet();
boolean addedAnythingToStack = false;
do {
// Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions,
- game.getAction().checkStateEffects();
+ allAffectedCards.addAll(game.getAction().checkStateEffects(false));
if (game.isGameOver())
return; // state-based effects check could lead to game over
addedAnythingToStack = game.getStack().addAllTriggeredAbilitiesToStack();
} while(addedAnythingToStack);
+ game.fireEvent(new GameEventCardStatsChanged(allAffectedCards));
+
if (playerTurn.hasLost() && pPlayerPriority.equals(playerTurn) && pFirstPriority.equals(playerTurn)) {
// If the active player has lost, and they have priority, set the next player to have priority
System.out.println("Active player is no longer in the game...");
diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java
index 1647e6967e6..d3ab554f28f 100644
--- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java
+++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java
@@ -288,10 +288,6 @@ public class StaticAbility extends CardTraitBase {
return StaticAbilityCantBeCast.applyCantPlayLandAbility(this, card, player);
}
- if (mode.equals("MayLookAt")) {
- return StaticAbilityMayLookAt.applyMayLookAtAbility(this, card, player);
- }
-
return false;
}
diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java
index 8df21f2ec27..b1d7dfb555d 100644
--- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java
+++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java
@@ -69,6 +69,7 @@ public class StaticAbilityContinuous {
public static List applyContinuousAbility(final StaticAbility stAb, List affectedCards) {
final Map params = stAb.getMapParams();
final Card hostCard = stAb.getHostCard();
+ final Player controller = hostCard.getController();
final StaticEffect se = new StaticEffect(hostCard);
final ArrayList affectedPlayers = StaticAbilityContinuous.getAffectedPlayers(stAb);
@@ -109,6 +110,7 @@ public class StaticAbilityContinuous {
boolean removeCardTypes = false;
boolean removeSubTypes = false;
boolean removeCreatureTypes = false;
+ boolean controllerMayLookAt = false;
//Global rules changes
if (params.containsKey("GlobalRule")) {
@@ -326,6 +328,10 @@ public class StaticAbilityContinuous {
}
}
+ if (params.containsKey("MayLookAt")) {
+ controllerMayLookAt = true;
+ }
+
if (params.containsKey("IgnoreEffectCost")) {
String cost = params.get("IgnoreEffectCost");
buildIgnorEffectAbility(stAb, cost, affectedPlayers, affectedCards);
@@ -551,6 +557,10 @@ public class StaticAbilityContinuous {
rE.setTemporarilySuppressed(true);
}
}
+
+ if (controllerMayLookAt) {
+ affectedCard.setMayLookAt(controller, true);
+ }
}
return affectedCards;
diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java
deleted file mode 100644
index 1c610bd29b3..00000000000
--- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityMayLookAt.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Forge: Play Magic: the Gathering.
- * Copyright (C) 2011 Forge Team
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package forge.game.staticability;
-
-import forge.game.card.Card;
-import forge.game.player.Player;
-import forge.game.zone.ZoneType;
-
-import java.util.Map;
-
-/**
- * The Class StaticAbility_CantBeCast.
- */
-public class StaticAbilityMayLookAt {
-
- /**
- * TODO Write javadoc for this method.
- *
- * @param stAb
- * a StaticAbility
- * @param card
- * the card
- * @param activator
- * the player
- * @return true, if successful
- */
- public static boolean applyMayLookAtAbility(final StaticAbility stAb, final Card card, final Player player) {
- final Map params = stAb.getMapParams();
- final Card hostCard = stAb.getHostCard();
-
- if (params.containsKey("Affected")
- && !card.isValid(params.get("Affected").split(","), hostCard.getController(), hostCard)) {
- return false;
- }
-
- if (params.containsKey("Player") && player != null
- && !player.isValid(params.get("Player"), hostCard.getController(), hostCard)) {
- return false;
- }
-
- if (params.containsKey("AffectedZone")) {
- ZoneType zone = card.getGame().getZoneOf(card).getZoneType();
- if (!ZoneType.listValueOf(params.get("AffectedZone")).contains(zone)) {
- return false;
- }
- }
-
- return true;
- }
-}
diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java
index c93caa295fd..1fb102d4174 100644
--- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java
+++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java
@@ -10,11 +10,13 @@ import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Collection;
import java.util.List;
+
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import org.apache.commons.lang3.StringUtils;
+
import com.google.common.base.Function;
import forge.assets.FSkinProp;
@@ -145,11 +147,7 @@ public class GuiDesktop implements IGuiBase {
}
@Override
- public T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) {
- if (initialInput instanceof GameObject || (inputOptions != null && inputOptions.length > 0 && inputOptions[0] instanceof GameObject)) {
- System.err.println("Warning: GameObject passed to GUI! Printing stack trace.");
- Thread.dumpStack();
- }
+ public String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) {
return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions);
}
diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java
index e8a2d4f9fb3..2107dcfae39 100644
--- a/forge-gui-mobile/src/forge/GuiMobile.java
+++ b/forge-gui-mobile/src/forge/GuiMobile.java
@@ -3,6 +3,7 @@ package forge;
import java.io.File;
import java.util.Collection;
import java.util.List;
+
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.graphics.Texture;
@@ -153,8 +154,8 @@ public class GuiMobile implements IGuiBase {
}
@Override
- public T showInputDialog(final String message, final String title, final FSkinProp icon, final T initialInput, final T[] inputOptions) {
- return new WaitCallback() {
+ public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) {
+ return new WaitCallback() {
@Override
public void run() {
FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImages().get(icon), initialInput, inputOptions, this);
diff --git a/forge-gui/res/cardsfolder/b/bane_alley_broker.txt b/forge-gui/res/cardsfolder/b/bane_alley_broker.txt
index 00f57aa8d93..baea848bd9c 100644
--- a/forge-gui/res/cardsfolder/b/bane_alley_broker.txt
+++ b/forge-gui/res/cardsfolder/b/bane_alley_broker.txt
@@ -4,7 +4,7 @@ Types:Creature Human Rogue
PT:0/3
A:AB$ Draw | Cost$ T | NumCards$ 1 | SubAbility$ DBExile | SpellDescription$ Draw a card, then exile a card from your hand face down.
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 1 | ExileFaceDown$ True | Mandatory$ True | RememberChanged$ True
-S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME.
+S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayLookAt$ True | Description$ You may look at cards exiled with CARDNAME.
A:AB$ ChooseCard | Cost$ U B T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card to put into your hand | Choices$ Card.IsRemembered | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card exiled with CARDNAME to its owner's hand.
SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget
diff --git a/forge-gui/res/cardsfolder/g/grimoire_thief.txt b/forge-gui/res/cardsfolder/g/grimoire_thief.txt
index db0f149e5b7..55cb321d64d 100644
--- a/forge-gui/res/cardsfolder/g/grimoire_thief.txt
+++ b/forge-gui/res/cardsfolder/g/grimoire_thief.txt
@@ -4,7 +4,7 @@ Types:Creature Merfolk Rogue
PT:2/2
T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ Whenever CARDNAME becomes tapped, exile the top three cards of target opponent's library face down.
SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Opponent | NumCards$ 3 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True
-S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME.
+S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayLookAt$ True | Description$ You may look at cards exiled with CARDNAME.
A:AB$ SetState | Cost$ U Sac<1/CARDNAME> | Defined$ Remembered | Mode$ TurnFace | SubAbility$ DBCounter | SpellDescription$ Turn all cards exiled with CARDNAME face up. Counter all spells with those names.
SVar:DBCounter:DB$ Counter | AllType$ Spell | AllValid$ Card.sharesNameWith Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
diff --git a/forge-gui/res/cardsfolder/g/gusthas_scepter.txt b/forge-gui/res/cardsfolder/g/gusthas_scepter.txt
index cb3cbefecff..61c79807a4d 100644
--- a/forge-gui/res/cardsfolder/g/gusthas_scepter.txt
+++ b/forge-gui/res/cardsfolder/g/gusthas_scepter.txt
@@ -1,8 +1,8 @@
Name:Gustha's Scepter
ManaCost:0
Types:Artifact
-A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled.
-S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile
+A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SubAbility$ DBMayLookAt | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled.
+SVar:DBMayLookAt:DB$ Pump | Defined$ Remembered | PumpZone$ Exile | KW$ You may look at this card. | Permanent$ True
A:AB$ ChooseCard | Cost$ T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card you own to put into your hand | Choices$ Card.IsRemembered+YouOwn | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card you own exiled with CARDNAME to your hand.
SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget
diff --git a/forge-gui/res/cardsfolder/j/jesters_scepter.txt b/forge-gui/res/cardsfolder/j/jesters_scepter.txt
index e6456753fdb..fbf6e0cf5a1 100644
--- a/forge-gui/res/cardsfolder/j/jesters_scepter.txt
+++ b/forge-gui/res/cardsfolder/j/jesters_scepter.txt
@@ -1,9 +1,11 @@
Name:Jester's Scepter
ManaCost:3
Types:Artifact
-T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile the top five cards of target player's library face down.
-SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Player | NumCards$ 5 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True
-S:Mode$ MayLookAt | Affected$ Card.IsRemembered | Player$ You | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME.
+T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.
+SVar:TrigExile:AB$ Mill | Cost$ 0 | ValidTgts$ Player | NumCards$ 5 | Destination$ Exile | ExileFaceDown$ True | RememberMilled$ True | SubAbility$ DBMayLookAt
+SVar:DBMayLookAt:DB$ Effect | Name$ Jester's Scepter Effect | StaticAbilities$ SMayLookAt | Triggers$ TForget | SVars$ DBForget | RememberObjects$ Remembered | Duration$ Permanent
+SVar:SMayLookAt:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | EffectZone$ Command | MayLookAt$ True | Duration$ Permanent
+SVar:TForget:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ DBCleanup | Static$ True
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget
@@ -12,4 +14,4 @@ A:AB$ Counter | Cost$ 2 T ExiledMoveToGrave<1/Card.IsRemembered/card exiled with
SVar:X:Targeted$Valid Card.sharesNameWith MovedToGrave
SVar:RemAIDeck:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/jesters_scepter.jpg
-Oracle:When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.\n{2}, {T}, Put a card exiled with Jester's Scepter into its owner's graveyard: Counter target spell if it has the same name as that card.
+Oracle:When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. You may look at those cards for as long as they remain exiled.\n{2}, {T}, Put a card exiled with Jester's Scepter into its owner's graveyard: Counter target spell if it has the same name as that card.
\ No newline at end of file
diff --git a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java
index 11f99a7fa46..22122a393d5 100644
--- a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java
+++ b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java
@@ -102,7 +102,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base {
return null;
}
- public void updateCombat() {
+ private void updateCombat() {
if (!isMainHandler || combatUpdPlanned.getAndSet(true)) { return; }
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
index 301a06e573b..a05a9e8e53a 100644
--- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
+++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java
@@ -3,6 +3,7 @@ package forge.interfaces;
import java.io.File;
import java.util.Collection;
import java.util.List;
+
import com.google.common.base.Function;
import forge.LobbyPlayer;
@@ -29,7 +30,7 @@ public interface IGuiBase {
void showImageDialog(ISkinImage image, String message, String title);
int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption);
int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption);
- T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);
+ String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions);
List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display);
List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode);
diff --git a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java
index 462ae03238e..e086f4b6d46 100644
--- a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java
+++ b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java
@@ -192,7 +192,7 @@ public class SGuiChoose {
}
public static List many(final IGuiBase gui, final String title, final String topCaption, int cnt, final List sourceChoices, final CardView referenceCard) {
- return order(gui, title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
+ return many(gui, title, topCaption, cnt, cnt, sourceChoices, referenceCard);
}
public static List many(final IGuiBase gui, final String title, final String topCaption, int min, int max, final List sourceChoices, final CardView referenceCard) {
diff --git a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java
index 442c984f289..c690c947f84 100644
--- a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java
+++ b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java
@@ -76,7 +76,7 @@ public class SOptionPane {
return showInputDialog(gui, message, title, icon, initialInput, null);
}
- public static T showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, T initialInput, T[] inputOptions) {
+ public static String showInputDialog(IGuiBase gui, String message, String title, FSkinProp icon, String initialInput, String[] inputOptions) {
return gui.showInputDialog(message, title, icon, initialInput, inputOptions);
}
diff --git a/forge-gui/src/main/java/forge/view/CardView.java b/forge-gui/src/main/java/forge/view/CardView.java
index eeae117d4da..7e68202fcf0 100644
--- a/forge-gui/src/main/java/forge/view/CardView.java
+++ b/forge-gui/src/main/java/forge/view/CardView.java
@@ -726,7 +726,23 @@ public class CardView extends GameEntityView {
@Override
public String toString() {
- return this.getOriginal().toString();
+ if (StringUtils.isEmpty(this.getOriginal().getName())) {
+ if (this.getId() <= 0) {
+ return "(Unknown card)";
+ } else if (this.hasAltState()) {
+ return "Face-down card (" + this.getAlternate().getName() + ")";
+ }
+ }
+
+ return this.getOriginal().getName() + " (" + this.getId() + ")";
+ }
+
+ public String determineName(final CardStateView state) {
+ if (state == original) {
+ return this.toString();
+ }
+
+ return this.getAlternate().getName() + " (" + this.getId() + ")";
}
public class CardStateView {
@@ -767,10 +783,7 @@ public class CardView extends GameEntityView {
@Override
public String toString() {
- if (StringUtils.isEmpty(this.getName()) && this.getCard().getId() <= 0) {
- return "(Unknown card)";
- }
- return this.getName() + " (" + this.getCard().getId() + ")";
+ return this.getCard().determineName(this);
}
public CardView getCard() {