From ecd4a5dedd11ed0281ac07682a9c51bf7026c60d Mon Sep 17 00:00:00 2001 From: Agetian Date: Sun, 4 Feb 2018 20:24:51 +0300 Subject: [PATCH] - Fixed the AI trying to e.g. Embalm a Vizier of Many Faces ignoring the NeedsToPlay SVar requirement. --- .../src/main/java/forge/ai/AiController.java | 38 ++--------------- .../main/java/forge/ai/ComputerUtilCard.java | 41 +++++++++++++++++++ .../forge/ai/ability/CopyPermanentAi.java | 12 ++++-- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 5ead75ec256..21e10ee577e 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -678,43 +678,11 @@ public class AiController { } private AiPlayDecision canPlaySpellBasic(final Card card, final SpellAbility sa) { - boolean isRightSplit = sa != null && sa.isRightSplit(); - String needsToPlayName = isRightSplit ? "SplitNeedsToPlay" : "NeedsToPlay"; - String needsToPlayVarName = isRightSplit ? "SplitNeedsToPlayVar": "NeedsToPlayVar"; + // add any other necessary logic to play a basic spell here - if (card.hasSVar(needsToPlayName)) { - final String needsToPlay = card.getSVar(needsToPlayName); - CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); - - list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card, null); - if (list.isEmpty()) { - return AiPlayDecision.MissingNeededCards; - } - } - if (card.getSVar(needsToPlayVarName).length() > 0) { - final String needsToPlay = card.getSVar(needsToPlayVarName); - int x = 0; - int y = 0; - String sVar = needsToPlay.split(" ")[0]; - String comparator = needsToPlay.split(" ")[1]; - String compareTo = comparator.substring(2); - try { - x = Integer.parseInt(sVar); - } catch (final NumberFormatException e) { - x = CardFactoryUtil.xCount(card, card.getSVar(sVar)); - } - try { - y = Integer.parseInt(compareTo); - } catch (final NumberFormatException e) { - y = CardFactoryUtil.xCount(card, card.getSVar(compareTo)); - } - if (!Expressions.compare(x, comparator, y)) { - return AiPlayDecision.NeedsToPlayCriteriaNotMet; - } - } - return AiPlayDecision.WillPlay; + return ComputerUtilCard.checkNeedsToPlayReqs(card, sa); } - + // not sure "playing biggest spell" matters? private final static Comparator saComparator = new Comparator() { @Override diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 4af7d5597dd..ccd53683d25 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -37,6 +37,7 @@ import forge.game.zone.MagicStack; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; +import forge.util.Expressions; import forge.util.MyRandom; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.MutablePair; @@ -1785,4 +1786,44 @@ public class ComputerUtilCard { return oppCards; } + + public static AiPlayDecision checkNeedsToPlayReqs(final Card card, final SpellAbility sa) { + Game game = card.getGame(); + boolean isRightSplit = sa != null && sa.isRightSplit(); + String needsToPlayName = isRightSplit ? "SplitNeedsToPlay" : "NeedsToPlay"; + String needsToPlayVarName = isRightSplit ? "SplitNeedsToPlayVar" : "NeedsToPlayVar"; + + if (card.hasSVar(needsToPlayName)) { + final String needsToPlay = card.getSVar(needsToPlayName); + CardCollectionView list = game.getCardsIn(ZoneType.Battlefield); + + list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card, null); + if (list.isEmpty()) { + return AiPlayDecision.MissingNeededCards; + } + } + if (card.getSVar(needsToPlayVarName).length() > 0) { + final String needsToPlay = card.getSVar(needsToPlayVarName); + int x = 0; + int y = 0; + String sVar = needsToPlay.split(" ")[0]; + String comparator = needsToPlay.split(" ")[1]; + String compareTo = comparator.substring(2); + try { + x = Integer.parseInt(sVar); + } catch (final NumberFormatException e) { + x = CardFactoryUtil.xCount(card, card.getSVar(sVar)); + } + try { + y = Integer.parseInt(compareTo); + } catch (final NumberFormatException e) { + y = CardFactoryUtil.xCount(card, card.getSVar(compareTo)); + } + if (!Expressions.compare(x, comparator, y)) { + return AiPlayDecision.NeedsToPlayCriteriaNotMet; + } + } + + return AiPlayDecision.WillPlay; + } } 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 1afb8a7bf9a..c43ec7c9001 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -3,10 +3,7 @@ package forge.ai.ability; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; -import forge.ai.ComputerUtil; -import forge.ai.ComputerUtilCard; -import forge.ai.SpecialCardAi; -import forge.ai.SpellAbilityAi; +import forge.ai.*; import forge.game.ability.AbilityUtils; import forge.game.card.*; import forge.game.card.CardPredicates.Presets; @@ -51,6 +48,13 @@ public class CopyPermanentAi extends SpellAbilityAi { } } + if (sa.hasParam("Embalm") || sa.hasParam("Eternalize")) { + // E.g. Vizier of Many Faces: check to make sure it makes sense to make the token now + if (ComputerUtilCard.checkNeedsToPlayReqs(sa.getHostCard(), sa) != AiPlayDecision.WillPlay) { + return false; + } + } + if (sa.usesTargeting() && sa.hasParam("TargetingPlayer")) { sa.resetTargets(); Player targetingPlayer = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("TargetingPlayer"), sa).get(0);