() {
- @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());
}