diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index c776932e798..68bf94ac97f 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -1507,7 +1507,7 @@ public class AiAttackController { } if (sa.usesTargeting()) { sa.setActivatingPlayer(c.getController(), true); - List validTargets = CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa); + List validTargets = CardUtil.getValidCardsToTarget(sa); if (validTargets.isEmpty()) { missTarget = true; break; diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 1806bcf7146..bfb9f737cea 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -644,7 +644,6 @@ public class AiController { public SpellAbility predictSpellToCastInMain2(ApiType exceptSA) { return predictSpellToCastInMain2(exceptSA, true); } - private SpellAbility predictSpellToCastInMain2(ApiType exceptSA, boolean handOnly) { if (!getBooleanProperty(AiProps.PREDICT_SPELLS_FOR_MAIN2)) { return null; @@ -684,15 +683,12 @@ public class AiController { public boolean reserveManaSourcesForNextSpell(SpellAbility sa, SpellAbility exceptForSa) { return reserveManaSources(sa, null, false, true, exceptForSa); } - public boolean reserveManaSources(SpellAbility sa) { return reserveManaSources(sa, PhaseType.MAIN2, false, false, null); } - public boolean reserveManaSources(SpellAbility sa, PhaseType phaseType, boolean enemy) { return reserveManaSources(sa, phaseType, enemy, true, null); } - public boolean reserveManaSources(SpellAbility sa, PhaseType phaseType, boolean enemy, boolean forNextSpell, SpellAbility exceptForThisSa) { ManaCostBeingPaid cost = ComputerUtilMana.calculateManaCost(sa, true, 0); CardCollection manaSources = ComputerUtilMana.getManaSourcesToPayCost(cost, sa, player); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index 9e3beeafe72..1813d70e50b 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -868,7 +868,7 @@ public class ComputerUtilCost { if (sa.usesTargeting()) { // if announce is used as min targets, check what the max possible number would be if ("X".equals(sa.getTargetRestrictions().getMinTargets())) { - val = ObjectUtils.min(val, CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa).size()); + val = ObjectUtils.min(val, CardUtil.getValidCardsToTarget(sa).size()); } if (sa.hasParam("AIMaxTgtsCount")) { diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 1dcf360858e..586801b37cb 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -962,6 +962,7 @@ public class ComputerUtilMana { ManaCostShard toPay, SpellAbility saPayment) { AbilityManaPart m = saPayment.getManaPart(); if (m.isComboMana()) { + m.setExpressChoice(ColorSet.fromMask(toPay.getColorMask())); getComboManaChoice(ai, saPayment, sa, cost); } else if (saPayment.getApi() == ApiType.ManaReflected) { diff --git a/forge-ai/src/main/java/forge/ai/SpecialAiLogic.java b/forge-ai/src/main/java/forge/ai/SpecialAiLogic.java index bdd640e4145..8082e20aaae 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialAiLogic.java +++ b/forge-ai/src/main/java/forge/ai/SpecialAiLogic.java @@ -46,7 +46,7 @@ public class SpecialAiLogic { return false; } - List targetable = CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa); + List targetable = CardUtil.getValidCardsToTarget(sa); CardCollection listOpp = CardLists.filterControlledBy(targetable, ai.getOpponents()); if (isDestroy) { diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index 66a5ddee8ae..87c163f181c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -228,7 +228,7 @@ public class AnimateAi extends SpellAbilityAi { } else if (sa.usesTargeting() && mandatory) { // fallback if animate is mandatory sa.resetTargets(); - List list = CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa); + List list = CardUtil.getValidCardsToTarget(sa); if (list.isEmpty()) { return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java index d842ce39305..a044b3606fe 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AttachAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AttachAi.java @@ -123,8 +123,7 @@ public class AttachAi extends SpellAbilityAi { if (ComputerUtilAbility.getAbilitySourceName(sa).equals("Chained to the Rocks")) { final SpellAbility effectExile = AbilityFactory.getAbility(source.getSVar("TrigExile"), source); effectExile.setActivatingPlayer(ai, true); - final TargetRestrictions exile_tgt = effectExile.getTargetRestrictions(); - final List targets = CardUtil.getValidCardsToTarget(exile_tgt, effectExile); + final List targets = CardUtil.getValidCardsToTarget(effectExile); return !targets.isEmpty(); } @@ -1328,11 +1327,9 @@ public class AttachAi extends SpellAbilityAi { return null; } - final TargetRestrictions tgt = sa.getTargetRestrictions(); - // Is a SA that moves target attachment if ("MoveTgtAura".equals(sa.getParam("AILogic"))) { - CardCollection list = CardLists.filter(CardUtil.getValidCardsToTarget(tgt, sa), Predicates.or(CardPredicates.isControlledByAnyOf(aiPlayer.getOpponents()), new Predicate() { + CardCollection list = CardLists.filter(CardUtil.getValidCardsToTarget(sa), Predicates.or(CardPredicates.isControlledByAnyOf(aiPlayer.getOpponents()), new Predicate() { @Override public boolean apply(final Card card) { return ComputerUtilCard.isUselessCreature(aiPlayer, card.getAttachedTo()); @@ -1341,7 +1338,7 @@ public class AttachAi extends SpellAbilityAi { return !list.isEmpty() ? ComputerUtilCard.getBestAI(list) : null; } else if ("Unenchanted".equals(sa.getParam("AILogic"))) { - List list = CardUtil.getValidCardsToTarget(tgt, sa); + List list = CardUtil.getValidCardsToTarget(sa); CardCollection preferred = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card card) { @@ -1358,10 +1355,10 @@ public class AttachAi extends SpellAbilityAi { } List list = null; - if (tgt == null) { - list = AbilityUtils.getDefinedCards(attachSource, sa.getParam("Defined"), sa); + if (sa.usesTargeting()) { + list = CardUtil.getValidCardsToTarget(sa); } else { - list = CardUtil.getValidCardsToTarget(tgt, sa); + list = AbilityUtils.getDefinedCards(attachSource, sa.getParam("Defined"), sa); } if (list.isEmpty()) { diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index d0a945d43a2..e430ae16866 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1432,7 +1432,7 @@ public class ChangeZoneAi extends SpellAbilityAi { final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final TargetRestrictions tgt = sa.getTargetRestrictions(); - List list = CardUtil.getValidCardsToTarget(tgt, sa); + List list = CardUtil.getValidCardsToTarget(sa); if (list.isEmpty()) { return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java index e17c9926259..5d274a154d8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -130,7 +130,7 @@ public class CopyPermanentAi extends SpellAbilityAi { if (sa.usesTargeting()) { sa.resetTargets(); - List list = CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa); + List list = CardUtil.getValidCardsToTarget(sa); //Nothing to target if (list.isEmpty()) { diff --git a/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java b/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java index 448b7d0443e..877f6a6284c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DebuffAi.java @@ -195,7 +195,7 @@ public class DebuffAi extends SpellAbilityAi { */ private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) { final TargetRestrictions tgt = sa.getTargetRestrictions(); - List list = CardUtil.getValidCardsToTarget(tgt, sa); + List list = CardUtil.getValidCardsToTarget(sa); if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) { sa.resetTargets(); diff --git a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java index 5e0b4d704e6..6e9701549ae 100644 --- a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java @@ -215,7 +215,7 @@ public class EffectAi extends SpellAbilityAi { } else if (logic.equals("Fight")) { return FightAi.canFightAi(ai, sa, 0, 0); } else if (logic.equals("Pump")) { - List options = CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa); + List options = CardUtil.getValidCardsToTarget(sa); options = CardLists.filterControlledBy(options, ai); if (sa.getPayCosts().hasTapCost()) { options.remove(sa.getHostCard()); diff --git a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java index 6ef2c03140f..98306dbf385 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java @@ -213,11 +213,10 @@ public class PlayAi extends SpellAbilityAi { private static List getPlayableCards(SpellAbility sa, Player ai) { List cards = null; - final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getHostCard(); - if (tgt != null) { - cards = CardUtil.getValidCardsToTarget(tgt, sa); + if (sa.usesTargeting()) { + cards = CardUtil.getValidCardsToTarget(sa); } else if (!sa.hasParam("Valid")) { cards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); } diff --git a/forge-ai/src/main/java/forge/ai/ability/ProtectAi.java b/forge-ai/src/main/java/forge/ai/ability/ProtectAi.java index 8d21940b918..d7571ff5d3a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ProtectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ProtectAi.java @@ -258,7 +258,7 @@ public class ProtectAi extends SpellAbilityAi { private static boolean protectMandatoryTarget(final Player ai, final SpellAbility sa) { final TargetRestrictions tgt = sa.getTargetRestrictions(); final Card source = sa.getHostCard(); - final List list = CardUtil.getValidCardsToTarget(tgt, sa); + final List list = CardUtil.getValidCardsToTarget(sa); if (list.size() < tgt.getMinTargets(source, sa)) { sa.resetTargets(); diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java index 4f8e4f58f83..bf0ce6ad9d4 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -617,7 +617,7 @@ public class PumpAi extends PumpAiBase { private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa) { final TargetRestrictions tgt = sa.getTargetRestrictions(); - List list = CardUtil.getValidCardsToTarget(tgt, sa); + List list = CardUtil.getValidCardsToTarget(sa); if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) { sa.resetTargets(); diff --git a/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java b/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java index cdba01f3f99..3e8870df354 100644 --- a/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/SetStateAi.java @@ -23,7 +23,6 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.spellability.SpellAbility; -import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; public class SetStateAi extends SpellAbilityAi { @@ -79,11 +78,10 @@ public class SetStateAi extends SpellAbilityAi { } return shouldTransformCard(source, ai, ph) || "Always".equals(logic); } else { - final TargetRestrictions tgt = sa.getTargetRestrictions(); sa.resetTargets(); // select only the ones that can transform - CardCollection list = CardLists.filter(CardUtil.getValidCardsToTarget(tgt, sa), CardPredicates.Presets.CREATURES, new Predicate() { + CardCollection list = CardLists.filter(CardUtil.getValidCardsToTarget(sa), CardPredicates.Presets.CREATURES, new Predicate() { @Override public boolean apply(Card c) { return c.canTransform(sa); @@ -106,17 +104,10 @@ public class SetStateAi extends SpellAbilityAi { return sa.isMinTargetChosen(); } } else if ("TurnFace".equals(mode)) { - if (!sa.usesTargeting()) { - CardCollection list = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa); - if (list.isEmpty()) { - return false; - } - return shouldTurnFace(list.get(0), ai, ph) || "Always".equals(logic); - } else { - final TargetRestrictions tgt = sa.getTargetRestrictions(); + if (sa.usesTargeting()) { sa.resetTargets(); - List list = CardUtil.getValidCardsToTarget(tgt, sa); + List list = CardUtil.getValidCardsToTarget(sa); if (list.isEmpty()) { return false; @@ -132,6 +123,12 @@ public class SetStateAi extends SpellAbilityAi { } return sa.isTargetNumberValid(); + } else { + CardCollection list = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa); + if (list.isEmpty()) { + return false; + } + return shouldTurnFace(list.get(0), ai, ph) || "Always".equals(logic); } } return true; diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index c7b99479eb8..97d82a2f379 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -544,7 +544,8 @@ public final class CardUtil { // parameters for target selection. // however, due to the changes necessary for SA_Requirements this is much // different than the original - public static List getValidCardsToTarget(TargetRestrictions tgt, SpellAbility ability) { + public static List getValidCardsToTarget(final SpellAbility ability) { + final TargetRestrictions tgt = ability.getTargetRestrictions(); final Card activatingCard = ability.getHostCard(); final Game game = ability.getActivatingPlayer().getGame(); final List zone = tgt.getZone(); diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 0da2ddaa556..3690df4b2ed 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -460,7 +460,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (ability.usesTargeting()) { // if announce is used as min targets, check what the max possible number would be if (announce.equals(ability.getTargetRestrictions().getMinTargets())) { - max = Math.min(max, CardUtil.getValidCardsToTarget(ability.getTargetRestrictions(), ability).size()); + max = Math.min(max, CardUtil.getValidCardsToTarget(ability).size()); } } if (min > max) { diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index 077fab6a8dc..721a26b2c2e 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -140,7 +140,7 @@ public class TargetSelection { return ability.getTargets().addAll(choices); } - List validTargets = CardUtil.getValidCardsToTarget(tgt, ability); + List validTargets = CardUtil.getValidCardsToTarget(ability); boolean mustTargetFiltered = false; if (canFilterMustTarget) { mustTargetFiltered = StaticAbilityMustTarget.filterMustTargetCards(controller.getPlayer(), validTargets, ability);