diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 5667179d12b..f6d48706a99 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -164,7 +164,7 @@ public class AbilityUtils { } } else if (defined.equals("Remembered")) { - if (hostCard.getRemembered().isEmpty()) { + if (!hostCard.hasRemembered()) { final Card newCard = game.getCardState(hostCard); for (final Object o : newCard.getRemembered()) { if (o instanceof Card) { @@ -180,7 +180,7 @@ public class AbilityUtils { } } else if (defined.equals("DirectRemembered")) { - if (hostCard.getRemembered().isEmpty()) { + if (!hostCard.hasRemembered()) { final Card newCard = game.getCardState(hostCard); for (final Object o : newCard.getRemembered()) { if (o instanceof Card) { @@ -456,7 +456,7 @@ public class AbilityUtils { // Add whole Remembered list to handlePaid final List list = new ArrayList(); Card newCard = card; - if (card.getRemembered().isEmpty()) { + if (!card.hasRemembered()) { newCard = game.getCardState(card); } @@ -1287,11 +1287,12 @@ public class AbilityUtils { } } else if (unlessCost.equals("RememberedCostMinus2")) { - if (source.getRemembered().isEmpty() || !(source.getRemembered().get(0) instanceof Card)) { + Card rememberedCard = (Card) source.getFirstRemembered(); + if (rememberedCard == null) { sa.resolve(); resolveSubAbilities(sa, game); + return; } - Card rememberedCard = (Card) source.getRemembered().get(0); ManaCostBeingPaid newCost = new ManaCostBeingPaid(rememberedCard.getManaCost()); newCost.decreaseColorlessMana(2); cost = new Cost(newCost.toManaCost(), true); @@ -1355,7 +1356,7 @@ public class AbilityUtils { if (sa.hasParam("RememberCostMana")) { host.clearRemembered(); - host.getRemembered().addAll(sa.getPayingMana()); + host.addRemembered(sa.getPayingMana()); } if (sa.hasParam("RememberCostCards") && !sa.getPaidHash().isEmpty()) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java index bd53a8a981d..c1849d4c345 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java @@ -133,14 +133,14 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { if (remember != null) { game.getCardState(source).addRemembered(movedCard); - if (!source.getRemembered().contains(movedCard)) { + if (!source.isRemembered(movedCard)) { source.addRemembered(movedCard); } } if (remLKI && movedCard != null) { final Card lki = CardUtil.getLKICopy(c); game.getCardState(source).addRemembered(lki); - if (!source.getRemembered().contains(lki)) { + if (!source.isRemembered(lki)) { source.addRemembered(lki); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 43f95f24c62..6d98c87f7b5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -544,7 +544,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { hostCard.addRemembered(movedCard); } if (forget != null && !movedCard.getZone().equals(originZone)) { - hostCard.getRemembered().remove(movedCard); + hostCard.removeRemembered(movedCard); } if (imprint != null && !movedCard.getZone().equals(originZone)) { hostCard.addImprintedCard(movedCard); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java index 517f0cb9241..abc0c357358 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseNumberEffect.java @@ -138,7 +138,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect { card.clearRemembered(); } if (sa.hasParam("RememberHighest")) { - card.getRemembered().addAll(highestNum); + card.addRemembered(highestNum); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CleanUpEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CleanUpEffect.java index de15cbde656..eae600a8b00 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CleanUpEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CleanUpEffect.java @@ -23,7 +23,7 @@ public class CleanUpEffect extends SpellAbilityEffect { } if (sa.hasParam("ForgetDefined")) { for (final Card card : AbilityUtils.getDefinedCards(source, sa.getParam("ForgetDefined"), sa)) { - source.getRemembered().remove(card); + source.removeRemembered(card); } } if (sa.hasParam("ClearImprinted")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index 7228f6f78a0..a4ec5258288 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -174,31 +174,30 @@ public class CloneEffect extends SpellAbilityEffect { @Override public void run() { if (cloneCard.isCloned()) { - cloneCard.switchStates(CardCharacteristicName.Cloner, CardCharacteristicName.Original); - cloneCard.setState(CardCharacteristicName.Original); - cloneCard.clearStates(CardCharacteristicName.Cloner); + cloneCard.switchStates(CardCharacteristicName.Cloner, CardCharacteristicName.Original); + cloneCard.setState(CardCharacteristicName.Original); + cloneCard.clearStates(CardCharacteristicName.Cloner); } } }; - String duration = sa.getParam("Duration"); if (duration.equals("UntilEndOfTurn")) { game.getEndOfTurn().addUntil(unclone); - } else if (duration.equals("UntilYourNextTurn")) { + } + else if (duration.equals("UntilYourNextTurn")) { game.getCleanup().addUntil(host.getController(), unclone); } } - game.fireEvent(new GameEventCardStatsChanged(tgtCard)); } // cloneResolve private void addExtraCharacteristics(final Card tgtCard, final SpellAbility sa, final Map origSVars) { // additional types to clone if (sa.hasParam("AddTypes")) { - for (final String type : Arrays.asList(sa.getParam("AddTypes").split(","))) { - tgtCard.addType(type); - } + for (final String type : Arrays.asList(sa.getParam("AddTypes").split(","))) { + tgtCard.addType(type); + } } // triggers to add to clone diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java index bc9b791ccf3..d7451477eb0 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java @@ -129,11 +129,11 @@ public class ControlGainEffect extends SpellAbilityEffect { } } - if (remember && !sa.getHostCard().getRemembered().contains(tgtC)) { + if (remember && !sa.getHostCard().isRemembered(tgtC)) { sa.getHostCard().addRemembered(tgtC); } - if (forget && sa.getHostCard().getRemembered().contains(tgtC)) { + if (forget && sa.getHostCard().isRemembered(tgtC)) { sa.getHostCard().removeRemembered(tgtC); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index 9042cb8e743..96f64eebd6b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -127,7 +127,7 @@ public class CounterEffect extends SpellAbilityEffect { if (sa.hasParam("RememberSplicedOntoCounteredSpell")) { if (tgtSA.getSplicedCards() != null) { - sa.getHostCard().getRemembered().addAll(tgtSA.getSplicedCards()); + sa.getHostCard().addRemembered(tgtSA.getSplicedCards()); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java index 00b398aaeeb..655466e7b17 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java @@ -11,12 +11,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import com.google.common.collect.Iterables; - public class DestroyEffect extends SpellAbilityEffect { - /* (non-Javadoc) - * @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility) - */ @Override protected String getStackDescription(SpellAbility sa) { final boolean noRegen = sa.hasParam("NoRegen"); @@ -99,9 +94,9 @@ public class DestroyEffect extends SpellAbilityEffect { boolean destroyed = false; final Card lki = CardUtil.getLKICopy(tgtC); if (remAttached) { - Iterables.addAll(card.getRemembered(), tgtC.getEnchantedBy(false)); - Iterables.addAll(card.getRemembered(), tgtC.getEquippedBy(false)); - Iterables.addAll(card.getRemembered(), tgtC.getFortifiedBy(false)); + card.addRemembered(tgtC.getEnchantedBy(false)); + card.addRemembered(tgtC.getEquippedBy(false)); + card.addRemembered(tgtC.getFortifiedBy(false)); } if (sac) { destroyed = game.getAction().sacrifice(tgtC, sa) != null; diff --git a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java index e553f50ef43..68c5f5a457f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java @@ -250,8 +250,9 @@ public class PumpEffect extends SpellAbilityEffect { final String targets = Lang.joinHomogenous(tgtCards); final String message = sa.hasParam("OptionQuestion") ? sa.getParam("OptionQuestion").replace("TARGETS", targets) : "Apply pump to " + targets + "?"; - if ( !sa.getActivatingPlayer().getController().confirmAction(sa, null, message) ) + if (!sa.getActivatingPlayer().getController().confirmAction(sa, null, message)) { return; + } } if (sa.hasParam("RememberObjects")) { @@ -260,9 +261,7 @@ public class PumpEffect extends SpellAbilityEffect { if (pumpRemembered != null) { for (final Object o : AbilityUtils.getDefinedObjects(host, pumpRemembered, sa)) { - if (!host.getRemembered().contains(o)) { - host.addRemembered(o); - } + host.addRemembered(o); } } @@ -272,9 +271,7 @@ public class PumpEffect extends SpellAbilityEffect { if (pumpForget != null) { for (final Object o : AbilityUtils.getDefinedObjects(host, pumpForget, sa)) { - if (host.getRemembered().contains(o)) { - host.removeRemembered(o); - } + host.removeRemembered(o); } } if (sa.hasParam("ImprintCards")) { @@ -283,17 +280,13 @@ public class PumpEffect extends SpellAbilityEffect { if (pumpImprint != null) { for (final Card c : AbilityUtils.getDefinedCards(host, pumpImprint, sa)) { - if (!host.getImprintedCards().contains(c)) { - host.addImprintedCard(c); - } + host.addImprintedCard(c); } } if (sa.hasParam("ForgetImprinted")) { for (final Card c : AbilityUtils.getDefinedCards(host, sa.getParam("ForgetImprinted"), sa)) { - if (host.getImprintedCards().contains(c)) { - host.removeImprintedCard(c); - } + host.removeImprintedCard(c); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java index 3b995cfd800..5b36e3c03f5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java @@ -334,9 +334,7 @@ public class TokenEffect extends SpellAbilityEffect { final Card token = game.getCardState(c); final String remembered = sa.getParam("TokenRemembered"); for (final Object o : AbilityUtils.getDefinedObjects(host, remembered, sa)) { - if (!token.getRemembered().contains(o)) { - token.addRemembered(o); - } + token.addRemembered(o); } } } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index c6197eb6e33..a1640d35911 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -141,7 +141,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable /** Original values of SVars changed by text changes. */ private Map originalSVars = Maps.newHashMap(); - private final ArrayList rememberedObjects = new ArrayList(); + private final Set rememberedObjects = new LinkedHashSet(); private final MapOfLists rememberMap = new HashMapOfLists(CollectionSuppliers.arrayLists()); private Map flipResult; @@ -463,17 +463,46 @@ public class Card extends GameEntity implements Comparable, IIdentifiable rememberMap.addAll(e, o); } - public final ArrayList getRemembered() { + public final Iterable getRemembered() { return rememberedObjects; } - public final void addRemembered(final Object o) { - rememberedObjects.add(o); + public final boolean hasRemembered() { + return !rememberedObjects.isEmpty(); } - public final void removeRemembered(final Object o) { - rememberedObjects.remove(o); + public final int getRememberedCount() { + return rememberedObjects.size(); + } + public final Object getFirstRemembered() { + return Iterables.getFirst(rememberedObjects, null); + } + public final boolean isRemembered(T o) { + return rememberedObjects.contains(o); + } + public final void addRemembered(final T o) { + if (rememberedObjects.add(o)) { + view.updateRemembered(this); + } + } + public final void addRemembered(final Iterable objects) { + boolean changed = false; + for (T o : objects) { + if (rememberedObjects.add(o)) { + changed = true; + } + } + if (changed) { + view.updateRemembered(this); + } + } + public final void removeRemembered(final T o) { + if (rememberedObjects.remove(o)) { + view.updateRemembered(this); + } } public final void clearRemembered() { + if (rememberedObjects.isEmpty()) { return; } rememberedObjects.clear(); + view.updateRemembered(this); } public final CardCollectionView getImprintedCards() { @@ -1062,7 +1091,9 @@ public class Card extends GameEntity implements Comparable, IIdentifiable return chosenDirection; } public void setChosenDirection(Direction chosenDirection0) { + if (chosenDirection == chosenDirection0) { return; } chosenDirection = chosenDirection0; + view.updateChosenDirection(this); } // used for cards like Meddling Mage... @@ -1106,98 +1137,6 @@ public class Card extends GameEntity implements Comparable, IIdentifiable text = originalText; } - // get the text that should be displayed - public String getText() { - final StringBuilder sb = new StringBuilder(); - - // Vanguard Modifiers - if (isType("Vanguard")) { - sb.append("Hand Modifier: ").append(getRules().getHand()); - sb.append("\r\nLife Modifier: ").append(getRules().getLife()); - sb.append("\r\n\r\n"); - } - if (isCommander) { - sb.append(getOwner()).append("'s Commander\r\n"); - sb.append(CardFactoryUtil.getCommanderInfo(getOwner())).append("\r\n"); - } - sb.append(getAbilityText()); - - String nonAbilityText = getNonAbilityText(); - if (getAmountOfKeyword("CARDNAME can block an additional creature.") > 1) { - final StringBuilder ab = new StringBuilder(); - ab.append("CARDNAME can block an additional "); - ab.append(getAmountOfKeyword("CARDNAME can block an additional creature.")); - ab.append(" creatures."); - nonAbilityText = nonAbilityText.replaceFirst("CARDNAME can block an additional creature.", ab.toString()); - nonAbilityText = nonAbilityText.replaceAll("CARDNAME can block an additional creature.", ""); - nonAbilityText = nonAbilityText.replaceAll("\r\n\r\n\r\n", ""); - } - if (nonAbilityText.length() > 0) { - sb.append("\r\n \r\nNon ability features: \r\n"); - sb.append(nonAbilityText.replaceAll("CARDNAME", getName())); - } - - // Remembered cards - if (rememberedObjects.size() > 0) { - sb.append("\r\nRemembered: \r\n"); - for (final Object o : rememberedObjects) { - if (o instanceof Card) { - final Card c = (Card) o; - if (c.isFaceDown()) { - sb.append("Face Down"); - // face-down cards don't show unique number to avoid cheating - } else { - sb.append(c.getName()); - sb.append(" ("); - sb.append(c.getId()); - sb.append(")"); - } - } else if (o != null) { - sb.append(o.toString()); - } - sb.append("\r\n"); - } - } - - if (chosenPlayer != null) { - sb.append("\r\n[Chosen player: "); - sb.append(getChosenPlayer()); - sb.append("]\r\n"); - } - - if (chosenDirection != null) { - sb.append("\r\n[Chosen direction: "); - sb.append(getChosenDirection()); - sb.append("]\r\n"); - } - - if (isHaunted()) { - sb.append("Haunted by: "); - for (final Card c : hauntedBy) { - sb.append(c).append(","); - } - sb.deleteCharAt(sb.length() - 1); - sb.append("\r\n"); - } - - if (haunting != null) { - sb.append("Haunting: ").append(haunting); - sb.append("\r\n"); - } - - if (pairedWith != null) { - sb.append("\r\n \r\nPaired With: ").append(pairedWith); - sb.append("\r\n"); - } - - if (characteristicsMap.get(CardCharacteristicName.Cloner) != null) { - sb.append("\r\nCloned by: ").append(characteristicsMap.get(CardCharacteristicName.Cloner).getName()).append(" (") - .append(id).append(")"); - } - - return sb.toString(); - } - // get the text that does not belong to a cards abilities (and is not really // there rules-wise) public final String getNonAbilityText() { @@ -3433,9 +3372,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable // Takes one argument like Permanent.Blue+withFlying @Override public final boolean isValid(final String restriction, final Player sourceController, final Card source) { - - if (isImmutable() - && !source.getRemembered().contains(this)) { // special case exclusion + if (isImmutable() && !source.isRemembered(this)) { // special case exclusion return false; } @@ -3494,7 +3431,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable return false; } } else if (property.equals("NamedByRememberedPlayer")) { - if (source.getRemembered().isEmpty()) { + if (!source.hasRemembered()) { final Card newCard = game.getCardState(source); for (final Object o : newCard.getRemembered()) { if (o instanceof Player) { @@ -3587,11 +3524,10 @@ public class Card extends GameEntity implements Comparable, IIdentifiable return false; } if (property.endsWith("ForRemembered")) { - if (source.getRemembered().isEmpty()) { + if (!source.hasRemembered()) { return false; } - if (getGame().getCombat().getDefendingPlayerRelatedTo((Card) source.getRemembered().get(0)) - != getController()) { + if (getGame().getCombat().getDefendingPlayerRelatedTo((Card) source.getFirstRemembered()) != getController()) { return false; } } else { @@ -3626,7 +3562,7 @@ public class Card extends GameEntity implements Comparable, IIdentifiable } } else if (property.startsWith("RememberedPlayer")) { Player p = property.endsWith("Ctrl") ? getController() : getOwner(); - if (source.getRemembered().isEmpty()) { + if (!source.hasRemembered()) { final Card newCard = game.getCardState(source); for (final Object o : newCard.getRemembered()) { if (o instanceof Player) { @@ -3645,14 +3581,14 @@ public class Card extends GameEntity implements Comparable, IIdentifiable } } } else if (property.startsWith("nonRememberedPlayerCtrl")) { - if (source.getRemembered().isEmpty()) { + if (!source.hasRemembered()) { final Card newCard = game.getCardState(source); - if (newCard.getRemembered().contains(getController())) { + if (newCard.isRemembered(getController())) { return false; } } - if (source.getRemembered().contains(getController())) { + if (source.isRemembered(getController())) { return false; } } else if (property.equals("TargetedPlayerCtrl")) { @@ -4935,11 +4871,11 @@ public class Card extends GameEntity implements Comparable, IIdentifiable } return false; } else if (property.equals("IsRemembered")) { - if (!source.getRemembered().contains(this)) { + if (!source.isRemembered(this)) { return false; } } else if (property.equals("IsNotRemembered")) { - if (source.getRemembered().contains(this)) { + if (source.isRemembered(this)) { return false; } } else if (property.equals("IsImprinted")) { diff --git a/forge-game/src/main/java/forge/game/card/CardCharacteristics.java b/forge-game/src/main/java/forge/game/card/CardCharacteristics.java index 3e4375cdd11..b501c171600 100644 --- a/forge-game/src/main/java/forge/game/card/CardCharacteristics.java +++ b/forge-game/src/main/java/forge/game/card/CardCharacteristics.java @@ -126,7 +126,7 @@ public class CardCharacteristics { } public void setOracleText(final String oracleText0) { oracleText = oracleText0; - view.updateText(this); + view.updateOracleText(this); } public final int getBaseAttack() { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index b9217b01d29..977ba487599 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -951,7 +951,7 @@ public class CardFactoryUtil { } if (l[0].startsWith("RememberedSize")) { - return doXMath(c.getRemembered().size(), m, c); + return doXMath(c.getRememberedCount(), m, c); } if (l[0].startsWith("RememberedNumber")) { @@ -1253,7 +1253,7 @@ public class CardFactoryUtil { ce = c.getEquipping(); } else if (sq[0].contains("Remembered")) { - ce = (Card) c.getRemembered().get(0); + ce = (Card) c.getFirstRemembered(); } else { ce = c; diff --git a/forge-game/src/main/java/forge/game/card/CardLists.java b/forge-game/src/main/java/forge/game/card/CardLists.java index 6514155c8f9..6a03b012473 100644 --- a/forge-game/src/main/java/forge/game/card/CardLists.java +++ b/forge-game/src/main/java/forge/game/card/CardLists.java @@ -81,8 +81,8 @@ public class CardLists { public static final Comparator TextLenComparator = new Comparator() { @Override public int compare(final Card a, final Card b) { - final int aLen = a.getText().length(); - final int bLen = b.getText().length(); + final int aLen = a.getView().getText().length(); + final int bLen = b.getView().getText().length(); return aLen - bLen; } }; diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index f7eaf34f8c5..ee010c561f5 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -3,6 +3,7 @@ package forge.game.card; import java.util.Set; import java.util.List; import java.util.Map; + import org.apache.commons.lang3.StringUtils; import com.google.common.base.Predicates; @@ -15,7 +16,9 @@ import forge.card.CardRarity; import forge.card.CardType; import forge.card.ColorSet; import forge.card.mana.ManaCost; +import forge.game.Direction; import forge.game.GameEntityView; +import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; import forge.item.IPaperCard; @@ -240,6 +243,45 @@ public class CardView extends GameEntityView { set(TrackableProperty.ChosenPlayer, c.getChosenPlayer()); } + public Direction getChosenDirection() { + return get(TrackableProperty.ChosenDirection); + } + void updateChosenDirection(Card c) { + set(TrackableProperty.ChosenDirection, c.getChosenDirection()); + } + + private String getRemembered() { + return get(TrackableProperty.Remembered); + } + void updateRemembered(Card c) { + if (c.getRemembered() == null) { + set(TrackableProperty.Remembered, null); + return; + } + StringBuilder sb = new StringBuilder(); + sb.append("\r\nRemembered: \r\n"); + for (final Object o : c.getRemembered()) { + if (o instanceof Card) { + final Card card = (Card) o; + if (card.isFaceDown()) { + sb.append("Face Down"); + // face-down cards don't show unique number to avoid cheating + } + else { + sb.append(card.getName()); + sb.append(" ("); + sb.append(card.getId()); + sb.append(")"); + } + } + else if (o != null) { + sb.append(o.toString()); + } + sb.append("\r\n"); + } + set(TrackableProperty.Remembered, sb.toString()); + } + public String getNamedCard() { return get(TrackableProperty.NamedCard); } @@ -335,6 +377,93 @@ public class CardView extends GameEntityView { set(TrackableProperty.ChangedTypes, c.getChangedTextTypeWords()); } + public String getText() { + final Card card = Card.get(this); //TODO: Avoid needing this + final CardStateView state = getOriginal(); + if (card == null) { + return state.getOracleText().trim(); + } + + final StringBuilder sb = new StringBuilder(); + + // Vanguard Modifiers + if (card.isType("Vanguard")) { + sb.append("Hand Modifier: ").append(card.getRules().getHand()); + sb.append("\r\nLife Modifier: ").append(card.getRules().getLife()); + sb.append("\r\n\r\n"); + } + if (card.isCommander()) { + sb.append(getOwner()).append("'s Commander\r\n"); + sb.append(CardFactoryUtil.getCommanderInfo(Player.get(getOwner()))).append("\r\n"); + } + sb.append(card.getAbilityText()); + + String nonAbilityText = card.getNonAbilityText(); + if (card.getAmountOfKeyword("CARDNAME can block an additional creature.") > 1) { + final StringBuilder ab = new StringBuilder(); + ab.append("CARDNAME can block an additional "); + ab.append(card.getAmountOfKeyword("CARDNAME can block an additional creature.")); + ab.append(" creatures."); + nonAbilityText = nonAbilityText.replaceFirst("CARDNAME can block an additional creature.", ab.toString()); + nonAbilityText = nonAbilityText.replaceAll("CARDNAME can block an additional creature.", ""); + nonAbilityText = nonAbilityText.replaceAll("\r\n\r\n\r\n", ""); + } + if (nonAbilityText.length() > 0) { + sb.append("\r\n \r\nNon ability features: \r\n"); + sb.append(nonAbilityText.replaceAll("CARDNAME", getName())); + } + + sb.append(getRemembered()); + + PlayerView chosenPlayer = getChosenPlayer(); + if (chosenPlayer != null) { + sb.append("\r\n[Chosen player: "); + sb.append(chosenPlayer); + sb.append("]\r\n"); + } + + Direction chosenDirection = getChosenDirection(); + if (chosenDirection != null) { + sb.append("\r\n[Chosen direction: "); + sb.append(chosenDirection); + sb.append("]\r\n"); + } + + Iterable hauntedBy = getHauntedBy(); + if (hauntedBy != null) { + sb.append("Haunted by: "); + boolean needDelim = false; + for (final CardView c : hauntedBy) { + if (needDelim) { + sb.append(","); + } + else { needDelim = false; } + sb.append(c); + } + sb.append("\r\n"); + } + + CardView haunting = getHaunting(); + if (haunting != null) { + sb.append("Haunting: ").append(haunting); + sb.append("\r\n"); + } + + CardView pairedWith = getPairedWith(); + if (pairedWith != null) { + sb.append("\r\n \r\nPaired With: ").append(pairedWith); + sb.append("\r\n"); + } + + CardCharacteristics cloner = card.getState(CardCharacteristicName.Cloner); + if (cloner != null) { + sb.append("\r\nCloned by: ").append(cloner.getView().getName()); + sb.append(" (").append(cloner.getView().getId()).append(")"); + } + + return sb.toString().trim(); + } + public CardStateView getOriginal() { return get(TrackableProperty.Original); } @@ -409,9 +538,9 @@ public class CardView extends GameEntityView { return getOriginal().getName(); } - /*if (!mayBeShown) { + if (!mayBeShown) { return "(Unknown card)"; - }*/ + } if (StringUtils.isEmpty(getOriginal().getName())) { CardStateView alternate = getAlternate(); @@ -501,13 +630,14 @@ public class CardView extends GameEntityView { set(TrackableProperty.Power, c.getNetAttack()); } void updatePower(CardCharacteristics c) { - Card card = Card.get(CardView.this); - if (card != null) { - updatePower(card); //TODO: find a better way to do this - } - else { - set(TrackableProperty.Power, c.getBaseAttack()); + if (CardView.this.getOriginal() == this) { + Card card = Card.get(CardView.this); + if (card != null) { + updatePower(card); //TODO: find a better way to do this + return; + } } + set(TrackableProperty.Power, c.getBaseAttack()); } public int getToughness() { @@ -517,13 +647,14 @@ public class CardView extends GameEntityView { set(TrackableProperty.Toughness, c.getNetDefense()); } void updateToughness(CardCharacteristics c) { - Card card = Card.get(CardView.this); - if (card != null) { - updateToughness(card); //TODO: find a better way to do this - } - else { - set(TrackableProperty.Toughness, c.getBaseDefense()); + if (CardView.this.getOriginal() == this) { + Card card = Card.get(CardView.this); + if (card != null) { + updateToughness(card); //TODO: find a better way to do this + return; + } } + set(TrackableProperty.Toughness, c.getBaseDefense()); } public int getLoyalty() { @@ -533,29 +664,21 @@ public class CardView extends GameEntityView { set(TrackableProperty.Loyalty, c.getCurrentLoyalty()); } void updateLoyalty(CardCharacteristics c) { - Card card = Card.get(CardView.this); - if (card != null) { - updateLoyalty(card); //TODO: find a better way to do this - } - else { - set(TrackableProperty.Loyalty, 0); + if (CardView.this.getOriginal() == this) { + Card card = Card.get(CardView.this); + if (card != null) { + updateLoyalty(card); //TODO: find a better way to do this + return; + } } + set(TrackableProperty.Loyalty, 0); //alternates don't need loyalty } - public String getText() { - return get(TrackableProperty.Text); + public String getOracleText() { + return get(TrackableProperty.OracleText); } - void updateText(Card c) { - set(TrackableProperty.Text, c.getText()); - } - void updateText(CardCharacteristics c) { - Card card = Card.get(CardView.this); - if (card != null) { - updateText(card); //TODO: find a better way to do this - } - else { - set(TrackableProperty.Text, c.getOracleText()); - } + void updateOracleText(CardCharacteristics c) { + set(TrackableProperty.OracleText, c.getOracleText()); } private int foilIndexOverride = -1; diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index ffb360d6611..d7f7a75f862 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1790,11 +1790,11 @@ public class Player extends GameEntity implements Comparable { return false; } } else if (property.equals("IsRemembered")) { - if (!source.getRemembered().contains(this)) { + if (!source.isRemembered(this)) { return false; } } else if (property.equals("IsNotRemembered")) { - if (source.getRemembered().contains(this)) { + if (source.isRemembered(this)) { return false; } } else if (property.startsWith("EnchantedBy")) { diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 881ba38613b..045b659cb3e 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -456,15 +456,16 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public String getStackDescription() { - if (stackDescription.equals(getHostCard().getText().trim())) { - return getHostCard().getName() + " - " + getHostCard().getText(); + String text = getHostCard().getView().getText(); + if (stackDescription.equals(text)) { + return getHostCard().getName() + " - " + text; } return stackDescription.replaceAll("CARDNAME", getHostCard().getName()); } public void setStackDescription(final String s) { originalStackDescription = s; stackDescription = originalStackDescription; - if (StringUtils.isEmpty(description) && StringUtils.isEmpty(hostCard.getText())) { + if (StringUtils.isEmpty(description) && StringUtils.isEmpty(hostCard.getView().getText())) { setDescription(s); } } diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index ec426200ff4..a7979e325a2 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -1,6 +1,7 @@ package forge.trackable; import forge.card.CardRarity; +import forge.game.Direction; import forge.game.GameType; import forge.game.phase.PhaseType; import forge.game.zone.ZoneType; @@ -38,6 +39,8 @@ public enum TrackableProperty { ChosenType(TrackableTypes.StringType), ChosenColors(TrackableTypes.CardViewCollectionType), ChosenPlayer(TrackableTypes.PlayerViewType), + ChosenDirection(TrackableTypes.EnumType(Direction.class)), + Remembered(TrackableTypes.StringType), NamedCard(TrackableTypes.StringType), Equipping(TrackableTypes.CardViewType), EquippedBy(TrackableTypes.CardViewCollectionType), @@ -60,6 +63,7 @@ public enum TrackableProperty { ImageKey(TrackableTypes.StringType), Type(TrackableTypes.StringSetType), ManaCost(TrackableTypes.ManaCostType), + OracleText(TrackableTypes.StringType), Power(TrackableTypes.IntegerType), Toughness(TrackableTypes.IntegerType), Loyalty(TrackableTypes.IntegerType), diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java index 4df390febfb..4c1cca799c7 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java @@ -176,15 +176,12 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen break; } - final String text = state.getText(); - final String firstText = firstState.getText(); - if (!panel.getAttachedPanels().isEmpty() || !card.hasSameCounters(firstPanel.getCard()) || (card.isSick() != firstCard.isSick()) || (state.getPower() != firstState.getPower()) || (state.getToughness() != firstState.getToughness()) - || !(text.equals(firstText)) + || !(card.getText().equals(firstCard.getText())) || (stack.size() == tokenStackMax)) { // If this token has attachments or the stack is full, // put it to the right. diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index f6e00dfc935..107829760f1 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -267,7 +267,7 @@ public class CardImageRenderer { g.drawImage(image, x + (w - iconSize) / 2, y + (h - iconSize) / 2, iconSize, iconSize); } else { - final String text = card.getOriginal().getText(); + final String text = card.getText(); if (StringUtils.isEmpty(text)) { return; } float padding = TEXT_FONT.getCapHeight() * 0.75f; diff --git a/forge-gui/src/main/java/forge/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/card/CardDetailUtil.java index 1341249b6af..00665d0c7c1 100644 --- a/forge-gui/src/main/java/forge/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/card/CardDetailUtil.java @@ -250,7 +250,7 @@ public class CardDetailUtil { if (area.length() != 0) { area.append("\n"); } - String text = state.getText(); + String text = card.getText(); // LEVEL [0-9]+-[0-9]+ // LEVEL [0-9]+\+