Large Commit: Passing in SpellAbilities into isValid/hasProperty to fix Harness the Storm not being possible otherwise.

Fixes a bunch of javadoc errors
This commit is contained in:
Sol
2016-04-20 17:47:28 +00:00
parent 3785488317
commit 87c7e8bbdd
129 changed files with 408 additions and 470 deletions

View File

@@ -375,7 +375,7 @@ public class AiController {
public boolean apply(final Card c) {
if (!c.getSVar("NeedsToPlay").isEmpty()) {
final String needsToPlay = c.getSVar("NeedsToPlay");
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), needsToPlay.split(","), c.getController(), c);
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), needsToPlay.split(","), c.getController(), c, null);
if (list.isEmpty()) {
return false;
}
@@ -697,7 +697,7 @@ public class AiController {
SpellAbility effectExile = AbilityFactory.getAbility(card.getSVar("TrigExile"), card);
final ZoneType origin = ZoneType.listValueOf(effectExile.getParam("Origin")).get(0);
final TargetRestrictions tgt = effectExile.getTargetRestrictions();
final CardCollection list = CardLists.getValidCards(game.getCardsIn(origin), tgt.getValidTgts(), player, card);
final CardCollection list = CardLists.getValidCards(game.getCardsIn(origin), tgt.getValidTgts(), player, card, effectExile);
CardCollection targets = CardLists.getTargetableCards(list, sa);
if (sa.getHostCard().getName().equals("Suspension Field")) {
//existing "exile until leaves" enchantments only target opponent's permanents
@@ -794,7 +794,7 @@ public class AiController {
final String needsToPlay = card.getSVar("NeedsToPlay");
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card);
list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card, null);
if (list.isEmpty()) {
return AiPlayDecision.MissingNeededCards;
}
@@ -917,7 +917,7 @@ public class AiController {
public CardCollection getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand));
if ((uTypes != null) && (sa != null)) {
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getHostCard());
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getHostCard(), sa);
}
return getCardsToDiscard(numDiscard, numDiscard, hand, sa);
}
@@ -1356,7 +1356,6 @@ public class AiController {
* Ai should run.
*
* @param sa the sa
* @param ai
* @return true, if successful
*/
public final boolean aiShouldRun(final ReplacementEffect effect, final SpellAbility sa) {

View File

@@ -173,7 +173,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
List<SpellAbility> chosen = new ArrayList<SpellAbility>();
for (SpellAbilityStackInstance si :source.getGame().getStack()) {
SpellAbility sp = si.getSpellAbility(true).getRootAbility();
if (si.getSourceCard().isValid(cost.getType().split(";"), source.getController(), source)) {
if (si.getSourceCard().isValid(cost.getType().split(";"), source.getController(), source, sp)) {
chosen.add(sp);
}
}
@@ -189,7 +189,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
}
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Exile), cost.getType().split(";"), player, source);
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Exile), cost.getType().split(";"), player, source, ability);
if (typeList.size() < c) {
return null;
@@ -230,7 +230,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
}
final CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, source);
final CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, source, ability);
if (typeList.size() < c) {
return null;
@@ -329,7 +329,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
}
list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
list = CardLists.getValidCards(list, cost.getType().split(";"), player, source, ability);
if (cost.isSameZone()) {
// Jotun Grunt
@@ -356,7 +356,8 @@ public class AiCostDecision extends CostDecisionMakerBase {
return PaymentDecision.card(source);
}
final CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, source);
final CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield),
cost.getType().split(";"), player, source, ability);
Card card;
if (cost.getType().equals("Creature.YouCtrl")) {
@@ -382,7 +383,8 @@ public class AiCostDecision extends CostDecisionMakerBase {
final String sVar = ability.getSVar(amount);
if (sVar.equals("XChoice")) {
CardCollectionView typeList =
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getHostCard());
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"),
ability.getActivatingPlayer(), ability.getHostCard(), ability);
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
c = typeList.size();
source.setSVar("ChosenX", "Number$" + Integer.toString(c));
@@ -467,7 +469,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
return null;
}
hand = CardLists.getValidCards(hand, type.split(";"), player, source);
hand = CardLists.getValidCards(hand, type.split(";"), player, source, ability);
Integer c = cost.convertAmount();
if (c == null) {
final String sVar = ability.getSVar(cost.getAmount());
@@ -488,7 +490,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
final int c = AbilityUtils.calculateAmount(source, amount, ability);
final String type = cost.getType();
CardCollectionView typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, source);
CardCollectionView typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, source, ability);
CardCollectionView hperms = CardLists.filter(typeList, new Predicate<Card>() {
@Override
public boolean apply(final Card crd) {
@@ -539,7 +541,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
if (type.equals("OriginalHost")) {
typeList = new CardCollection(ability.getOriginalHost());
} else {
typeList = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
typeList = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source, ability);
}
for (Card card : typeList) {
if (card.getCounters(cost.counter) >= c) {
@@ -564,7 +566,8 @@ public class AiCostDecision extends CostDecisionMakerBase {
if (c == null) {
final String sVar = ability.getSVar(amount);
if (sVar.equals("XChoice")) {
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, ability.getHostCard());
CardCollection typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield),
cost.getType().split(";"), player, ability.getHostCard(), ability);
if (!cost.canUntapSource) {
typeList.remove(source);
}

View File

@@ -278,7 +278,7 @@ public class ComputerUtil {
if (activate != null) {
final String[] prefValid = activate.getSVar("AIPreference").split("\\$");
if (prefValid[0].equals(pref)) {
final CardCollection prefList = CardLists.getValidCards(typeList, prefValid[1].split(","), activate.getController(), activate);
final CardCollection prefList = CardLists.getValidCards(typeList, prefValid[1].split(","), activate.getController(), activate, null);
if (prefList.size() != 0) {
CardLists.shuffle(prefList);
return prefList.get(0);
@@ -371,7 +371,7 @@ public class ComputerUtil {
}
public static CardCollection chooseSacrificeType(final Player ai, final String type, final Card source, final Card target, final int amount) {
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source);
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, null);
if (ai.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) {
typeList = CardLists.getNotType(typeList, "Creature");
}
@@ -404,7 +404,7 @@ public class ComputerUtil {
public static CardCollection chooseExileFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
final Card target, final int amount) {
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate);
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, null);
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
typeList.remove(target); // don't exile the card we're pumping
@@ -425,7 +425,7 @@ public class ComputerUtil {
public static CardCollection choosePutToLibraryFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
final Card target, final int amount) {
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate);
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, null);
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
typeList.remove(target); // don't move the card we're pumping
@@ -450,7 +450,7 @@ public class ComputerUtil {
public static CardCollection chooseTapType(final Player ai, final String type, final Card activate, final boolean tap, final int amount) {
CardCollection typeList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate);
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, null);
// is this needed?
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
@@ -475,7 +475,7 @@ public class ComputerUtil {
public static CardCollection chooseUntapType(final Player ai, final String type, final Card activate, final boolean untap, final int amount) {
CardCollection typeList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate);
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, null);
// is this needed?
typeList = CardLists.filter(typeList, Presets.TAPPED);
@@ -500,7 +500,7 @@ public class ComputerUtil {
public static CardCollection chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) {
final CardCollection typeList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate);
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, null);
if ((target != null) && target.getController() == ai && typeList.contains(target)) {
// don't bounce the card we're pumping
typeList.remove(target);
@@ -661,7 +661,7 @@ public class ComputerUtil {
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard()).contains(card)) {
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard(), sa).contains(card)) {
return true;
}
} else if (AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa).contains(card)) {
@@ -699,7 +699,7 @@ public class ComputerUtil {
}
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard()).contains(card)) {
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard(), null).contains(card)) {
prevented += AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa);
}
@@ -768,7 +768,7 @@ public class ComputerUtil {
if (buffedcard.hasSVar("BuffedBy")) {
final String buffedby = buffedcard.getSVar("BuffedBy");
final String[] bffdby = buffedby.split(",");
if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) {
if (card.isValid(bffdby, buffedcard.getController(), buffedcard, sa)) {
return true;
}
}
@@ -797,7 +797,7 @@ public class ComputerUtil {
if (buffedcard.hasSVar("AntiBuffedBy")) {
final String buffedby = buffedcard.getSVar("AntiBuffedBy");
final String[] bffdby = buffedby.split(",");
if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) {
if (card.isValid(bffdby, buffedcard.getController(), buffedcard, sa)) {
return true;
}
}
@@ -884,7 +884,7 @@ public class ComputerUtil {
// not castable for at least one other turn.
return true;
} else if (landsInPlay.size() > 5 && discard.getCMC() <= 1
&& !discard.hasProperty("hasXCost", ai, null)) {
&& !discard.hasProperty("hasXCost", ai, null, null)) {
// Probably don't need small stuff now.
return true;
}
@@ -929,7 +929,7 @@ public class ComputerUtil {
if (buffedCard.hasSVar("BuffedBy")) {
final String buffedby = buffedCard.getSVar("BuffedBy");
final String[] bffdby = buffedby.split(",");
if (source.isValid(bffdby, buffedCard.getController(), buffedCard)) {
if (source.isValid(bffdby, buffedCard.getController(), buffedCard, sa)) {
return true;
}
}
@@ -949,7 +949,7 @@ public class ComputerUtil {
if (buffedcard.hasSVar("AntiBuffedBy")) {
final String buffedby = buffedcard.getSVar("AntiBuffedBy");
final String[] bffdby = buffedby.split(",");
if (source.isValid(bffdby, buffedcard.getController(), buffedcard)) {
if (source.isValid(bffdby, buffedcard.getController(), buffedcard, sa)) {
return true;
}
}
@@ -1008,7 +1008,7 @@ public class ComputerUtil {
}
final CardCollection typeList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source);
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source, sa);
for (Card c : typeList) {
if (c.getSVar("SacMe").equals("6")) {
return true;
@@ -1150,7 +1150,7 @@ public class ComputerUtil {
objects = AbilityUtils.getDefinedObjects(source, topStack.getParam("Defined"), topStack);
} else if (topStack.hasParam("ValidCards")) {
CardCollectionView battleField = aiPlayer.getCardsIn(ZoneType.Battlefield);
objects = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source);
objects = CardLists.getValidCards(battleField, topStack.getParam("ValidCards").split(","), source.getController(), source, topStack);
} else {
return threatened;
}
@@ -1797,13 +1797,13 @@ public class ComputerUtil {
continue;
}
if (trigParams.containsKey("ValidCard")) {
if (!card.isValid(trigParams.get("ValidCard"), source.getController(), source)) {
if (!card.isValid(trigParams.get("ValidCard"), source.getController(), source, sa)) {
continue;
}
}
if (trigParams.containsKey("ValidActivatingPlayer")) {
if (!player.isValid(trigParams.get("ValidActivatingPlayer"), source.getController(), source)) {
if (!player.isValid(trigParams.get("ValidActivatingPlayer"), source.getController(), source, sa)) {
continue;
}
}
@@ -1869,7 +1869,7 @@ public class ComputerUtil {
continue;
}
if (trigParams.containsKey("ValidCard")) {
if (!permanent.isValid(trigParams.get("ValidCard"), source.getController(), source)) {
if (!permanent.isValid(trigParams.get("ValidCard"), source.getController(), source, null)) {
continue;
}
}

View File

@@ -73,7 +73,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
*/
public static void sortByEvaluateCreature(final CardCollection list) {
Collections.sort(list, ComputerUtilCard.EvaluateCreatureComparator);
@@ -86,7 +85,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getBestArtifactAI(final List<Card> list) {
@@ -119,7 +117,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @param spell
* a {@link forge.game.card.Card} object.
* @param targeted
@@ -148,7 +145,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getBestLandAI(final Iterable<Card> list) {
@@ -199,8 +195,7 @@ public class ComputerUtilCard {
* getCheapestPermanentAI.
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @param all
* @param spell
* a {@link forge.game.card.Card} object.
* @param targeted
@@ -240,7 +235,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getBestAI(final Iterable<Card> list) {
@@ -274,7 +268,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getWorstCreatureAI(final Iterable<Card> list) {
@@ -288,7 +281,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getBestCreatureToBounceAI(final CardCollectionView list) {
@@ -314,7 +306,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getWorstAI(final Iterable<Card> list) {
@@ -327,7 +318,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @param biasEnch
* a boolean.
* @param biasLand
@@ -586,7 +576,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link java.lang.String} object.
*/
public static String getMostProminentCreatureType(final CardCollectionView list) {
@@ -630,7 +619,6 @@ public class ComputerUtilCard {
* </p>
*
* @param list
* a {@link forge.CardList} object.
* @return a {@link java.lang.String} object.
*/
public static String getMostProminentColor(final Iterable<Card> list) {
@@ -690,7 +678,6 @@ public class ComputerUtilCard {
* </p>
*
* @param lands
* a {@link forge.CardList} object.
* @return a {@link forge.game.card.Card} object.
*/
public static Card getWorstLand(final List<Card> lands) {
@@ -1310,7 +1297,7 @@ public class ComputerUtilCard {
continue;
}
final String valid = params.get("Affected");
if (!vCard.isValid(valid, c.getController(), c)) {
if (!vCard.isValid(valid, c.getController(), c, null)) {
continue;
}
if (params.containsKey("AddPower")) {
@@ -1359,7 +1346,7 @@ public class ComputerUtilCard {
return false;
}
CardCollection targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard());
CardCollection targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
targetables = CardLists.getTargetableCards(targetables, sa);
targetables = ComputerUtil.getSafeTargets(ai, sa, targetables);
for (final Card c : targetables) {

View File

@@ -69,8 +69,6 @@ public class ComputerUtilCombat {
*
* @param attacker
* a {@link forge.game.card.Card} object.
* @param def
* the defending {@link GameEntity}.
* @return a boolean.
*/
public static boolean canAttackNextTurn(final Card attacker) {
@@ -89,7 +87,7 @@ public class ComputerUtilCombat {
*
* @param atacker
* a {@link forge.game.card.Card} object.
* @param def
* @param defender
* the defending {@link GameEntity}.
* @return a boolean.
*/
@@ -206,8 +204,6 @@ public class ComputerUtilCombat {
* a {@link forge.game.card.Card} object.
* @param attacked
* a {@link forge.game.player.Player} object.
* @param combat
* a {@link forge.game.combat.Combat} object.
* @return a int.
*/
public static int poisonIfUnblocked(final Card attacker, final Player attacked) {
@@ -233,7 +229,6 @@ public class ComputerUtilCombat {
* </p>
*
* @param attackers
* a {@link forge.CardList} object.
* @param attacked
* a {@link forge.game.player.Player} object.
* @return a int.
@@ -253,7 +248,6 @@ public class ComputerUtilCombat {
* </p>
*
* @param attackers
* a {@link forge.CardList} object.
* @param attacked
* a {@link forge.game.player.Player} object.
* @return a int.
@@ -474,7 +468,6 @@ public class ComputerUtilCombat {
* @param attacker
* a {@link forge.game.card.Card} object.
* @param defenders
* a {@link forge.CardList} object.
* @return a int.
*/
public static int totalDamageOfBlockers(final Card attacker, final List<Card> defenders) {
@@ -589,7 +582,6 @@ public class ComputerUtilCombat {
* @param attacker
* a {@link forge.game.card.Card} object.
* @param defenders
* a {@link forge.CardList} object.
* @return a int.
*/
public static int totalShieldDamage(final Card attacker, final List<Card> defenders) {
@@ -612,7 +604,7 @@ public class ComputerUtilCombat {
*
* @param attacker
* a {@link forge.game.card.Card} object.
* @param defender
* @param blocker
* a {@link forge.game.card.Card} object.
* @return a int.
*/
@@ -886,7 +878,7 @@ public class ComputerUtilCombat {
continue;
}
final String valid = params.get("Affected").replace("blocking", "Creature");
if (!blocker.isValid(valid, card.getController(), card)) {
if (!blocker.isValid(valid, card.getController(), card, null)) {
continue;
}
if (params.containsKey("AddPower")) {
@@ -1223,7 +1215,7 @@ public class ComputerUtilCombat {
continue;
}
final String valid = params.get("Affected").replace("attacking", "Creature");
if (!attacker.isValid(valid, card.getController(), card)) {
if (!attacker.isValid(valid, card.getController(), card, null)) {
continue;
}
if (params.containsKey("AddPower")) {
@@ -1267,9 +1259,9 @@ public class ComputerUtilCombat {
list.add(attacker);
}
if (abilityParams.containsKey("ValidCards")) {
if (attacker.isValid(abilityParams.get("ValidCards").split(","), source.getController(), source)
if (attacker.isValid(abilityParams.get("ValidCards").split(","), source.getController(), source, null)
|| attacker.isValid(abilityParams.get("ValidCards").replace("attacking+", "").split(","),
source.getController(), source)) {
source.getController(), source, null)) {
list.add(attacker);
}
}
@@ -1396,7 +1388,7 @@ public class ComputerUtilCombat {
continue;
}
final String valid = params.get("Affected").replace("attacking", "Creature");
if (!attacker.isValid(valid, card.getController(), card)) {
if (!attacker.isValid(valid, card.getController(), card, null)) {
continue;
}
if (params.containsKey("AddToughness")) {
@@ -1459,9 +1451,9 @@ public class ComputerUtilCombat {
list.add(attacker);
}
if (abilityParams.containsKey("ValidCards")) {
if (attacker.isValid(abilityParams.get("ValidCards").split(","), source.getController(), source)
if (attacker.isValid(abilityParams.get("ValidCards").split(","), source.getController(), source, null)
|| attacker.isValid(abilityParams.get("ValidCards").replace("attacking+", "").split(","),
source.getController(), source)) {
source.getController(), source, null)) {
list.add(attacker);
}
}
@@ -1966,7 +1958,6 @@ public class ComputerUtilCombat {
* @param attacker
* a {@link forge.game.card.Card} object.
* @param block
* a {@link forge.CardList} object.
* @param dmgCanDeal
* a int.
* @param defender
@@ -2169,11 +2160,11 @@ public class ComputerUtilCombat {
continue;
}
if (params.containsKey("ValidSource")
&& !source.isValid(params.get("ValidSource"), ca.getController(), ca)) {
&& !source.isValid(params.get("ValidSource"), ca.getController(), ca, null)) {
continue;
}
if (params.containsKey("ValidTarget")
&& !target.isValid(params.get("ValidTarget"), ca.getController(), ca)) {
&& !target.isValid(params.get("ValidTarget"), ca.getController(), ca, null)) {
continue;
}
if (params.containsKey("IsCombat")) {

View File

@@ -108,7 +108,7 @@ public class ComputerUtilCost {
if (type.equals("CARDNAME") && source.getAbilityText().contains("Bloodrush")) {
continue;
}
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Hand), type.split(","), source.getController(), source);
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Hand), type.split(","), source.getController(), source, null);
if (typeList.size() > ai.getMaxHandSize()) {
continue;
}
@@ -217,7 +217,7 @@ public class ComputerUtilCost {
continue;
}
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source);
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source, null);
if (ComputerUtil.getCardPreference(ai, source, "SacCost", typeList) == null) {
return false;
}
@@ -257,7 +257,7 @@ public class ComputerUtilCost {
continue;
}
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source);
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(","), source.getController(), source, null);
if (ComputerUtil.getCardPreference(ai, source, "SacCost", typeList) == null) {
return false;
}
@@ -321,8 +321,7 @@ public class ComputerUtilCost {
*
* @param hostCard
* a {@link forge.game.card.Card} object.
* @param costString
* a {@link java.lang.String} object.
* @param cost
* @return a boolean.
*/
public static boolean shouldPayCost(final Player ai, final Card hostCard, final Cost cost) {
@@ -368,7 +367,7 @@ public class ComputerUtilCost {
final String snem = c.getSVar("AI_SpellsNeedExtraMana");
if (!StringUtils.isBlank(snem)) {
String[] parts = TextUtil.split(snem, ' ');
boolean meetsRestriction = parts.length == 1 || player.isValid(parts[1], c.getController(), c);
boolean meetsRestriction = parts.length == 1 || player.isValid(parts[1], c.getController(), c, sa);
if(!meetsRestriction)
continue;

View File

@@ -76,14 +76,15 @@ public class AnimateAi extends SpellAbilityAi {
num = (num == null) ? "1" : num;
final int nToSac = AbilityUtils.calculateAmount(topStack.getHostCard(), num, topStack);
CardCollection list =
CardLists.getValidCards(aiPlayer.getCardsIn(ZoneType.Battlefield), valid.split(","), aiPlayer.getOpponent(), topStack.getHostCard());
CardLists.getValidCards(aiPlayer.getCardsIn(ZoneType.Battlefield), valid.split(","),
aiPlayer.getOpponent(), topStack.getHostCard(), topStack);
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(topStack));
ComputerUtilCard.sortByEvaluateCreature(list);
if (!list.isEmpty() && list.size() == nToSac && ComputerUtilCost.canPayCost(sa, aiPlayer)) {
Card animatedCopy = CardFactory.copyCard(source, true);
becomeAnimated(animatedCopy, source.hasSickness(), sa);
list.add(animatedCopy);
list = CardLists.getValidCards(list, valid.split(","), aiPlayer.getOpponent(), topStack.getHostCard());
list = CardLists.getValidCards(list, valid.split(","), aiPlayer.getOpponent(), topStack.getHostCard(), topStack);
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(topStack));
if (ComputerUtilCard.evaluateCreature(animatedCopy) < ComputerUtilCard.evaluateCreature(list.get(0))
&& list.contains(animatedCopy)) {
@@ -98,7 +99,7 @@ public class AnimateAi extends SpellAbilityAi {
if (ph.getPlayerTurn().isOpponentOf(aiPlayer) || ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return false;
}
List<Card> list = CardLists.getValidCards(aiPlayer.getCreaturesInPlay(), tgt.getValidTgts(), aiPlayer, source);
List<Card> list = CardLists.getValidCards(aiPlayer.getCreaturesInPlay(), tgt.getValidTgts(), aiPlayer, source, sa);
for (Card c : list) {
if (ComputerUtilCard.doesCreatureAttackAI(aiPlayer, c)) {
sa.getTargets().add(c);
@@ -237,7 +238,7 @@ public class AnimateAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card animateSource = sa.getHostCard();
CardCollectionView list = aiPlayer.getGame().getCardsIn(tgt.getZone());
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), animateSource);
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), animateSource, sa);
CardCollection prefList = CardLists.getValidCards(list, sa.getParam("AITgts"), sa.getActivatingPlayer(), animateSource);
if (!prefList.isEmpty()){
CardLists.shuffle(prefList);

View File

@@ -81,7 +81,7 @@ public class AttachAi extends SpellAbilityAi {
final SpellAbility effectExile = AbilityFactory.getAbility(source.getSVar("TrigExile"), source);
final ZoneType origin = ZoneType.listValueOf(effectExile.getParam("Origin")).get(0);
final TargetRestrictions exile_tgt = effectExile.getTargetRestrictions();
final CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), exile_tgt.getValidTgts(), ai, source);
final CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), exile_tgt.getValidTgts(), ai, source, effectExile);
final CardCollection targets = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
@@ -283,9 +283,7 @@ public class AttachAi extends SpellAbilityAi {
/**
* Attach to player ai preferences.
*
* @param af
* the af
*
* @param sa
* the sa
* @param mandatory
@@ -695,8 +693,6 @@ public class AttachAi extends SpellAbilityAi {
* the sa
* @param mandatory
* the mandatory
* @param af
* the af
*
* @return true, if successful
*/
@@ -766,9 +762,7 @@ public class AttachAi extends SpellAbilityAi {
/**
* Attach preference.
*
* @param af
* the af
*
* @param sa
* the sa
* @param sa
@@ -1051,7 +1045,7 @@ public class AttachAi extends SpellAbilityAi {
if (tgt == null) {
list = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
} else {
list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(tgt.getZone()), tgt.getValidTgts(), sa.getActivatingPlayer(), attachSource);
list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(tgt.getZone()), tgt.getValidTgts(), sa.getActivatingPlayer(), attachSource, sa);
// TODO If Attaching without casting, don't need to actually target.
// I believe this is the only case where mandatory will be true, so just
// check that when starting that work
@@ -1370,7 +1364,7 @@ public class AttachAi extends SpellAbilityAi {
/**
* Checks if it is useful to execute the attach action given the current context.
*
* @param card
* @param c
* the card
* @param sa SpellAbility
* @return true, if the action is useful (beneficial) in the current minimal context (Card vs. Attach SpellAbility)

View File

@@ -28,7 +28,7 @@ public class BecomesBlockedAi extends SpellAbilityAi {
if (tgt != null) {
sa.resetTargets();
CardCollection list = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), aiPlayer.getOpponents());
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
list = CardLists.getNotKeyword(list, "Trample");

View File

@@ -25,7 +25,7 @@ public class BidLifeAi extends SpellAbilityAi {
sa.resetTargets();
if (tgt.canTgtCreature()) {
List<Card> list = CardLists.getTargetableCards(aiPlayer.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
if (list.isEmpty()) {
return false;
}

View File

@@ -42,8 +42,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
* </p>
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @return a boolean.
*/
@@ -81,8 +79,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
* </p>
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @return a boolean.
*/
@@ -109,8 +105,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
* a boolean.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @return a boolean.
*/
@@ -144,9 +138,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeHiddenOriginCanPlayAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @return a boolean.
@@ -349,9 +341,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeHiddenOriginPlayDrawbackAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @return a boolean.
@@ -379,9 +369,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeHiddenTriggerAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -465,7 +453,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* @param ai
*
* @param list
* a {@link forge.CardList} object.
* a List<Card> object.
* @return a {@link forge.game.card.Card} object.
*/
private static Card basicManaFixing(final Player ai, final List<Card> list) { // Search for a Basic Land
@@ -560,9 +548,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeKnownOriginCanPlayAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @return a boolean.
@@ -689,9 +675,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeKnownOriginPlayDrawbackAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @return a boolean.
@@ -708,9 +692,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeKnownPreferredTarget.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -735,7 +717,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
sa.resetTargets();
CardCollection list = CardLists.getValidCards(game.getCardsIn(origin), tgt.getValidTgts(), ai, source);
CardCollection list = CardLists.getValidCards(game.getCardsIn(origin), tgt.getValidTgts(), ai, source, sa);
list = CardLists.getTargetableCards(list, sa);
if (sa.hasParam("AITgts")) {
list = CardLists.getValidCards(list, sa.getParam("AITgts"), ai, source);
@@ -753,7 +735,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
@Override
public boolean apply(final Card c) {
for (Card card : game.getCardsIn(ZoneType.Battlefield)) {
if (card.isValid(sa.getParam("AttachedTo"), ai, c)) {
if (card.isValid(sa.getParam("AttachedTo"), ai, c, sa)) {
return true;
}
}
@@ -1114,7 +1096,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source, sa);
// Narrow down the list:
if (origin.equals(ZoneType.Battlefield)) {
@@ -1203,9 +1185,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
* <p>
* changeKnownOriginTriggerAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory

View File

@@ -74,7 +74,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
if (sa.getParam("AILogic").equals("NeedsPrevention")) {
if (!game.getStack().isEmpty()) {
final SpellAbility topStack = game.getStack().peekAbility();
if (sa.hasParam("Choices") && !topStack.getHostCard().isValid(sa.getParam("Choices"), ai, source)) {
if (sa.hasParam("Choices") && !topStack.getHostCard().isValid(sa.getParam("Choices"), ai, source, sa)) {
return false;
}
final ApiType threatApi = topStack.getApi();
@@ -161,7 +161,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
final Card source = si.getSourceCard();
final SpellAbility abilityOnStack = si.getSpellAbility(true);
if (sa.hasParam("Choices") && !abilityOnStack.getHostCard().isValid(sa.getParam("Choices"), ai, sa.getHostCard())) {
if (sa.hasParam("Choices") && !abilityOnStack.getHostCard().isValid(sa.getParam("Choices"), ai, sa.getHostCard(), sa)) {
continue;
}
final ApiType threatApi = abilityOnStack.getApi();

View File

@@ -31,7 +31,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
sa.resetTargets();
List<Card> list =
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard());
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
// AI won't try to grab cards that are filtered out of AI decks on
// purpose
list = CardLists.filter(list, new Predicate<Card>() {
@@ -46,7 +46,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
object2 = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa).get(0);
} else if (tgt.getMinTargets(sa.getHostCard(), sa) > 1) {
CardCollectionView list2 = ai.getCardsIn(ZoneType.Battlefield);
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getHostCard());
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getHostCard(), sa);
object2 = ComputerUtilCard.getWorstAI(list2);
sa.getTargets().add(object2);
}
@@ -69,7 +69,8 @@ public class ControlExchangeAi extends SpellAbilityAi {
}
} else {
if (mandatory) {
CardCollection list2 = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), aiPlayer, sa.getHostCard());
CardCollection list2 = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(ZoneType.Battlefield),
tgt.getValidTgts(), aiPlayer, sa.getHostCard(), sa);
while (!list2.isEmpty()) {
Card best = ComputerUtilCard.getBestAI(list2);
if (sa.canTarget(best)) {

View File

@@ -119,7 +119,7 @@ public class ControlGainAi extends SpellAbilityAi {
}
CardCollection list =
CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
// AI won't try to grab cards that are filtered out of AI decks on purpose
list = CardLists.filter(list, new Predicate<Card>() {

View File

@@ -57,7 +57,8 @@ public class CopyPermanentAi extends SpellAbilityAi {
if (abTgt != null) {
sa.resetTargets();
CardCollection list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(abTgt.getZone()), abTgt.getValidTgts(), source.getController(), source);
CardCollection list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(abTgt.getZone()),
abTgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
list = CardLists.filter(list, new Predicate<Card>() {
@Override

View File

@@ -48,7 +48,7 @@ public class CounterAi extends SpellAbilityAi {
return false;
}
if (sa.hasParam("AITgts") && (topSA.getHostCard() == null
|| !topSA.getHostCard().isValid(sa.getParam("AITgts"), sa.getActivatingPlayer(), source))) {
|| !topSA.getHostCard().isValid(sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa))) {
return false;
}

View File

@@ -79,12 +79,12 @@ public class CountersMoveAi extends SpellAbilityAi {
} else { // targeted
final Player player = sa.isCurse() ? ai.getOpponent() : ai;
CardCollectionView list = CardLists.getTargetableCards(player.getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), host.getController(), host);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), host.getController(), host, sa);
if (list.isEmpty() && mandatory) {
// If there isn't any prefered cards to target, gotta choose
// non-preferred ones
list = CardLists.getTargetableCards(player.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), host.getController(), host);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), host.getController(), host, sa);
preferred = false;
}
// Not mandatory, or the the list was regenerated and is still

View File

@@ -211,7 +211,7 @@ public class CountersPutAi extends SpellAbilityAi {
}
});
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source, sa);
if (list.size() < abTgt.getMinTargets(source, sa)) {
return false;
@@ -365,7 +365,7 @@ public class CountersPutAi extends SpellAbilityAi {
if (abTgt != null) {
CardCollection list =
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), abTgt.getValidTgts(), source.getController(), source);
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), abTgt.getValidTgts(), source.getController(), source, sa);
if (list.size() == 0) {
return false;
@@ -454,7 +454,7 @@ public class CountersPutAi extends SpellAbilityAi {
}
} else {
list = CardLists.getTargetableCards(player.getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source, sa);
int totalTargets = list.size();
@@ -468,7 +468,7 @@ public class CountersPutAi extends SpellAbilityAi {
if (list.isEmpty() && preferred) {
// If it's required to choose targets and the list is empty, get a new list
list = CardLists.getTargetableCards(player.getOpponent().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source, sa);
preferred = false;
}
}

View File

@@ -51,7 +51,7 @@ public class CountersPutOrRemoveAi extends SpellAbilityAi {
List<ZoneType> zones = ZoneType.listValueOf(sa.getParamOrDefault("TgtZones", "Battlefield"));
List<Card> validCards = CardLists.getValidCards(ai.getGame().getCardsIn(zones),
tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
if (validCards.isEmpty()) {
return false;

View File

@@ -186,7 +186,7 @@ public class DamageAllAi extends SpellAbilityAi {
// TODO: X may be something different than X paid
CardCollection list =
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), validC.split(","), source.getController(), source);
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), validC.split(","), source.getController(), source, sa);
final Predicate<Card> filterKillable = new Predicate<Card>() {
@Override

View File

@@ -167,7 +167,7 @@ public class DamageDealAi extends DamageAiBase {
}
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Card source = sa.getHostCard();
List<Card> hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source);
List<Card> hPlay = CardLists.getValidCards(pl.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, source, sa);
final List<GameObject> objects = Lists.newArrayList(sa.getTargets().getTargets());
if (sa.hasParam("TargetUnique")) {

View File

@@ -102,7 +102,7 @@ public class DamagePreventAi extends SpellAbilityAi {
}
final List<Card> threatenedTargets = new ArrayList<Card>();
// filter AIs battlefield by what I can target
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard);
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
for (final Card c : targetables) {
@@ -129,7 +129,7 @@ public class DamagePreventAi extends SpellAbilityAi {
} else {
// filter AIs battlefield by what I can target
CardCollectionView targetables = ai.getCardsIn(ZoneType.Battlefield);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
if (targetables.isEmpty()) {
@@ -171,9 +171,7 @@ public class DamagePreventAi extends SpellAbilityAi {
* <p>
* preventDamageMandatoryTarget.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -186,7 +184,7 @@ public class DamagePreventAi extends SpellAbilityAi {
// filter AIs battlefield by what I can target
final Game game = ai.getGame();
CardCollectionView targetables = game.getCardsIn(ZoneType.Battlefield);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, sa.getHostCard());
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, sa.getHostCard(), sa);
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, ai);
Card target = null;

View File

@@ -107,9 +107,7 @@ public class DebuffAi extends SpellAbilityAi {
* <p>
* debuffTgtAI.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param kws
@@ -127,7 +125,7 @@ public class DebuffAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
sa.resetTargets();
CardCollection list = getCurseCreatures(ai, sa, kws == null ? Lists.<String>newArrayList() : kws);
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
// several uses here:
// 1. make human creatures lose evasion when they are attacking
@@ -170,14 +168,12 @@ public class DebuffAi extends SpellAbilityAi {
* <p>
* getCurseCreatures.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param kws
* a {@link java.util.ArrayList} object.
* @return a {@link forge.CardList} object.
* @return a CardCollection.
*/
private CardCollection getCurseCreatures(final Player ai, final SpellAbility sa, final List<String> kws) {
final Player opp = ai.getOpponent();
@@ -198,9 +194,7 @@ public class DebuffAi extends SpellAbilityAi {
* <p>
* debuffMandatoryTarget.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -209,7 +203,8 @@ public class DebuffAi extends SpellAbilityAi {
*/
private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(),
sa.getActivatingPlayer(), sa.getHostCard(), sa);
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
sa.resetTargets();

View File

@@ -246,7 +246,7 @@ public class DestroyAi extends SpellAbilityAi {
sa.resetTargets();
CardCollection list = CardLists.getTargetableCards(ai.getGame().getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
if (list.isEmpty() || list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
return false;

View File

@@ -35,8 +35,10 @@ public class DestroyAllAi extends SpellAbilityAi {
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
CardCollection humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardCollection computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardCollection humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield),
valid.split(","), source.getController(), source, sa);
CardCollection computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","),
source.getController(), source, sa);
if (sa.usesTargeting()) {
sa.resetTargets();
@@ -94,8 +96,10 @@ public class DestroyAllAi extends SpellAbilityAi {
valid = valid.replace("X", Integer.toString(xPay));
}
CardCollection humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardCollection computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardCollection humanlist = CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield),
valid.split(","), source.getController(), source, sa);
CardCollection computerlist = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","),
source.getController(), source, sa);
if (sa.usesTargeting()) {
sa.resetTargets();
sa.getTargets().add(ai.getOpponent());

View File

@@ -42,7 +42,7 @@ public class DigUntilAi extends SpellAbilityAi {
} else {
if (sa.hasParam("Valid")) {
final String valid = sa.getParam("Valid");
if (CardLists.getValidCards(ai.getCardsIn(ZoneType.Library), valid.split(","), source.getController(), source).isEmpty()) {
if (CardLists.getValidCards(ai.getCardsIn(ZoneType.Library), valid.split(","), source.getController(), source, sa).isEmpty()) {
return false;
}
}

View File

@@ -74,7 +74,7 @@ public class EffectAi extends SpellAbilityAi {
}
} else {
List<Card> list = game.getCombat().getAttackers();
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
list = CardLists.getTargetableCards(list, sa);
Card target = ComputerUtilCard.getBestCreatureAI(list);
if (target == null) {

View File

@@ -62,7 +62,7 @@ public class MustBlockAi extends SpellAbilityAi {
if (abTgt != null) {
List<Card> list = CardLists.filter(ai.getOpponent().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
list = CardLists.getTargetableCards(list, sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {

View File

@@ -107,7 +107,7 @@ public class PhasesAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source), sa);
list = CardLists.getTargetableCards(CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa), sa);
return false;
}

View File

@@ -63,7 +63,7 @@ public class PlayAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt != null) {
ZoneType zone = tgt.getZone().get(0);
cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source);
cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source, sa);
if (cards.isEmpty()) {
return false;
}
@@ -85,8 +85,6 @@ public class PlayAi extends SpellAbilityAi {
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
* a boolean.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @return a boolean.
*/

View File

@@ -31,7 +31,7 @@ public class PowerExchangeAi extends SpellAbilityAi {
sa.resetTargets();
List<Card> list =
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard());
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
// AI won't try to grab cards that are filtered out of AI decks on
// purpose
list = CardLists.filter(list, new Predicate<Card>() {
@@ -47,7 +47,7 @@ public class PowerExchangeAi extends SpellAbilityAi {
c2 = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa).get(0);
}
else if (tgt.getMinTargets(sa.getHostCard(), sa) > 1) {
CardCollection list2 = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard());
CardCollection list2 = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
CardLists.sortByPowerAsc(list2);
Collections.reverse(list2);
c2 = list2.isEmpty() ? null : list2.get(0);

View File

@@ -99,10 +99,7 @@ public class ProtectAi extends SpellAbilityAi {
* <p>
* getProtectCreatures.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
* @return a {@link forge.CardList} object.
*
*/
public static CardCollection getProtectCreatures(final Player ai, final SpellAbility sa) {
final List<String> gains = ProtectEffect.getProtectionList(sa);
@@ -252,7 +249,7 @@ public class ProtectAi extends SpellAbilityAi {
sa.resetTargets();
CardCollection list = getProtectCreatures(ai, sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
if (game.getStack().isEmpty()) {
// If the cost is tapping, don't activate before declare
@@ -306,7 +303,7 @@ public class ProtectAi extends SpellAbilityAi {
final Game game = ai.getGame();
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
sa.resetTargets();

View File

@@ -240,7 +240,7 @@ public class PumpAi extends PumpAiBase {
CardCollection list;
if (sa.hasParam("AILogic")) {
if (sa.getParam("AILogic").equals("HighestPower")) {
list = CardLists.getValidCards(CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES), tgt.getValidTgts(), ai, source);
list = CardLists.getValidCards(CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES), tgt.getValidTgts(), ai, source, sa);
list = CardLists.getTargetableCards(list, sa);
CardLists.sortByPowerDesc(list);
if (!list.isEmpty()) {
@@ -274,7 +274,7 @@ public class PumpAi extends PumpAiBase {
}
}
list = CardLists.getValidCards(list, tgt.getValidTgts(), ai, source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), ai, source, sa);
if (game.getStack().isEmpty()) {
// If the cost is tapping, don't activate before declare
// attack/block
@@ -359,7 +359,7 @@ public class PumpAi extends PumpAiBase {
final Game game = ai.getGame();
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player opp = ai.getOpponent();
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard(), sa);
list = CardLists.getTargetableCards(list, sa);
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {

View File

@@ -115,7 +115,7 @@ public class RegenerateAi extends SpellAbilityAi {
} else {
sa.resetTargets();
// filter AIs battlefield by what I can target
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard);
List<Card> targetables = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
if (targetables.size() == 0) {
@@ -184,7 +184,7 @@ public class RegenerateAi extends SpellAbilityAi {
sa.resetTargets();
// filter AIs battlefield by what I can target
CardCollectionView targetables = game.getCardsIn(ZoneType.Battlefield);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard);
targetables = CardLists.getValidCards(targetables, tgt.getValidTgts(), ai, hostCard, sa);
targetables = CardLists.getTargetableCards(targetables, sa);
final List<Card> compTargetables = CardLists.filterControlledBy(targetables, ai);

View File

@@ -50,7 +50,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
}
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard);
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);
list = CardLists.filter(list, CardPredicates.isController(ai));
if (list.size() == 0) {

View File

@@ -72,7 +72,7 @@ public class SacrificeAi extends SpellAbilityAi {
final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);
List<Card> list =
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard());
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard(), sa);
for (Card c : list) {
if (c.hasSVar("SacMe") && Integer.parseInt(c.getSVar("SacMe")) > 3) {
return false;
@@ -126,7 +126,7 @@ public class SacrificeAi extends SpellAbilityAi {
}
List<Card> humanList =
CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard());
CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard(), sa);
// Since all of the cards have remAIDeck:True, I enabled 1 for 1
// (or X for X) trades for special decks
@@ -135,7 +135,7 @@ public class SacrificeAi extends SpellAbilityAi {
}
} else if (defined.equals("You")) {
List<Card> computerList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard());
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard(), sa);
for (Card c : computerList) {
if (c.hasSVar("SacMe") || ComputerUtilCard.evaluateCreature(c) <= 135) {
return true;

View File

@@ -38,9 +38,9 @@ public class SacrificeAllAi extends SpellAbilityAi {
}
CardCollection humanlist =
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardLists.getValidCards(ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source, sa);
CardCollection computerlist =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source);
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), source.getController(), source, sa);
if (abCost != null) {
// AI currently disabled for some costs

View File

@@ -29,12 +29,11 @@ public abstract class TapAiBase extends SpellAbilityAi {
* tapTargetList.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param tapList
* a {@link forge.CardList} object.
* a CardCollection object.
* @param mandatory
* a boolean.
* @return a boolean.
@@ -105,8 +104,6 @@ public abstract class TapAiBase extends SpellAbilityAi {
* a {@link forge.game.card.Card} object.
* @param tgt
* a {@link forge.game.spellability.TargetRestrictions} object.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -117,7 +114,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
final Player opp = ai.getOpponent();
final Game game = ai.getGame();
CardCollection tapList = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponents());
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source);
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source, sa);
tapList = CardLists.getTargetableCards(tapList, sa);
tapList = CardLists.filter(tapList, Presets.UNTAPPED);
tapList = CardLists.filter(tapList, new Predicate<Card>() {
@@ -139,7 +136,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
//use broader approach when the cost is a positive thing
if (tapList.isEmpty() && ComputerUtil.activateForCost(sa, ai)) {
tapList = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponents());
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source);
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source, sa);
tapList = CardLists.getTargetableCards(tapList, sa);
tapList = CardLists.filter(tapList, new Predicate<Card>() {
@Override
@@ -252,9 +249,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
* <p>
* tapUnpreferredTargeting.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -266,7 +261,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Game game = ai.getGame();
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), source.getController(), source);
CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
// try to tap anything controlled by the computer
@@ -281,7 +276,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
// filter by enchantments and planeswalkers, their tapped state doesn't matter.
final String[] tappablePermanents = { "Enchantment", "Planeswalker" };
tapList = CardLists.getValidCards(list, tappablePermanents, source.getController(), source);
tapList = CardLists.getValidCards(list, tappablePermanents, source.getController(), source, sa);
if (tapTargetList(ai, sa, tapList, mandatory)) {
return true;

View File

@@ -181,7 +181,7 @@ public class TokenAi extends SpellAbilityAi {
} else {
//Flash Foliage
CardCollection list = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponents());
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
CardCollection betterList = CardLists.filter(list, new Predicate<Card>() {
@Override
@@ -233,14 +233,14 @@ public class TokenAi extends SpellAbilityAi {
num = (num == null) ? "1" : num;
final int nToSac = AbilityUtils.calculateAmount(topStack.getHostCard(), num, topStack);
CardCollection list =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), opp, topStack.getHostCard());
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), opp, topStack.getHostCard(), sa);
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(topStack));
if (!list.isEmpty() && nTokens > 0 && list.size() == nToSac) { //only care about saving single creature for now
ComputerUtilCard.sortByEvaluateCreature(list);
Card token = spawnToken(ai, sa);
if (token != null) {
list.add(token);
list = CardLists.getValidCards(list, valid.split(","), ai.getOpponent(), topStack.getHostCard());
list = CardLists.getValidCards(list, valid.split(","), ai.getOpponent(), topStack.getHostCard(), sa);
list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(topStack));
if (ComputerUtilCard.evaluateCreature(token) < ComputerUtilCard.evaluateCreature(list.get(0))
&& list.contains(token)) {

View File

@@ -109,8 +109,6 @@ public class UntapAi extends SpellAbilityAi {
*
* @param tgt
* a {@link forge.game.spellability.TargetRestrictions} object.
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -127,7 +125,7 @@ public class UntapAi extends SpellAbilityAi {
}
CardCollection list = CardLists.getTargetableCards(targetController.getCardsIn(ZoneType.Battlefield), sa);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source);
list = CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source, sa);
if (list.isEmpty()) {
return false;
@@ -137,7 +135,7 @@ public class UntapAi extends SpellAbilityAi {
// filter out enchantments and planeswalkers, their tapped state doesn't
// matter.
final String[] tappablePermanents = { "Creature", "Land", "Artifact" };
untapList = CardLists.getValidCards(untapList, tappablePermanents, source.getController(), source);
untapList = CardLists.getValidCards(untapList, tappablePermanents, source.getController(), source, sa);
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(sa.getHostCard(), sa)) {
Card choice = null;
@@ -198,9 +196,7 @@ public class UntapAi extends SpellAbilityAi {
* <p>
* untapUnpreferredTargeting.
* </p>
*
* @param af
* a {@link forge.game.ability.AbilityFactory} object.
*
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
* @param mandatory
@@ -211,13 +207,14 @@ public class UntapAi extends SpellAbilityAi {
final Card source = sa.getHostCard();
final TargetRestrictions tgt = sa.getTargetRestrictions();
CardCollection list = CardLists.getValidCards(sa.getActivatingPlayer().getGame().getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), source.getController(), source);
CardCollection list = CardLists.getValidCards(source.getGame().getCardsIn(ZoneType.Battlefield),
tgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.getTargetableCards(list, sa);
// filter by enchantments and planeswalkers, their tapped state doesn't
// matter.
final String[] tappablePermanents = { "Enchantment", "Planeswalker" };
CardCollection tapList = CardLists.getValidCards(list, tappablePermanents, source.getController(), source);
CardCollection tapList = CardLists.getValidCards(list, tappablePermanents, source.getController(), source, sa);
if (untapTargetList(source, tgt, sa, mandatory, tapList)) {
return true;

View File

@@ -27,7 +27,7 @@ public class UntapAllAi extends SpellAbilityAi {
if (sa.hasParam("ValidCards")) {
valid = sa.getParam("ValidCards");
}
list = CardLists.getValidCards(list, valid.split(","), source.getController(), source);
list = CardLists.getValidCards(list, valid.split(","), source.getController(), source, sa);
return !list.isEmpty();
}
return false;