diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 181c5136972..c4a1a0de786 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -22,9 +22,6 @@ import java.util.*; import org.apache.commons.lang.StringUtils; import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - import forge.Card; import forge.CardCharacteristicName; import forge.CardLists; @@ -67,7 +64,6 @@ import forge.game.ai.ComputerUtilCost; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.Player; -import forge.game.zone.PlayerZone; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; @@ -777,102 +773,6 @@ public class CardFactoryUtil { return true; } - /** - *

- * getExternalZoneActivationCards. - *

- * - * @param activator - * a {@link forge.game.player.Player} object. - * @return a {@link forge.CardList} object. - */ - public static List getExternalZoneActivationCards(final Player activator) { - final List cl = new ArrayList(); - - cl.addAll(getActivateablesFromZone(activator.getZone(ZoneType.Graveyard), activator)); - cl.addAll(getActivateablesFromZone(activator.getZone(ZoneType.Exile), activator)); - cl.addAll(getActivateablesFromZone(activator.getZone(ZoneType.Library), activator)); - cl.addAll(getActivateablesFromZone(activator.getZone(ZoneType.Command), activator)); - - //External activatables from all opponents - for (final Player opponent : activator.getOpponents()) { - cl.addAll(getActivateablesFromZone(opponent.getZone(ZoneType.Exile), activator)); - cl.addAll(getActivateablesFromZone(opponent.getZone(ZoneType.Graveyard), activator)); - cl.addAll(getActivateablesFromZone(opponent.getZone(ZoneType.Library), activator)); - if (opponent.hasKeyword("Play with your hand revealed.")) { - cl.addAll(getActivateablesFromZone(opponent.getZone(ZoneType.Hand), activator)); - } - } - - return cl; - } - - /** - *

- * getActivateablesFromZone. - *

- * - * @param zone - * a PlayerZone object. - * @param activator - * a {@link forge.game.player.Player} object. - * @return a boolean. - */ - public static List getActivateablesFromZone(final PlayerZone zone, final Player activator) { - - Iterable cl = zone.getCards(); // copy to new AL won't help here - - // Only check the top card of the library - if (zone.is(ZoneType.Library)) { - cl = Iterables.limit(cl, 1); - } - - if (activator.equals(zone.getPlayer())) { - cl = Iterables.filter(cl, new Predicate() { - @Override - public boolean apply(final Card c) { - if (c.hasKeyword("You may look at this card.")) { - return true; - } - - if (c.isLand() - && (c.hasKeyword("May be played") || c.hasKeyword("May be played without paying its mana cost"))) { - return true; - } - - for (final SpellAbility sa : c.getSpellAbilities()) { - final ZoneType restrictZone = sa.getRestrictions().getZone(); - if (zone.is(restrictZone)) { - return true; - } - - if (sa.isSpell() - && (c.hasKeyword("May be played") || c.hasKeyword("May be played without paying its mana cost") - || (c.hasStartOfKeyword("Flashback") && zone.is(ZoneType.Graveyard))) - && restrictZone.equals(ZoneType.Hand)) { - return true; - } - } - return false; - } - }); - } else { - // the activator is not the owner of the card - cl = Iterables.filter(cl, new Predicate() { - @Override - public boolean apply(final Card c) { - - if (c.hasStartOfKeyword("May be played by your opponent") - || c.hasKeyword("Your opponent may look at this card.")) { - return true; - } - return false; - } - }); - } - return Lists.newArrayList(cl); - } - /** *

* countOccurrences. diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 308782338d7..0f0f9d9ab80 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -41,7 +41,6 @@ import forge.card.MagicColor; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.effects.CharmEffect; -import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.cost.CostDiscard; import forge.card.cost.CostPart; @@ -1205,7 +1204,7 @@ public class ComputerUtil { } } - all.addAll(CardFactoryUtil.getExternalZoneActivationCards(ai)); + all.addAll(ai.getCardsActivableInExternalZones()); all.addAll(ai.getCardsIn(ZoneType.Hand)); for (final Card c : all) { @@ -1226,7 +1225,7 @@ public class ComputerUtil { public static int possibleNonCombatDamage(Player ai) { int damage = 0; final List all = new ArrayList(ai.getCardsIn(ZoneType.Battlefield)); - all.addAll(CardFactoryUtil.getExternalZoneActivationCards(ai)); + all.addAll(ai.getCardsActivableInExternalZones()); all.addAll(ai.getCardsIn(ZoneType.Hand)); for (final Card c : all) { diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index c0da7539fa4..b33f1ce0b35 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -1536,6 +1536,28 @@ public class Player extends GameEntity implements Comparable { return CardLists.filter(this.getCardsIn(zone), CardPredicates.nameEquals(cardName)); } + + public List getCardsActivableInExternalZones() { + final List cl = new ArrayList(); + + cl.addAll(this.getZone(ZoneType.Graveyard).getCardsPlayerCanActivate(this)); + cl.addAll(this.getZone(ZoneType.Exile).getCardsPlayerCanActivate(this)); + cl.addAll(this.getZone(ZoneType.Library).getCardsPlayerCanActivate(this)); + cl.addAll(this.getZone(ZoneType.Command).getCardsPlayerCanActivate(this)); + + //External activatables from all opponents + for (final Player opponent : this.getOpponents()) { + cl.addAll(opponent.getZone(ZoneType.Exile).getCardsPlayerCanActivate(this)); + cl.addAll(opponent.getZone(ZoneType.Graveyard).getCardsPlayerCanActivate(this)); + cl.addAll(opponent.getZone(ZoneType.Library).getCardsPlayerCanActivate(this)); + if (opponent.hasKeyword("Play with your hand revealed.")) { + cl.addAll(opponent.getZone(ZoneType.Hand).getCardsPlayerCanActivate(this)); + } + } + + return cl; + } + /** * Gets the all cards. * diff --git a/src/main/java/forge/game/zone/PlayerZone.java b/src/main/java/forge/game/zone/PlayerZone.java index 7d916b53ba0..4795cb5cac2 100644 --- a/src/main/java/forge/game/zone/PlayerZone.java +++ b/src/main/java/forge/game/zone/PlayerZone.java @@ -17,7 +17,14 @@ */ package forge.game.zone; +import java.util.List; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + import forge.Card; +import forge.card.spellability.SpellAbility; import forge.game.player.Player; /** @@ -29,6 +36,48 @@ import forge.game.player.Player; * @version $Id$ */ public class PlayerZone extends Zone { + + // the this is not the owner of the card + private final class AlienCardsActivationFilter implements Predicate { + @Override + public boolean apply(final Card c) { + + if (c.hasStartOfKeyword("May be played by your opponent") + || c.hasKeyword("Your opponent may look at this card.")) { + return true; + } + return false; + } + } + + private final class OwnCardsActivationFilter implements Predicate { + @Override + public boolean apply(final Card c) { + if (c.hasKeyword("You may look at this card.")) { + return true; + } + + if (c.isLand() && (c.hasKeyword("May be played") || c.hasKeyword("May be played without paying its mana cost"))) { + return true; + } + + for (final SpellAbility sa : c.getSpellAbilities()) { + final ZoneType restrictZone = sa.getRestrictions().getZone(); + if (PlayerZone.this.is(restrictZone)) { + return true; + } + + if (sa.isSpell() + && (c.hasKeyword("May be played") || c.hasKeyword("May be played without paying its mana cost") + || (c.hasStartOfKeyword("Flashback") && PlayerZone.this.is(ZoneType.Graveyard))) + && restrictZone.equals(ZoneType.Hand)) { + return true; + } + } + return false; + } + } + /** Constant serialVersionUID=-5687652485777639176L. */ private static final long serialVersionUID = -5687652485777639176L; @@ -143,5 +192,23 @@ public class PlayerZone extends Zone { getPlayer().updateLabelObservers(); } + public List getCardsPlayerCanActivate(Player who) { + + Iterable cl = roCardList; // copy to new AL won't help here + + // Only check the top card of the library + if (is(ZoneType.Library)) { + cl = Iterables.limit(cl, 1); + } + + boolean checkingForOwner = who == this.player; + + if (checkingForOwner && (this.is(ZoneType.Battlefield) || this.is(ZoneType.Hand))) + return roCardList; + + final Predicate filterPredicate = checkingForOwner ? new OwnCardsActivationFilter() : new AlienCardsActivationFilter(); + return Lists.newArrayList(cl = Iterables.filter(cl, filterPredicate)); + } + } diff --git a/src/main/java/forge/gui/match/nonsingleton/CField.java b/src/main/java/forge/gui/match/nonsingleton/CField.java index 6b6253b7624..0931150aa5b 100644 --- a/src/main/java/forge/gui/match/nonsingleton/CField.java +++ b/src/main/java/forge/gui/match/nonsingleton/CField.java @@ -33,7 +33,6 @@ import forge.Command; import forge.FThreads; import forge.Singletons; import forge.Constant.Preferences; -import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; import forge.game.Game; import forge.game.player.HumanPlay; @@ -141,7 +140,7 @@ public class CField implements ICDoc { flashBackAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANFLASHBACK) { @Override protected List getCardsAsIterable() { - return CardFactoryUtil.getExternalZoneActivationCards(player); + return player.getCardsActivableInExternalZones(); } @Override diff --git a/src/main/java/forge/gui/match/nonsingleton/VField.java b/src/main/java/forge/gui/match/nonsingleton/VField.java index 45c673aaf96..c98b5695f1f 100644 --- a/src/main/java/forge/gui/match/nonsingleton/VField.java +++ b/src/main/java/forge/gui/match/nonsingleton/VField.java @@ -36,7 +36,6 @@ import org.apache.commons.lang3.tuple.Pair; import net.miginfocom.swing.MigLayout; import forge.card.MagicColor; -import forge.card.cardfactory.CardFactoryUtil; import forge.card.mana.ManaPool; import forge.game.player.LobbyPlayer; import forge.game.player.Player; @@ -285,7 +284,7 @@ public class VField implements IVDoc { this.getLblHand().setToolTipText("Cards in hand (max: " + handMaxToolTip + ")"); this.getLblGraveyard().setText("" + p0.getZone(ZoneType.Graveyard).size()); this.getLblLibrary().setText("" + p0.getZone(ZoneType.Library).size()); - this.getLblFlashback().setText("" + CardFactoryUtil.getExternalZoneActivationCards(p0).size()); + this.getLblFlashback().setText("" + p0.getCardsActivableInExternalZones().size()); this.getLblExile().setText("" + p0.getZone(ZoneType.Exile).size()); }