diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index 93606b758e9..285e3e15a0b 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -41,14 +41,12 @@ import forge.game.spellability.TargetRestrictions; import forge.game.staticability.StaticAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; -import forge.util.collect.FCollection; - public abstract class GameEntity extends GameObject implements IIdentifiable { protected final int id; private String name = ""; private int preventNextDamage = 0; - protected CardCollection attachedCards; + protected CardCollection attachedCards = new CardCollection(); private Map> preventionShieldsWithEffects = Maps.newTreeMap(); protected Map counters = Maps.newHashMap(); @@ -285,43 +283,36 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { public abstract boolean hasKeyword(final Keyword keyword); public final CardCollectionView getEnchantedBy() { - if (attachedCards == null) { - return CardCollection.EMPTY; - } // enchanted means attached by Aura - return CardLists.filter(attachedCards, CardPredicates.Presets.AURA); + return CardLists.filter(getAttachedCards(), CardPredicates.Presets.AURA); } + // doesn't include phased out cards public final CardCollectionView getAttachedCards() { - return CardCollection.getView(attachedCards); + return CardLists.filter(attachedCards, CardPredicates.phasedIn()); + } + + // for view does include phased out cards + public final CardCollectionView getAllAttachedCards() { + return attachedCards; } public final void setAttachedCards(final Iterable cards) { - if (cards == null) { - attachedCards = null; - } - else { - attachedCards = new CardCollection(cards); - } - - getView().updateAttachedCards(this); + attachedCards = new CardCollection(cards); + updateAttachedCards(); } public final boolean hasCardAttachments() { - return FCollection.hasElements(attachedCards); + return !getAttachedCards().isEmpty(); } public final boolean isEnchanted() { - if (attachedCards == null) { - return false; - } - // enchanted means attached by Aura - return Iterables.any(attachedCards, CardPredicates.Presets.AURA); + return Iterables.any(getAttachedCards(), CardPredicates.Presets.AURA); } public final boolean hasCardAttachment(Card c) { - return FCollection.hasElement(attachedCards, c); + return getAttachedCards().contains(c); } public final boolean isEnchantedBy(Card c) { // Rule 303.4k Even if c is no Aura it still counts @@ -329,9 +320,6 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { } public final boolean hasCardAttachment(final String cardName) { - if (attachedCards == null) { - return false; - } return CardLists.count(getAttachedCards(), CardPredicates.nameEquals(cardName)) > 0; } public final boolean isEnchantedBy(final String cardName) { @@ -344,12 +332,8 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { * @param Card c */ public final void addAttachedCard(final Card c) { - if (attachedCards == null) { - attachedCards = new CardCollection(); - } - if (attachedCards.add(c)) { - getView().updateAttachedCards(this); + updateAttachedCards(); getGame().fireEvent(new GameEventCardAttachment(c, null, this)); } } @@ -359,17 +343,16 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { * @param Card c */ public final void removeAttachedCard(final Card c) { - if (attachedCards == null) { return; } - if (attachedCards.remove(c)) { - if (attachedCards.isEmpty()) { - attachedCards = null; - } - getView().updateAttachedCards(this); + updateAttachedCards(); getGame().fireEvent(new GameEventCardAttachment(c, this, null)); } } + public final void updateAttachedCards() { + getView().updateAttachedCards(this); + } + public final void unAttachAllCards() { for (Card c : Lists.newArrayList(getAttachedCards())) { c.unattachFromEntity(this); diff --git a/forge-game/src/main/java/forge/game/GameEntityView.java b/forge-game/src/main/java/forge/game/GameEntityView.java index 5684e41d424..282d28c8a1b 100644 --- a/forge-game/src/main/java/forge/game/GameEntityView.java +++ b/forge-game/src/main/java/forge/game/GameEntityView.java @@ -1,5 +1,6 @@ package forge.game; +import forge.game.card.CardCollectionView; import forge.game.card.CardView; import forge.trackable.TrackableCollection; import forge.trackable.TrackableObject; @@ -54,6 +55,12 @@ public abstract class GameEntityView extends TrackableObject { public boolean hasCardAttachments() { return getAttachedCards() != null; } + public Iterable getAllAttachedCards() { + return get(TrackableProperty.AllAttachedCards); + } + public boolean hasAnyCardAttachments() { + return getAllAttachedCards() != null; + } protected void updateAttachedCards(GameEntity e) { if (e.hasCardAttachments()) { @@ -62,5 +69,11 @@ public abstract class GameEntityView extends TrackableObject { else { set(TrackableProperty.AttachedCards, null); } + CardCollectionView all = e.getAllAttachedCards(); + if (all.isEmpty()) { + set(TrackableProperty.AllAttachedCards, null); + } else { + set(TrackableProperty.AllAttachedCards, CardView.getCollection(all)); + } } } 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 87f644cce74..1d6e9a16e26 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3226,19 +3226,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final CardCollectionView getEquippedBy() { - if (this.attachedCards == null) { - return CardCollection.EMPTY; - } - - return CardLists.filter(attachedCards, CardPredicates.Presets.EQUIPMENT); + return CardLists.filter(getAttachedCards(), CardPredicates.Presets.EQUIPMENT); } public final boolean isEquipped() { - if (this.attachedCards == null) { - return false; - } - - return Iterables.any(attachedCards, CardPredicates.Presets.EQUIPMENT); + return Iterables.any(getAttachedCards(), CardPredicates.Presets.EQUIPMENT); } public final boolean isEquippedBy(Card c) { return this.hasCardAttachment(c); @@ -3248,19 +3240,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final CardCollectionView getFortifiedBy() { - if (this.attachedCards == null) { - return CardCollection.EMPTY; - } - - return CardLists.filter(attachedCards, CardPredicates.Presets.FORTIFICATION); + return CardLists.filter(getAttachedCards(), CardPredicates.Presets.FORTIFICATION); } public final boolean isFortified() { - if (this.attachedCards == null) { - return false; - } - - return Iterables.any(attachedCards, CardPredicates.Presets.FORTIFICATION); + return Iterables.any(getAttachedCards(), CardPredicates.Presets.FORTIFICATION); } public final boolean isFortifiedBy(Card c) { // 301.5e + 301.6 @@ -4624,6 +4608,12 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } + // update the game entity it was attached to + GameEntity ge = this.getEntityAttachedTo(); + if (ge != null) { + ge.updateAttachedCards(); + } + getGame().fireEvent(new GameEventCardPhased(this, isPhasedOut())); } diff --git a/forge-game/src/main/java/forge/game/card/CardPredicates.java b/forge-game/src/main/java/forge/game/card/CardPredicates.java index ed1d9a3fb2c..56c22dd1429 100644 --- a/forge-game/src/main/java/forge/game/card/CardPredicates.java +++ b/forge-game/src/main/java/forge/game/card/CardPredicates.java @@ -6,12 +6,12 @@ * 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 . */ @@ -37,7 +37,7 @@ import forge.util.collect.FCollectionView; *

* Predicate interface. *

- * + * * @author Forge * @version $Id$ */ @@ -288,7 +288,7 @@ public final class CardPredicates { } }; } - + public static final Predicate greaterCMC(final int cmc) { return new Predicate() { @Override @@ -354,7 +354,7 @@ public final class CardPredicates { public static final Predicate hasCounter(final CounterEnumType type, final int n) { return hasCounter(CounterType.get(type), n); } - + public static final Predicate hasLessCounter(final CounterType type, final int n) { return new Predicate() { @Override @@ -479,6 +479,16 @@ public final class CardPredicates { }; } + public static final Predicate phasedIn() { + return new Predicate() { + @Override + public boolean apply(final Card c) + { + return !c.isPhasedOut(); + } + }; + } + public static class Presets { /** @@ -497,7 +507,7 @@ public final class CardPredicates { return c.isFaceDown(); } }; - + /** * a Predicate to get all cards that are untapped. */ 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 9523f64478c..458a041387b 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -3426,11 +3426,7 @@ public class Player extends GameEntity implements Comparable { } public final boolean isCursed() { - if (this.attachedCards == null) { - return false; - } - - return CardLists.count(attachedCards, CardPredicates.Presets.CURSE) > 0; + return CardLists.count(getAttachedCards(), CardPredicates.Presets.CURSE) > 0; } public boolean canDiscardBy(SpellAbility sa) { diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 8b4dce81525..97630cbc157 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -14,6 +14,7 @@ public enum TrackableProperty { Text(TrackableTypes.StringType), PreventNextDamage(TrackableTypes.IntegerType), AttachedCards(TrackableTypes.CardViewCollectionType), + AllAttachedCards(TrackableTypes.CardViewCollectionType), Counters(TrackableTypes.CounterMapType), CurrentPlane(TrackableTypes.StringType), PlanarPlayer(TrackableTypes.PlayerViewType), 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 b0312ce053c..dbb6fb7ef22 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 @@ -688,8 +688,8 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } toPanel.getAttachedPanels().clear(); - if (card.hasCardAttachments()) { - final Iterable enchants = card.getAttachedCards(); + if (card.hasAnyCardAttachments()) { + final Iterable enchants = card.getAllAttachedCards(); for (final CardView e : enchants) { final CardPanel cardE = getCardPanel(e.getId()); if (cardE != null) { diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index 50dd63362e9..53797b22aff 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -286,8 +286,8 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH attachedPanels.clear(); - if (card.hasCardAttachments()) { - final Iterable enchants = card.getAttachedCards(); + if (card.hasAnyCardAttachments()) { + final Iterable enchants = card.getAllAttachedCards(); for (final CardView e : enchants) { final CardAreaPanel cardE = CardAreaPanel.get(e); if (cardE != null) {