diff --git a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java
index cc2dc4647d6..71fd9251221 100644
--- a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java
+++ b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java
@@ -75,6 +75,7 @@ public enum SpellApiToAi {
.put(ApiType.DigMultiple, DigMultipleAi.class)
.put(ApiType.DigUntil, DigUntilAi.class)
.put(ApiType.Discard, DiscardAi.class)
+ .put(ApiType.Discover, DiscoverAi.class)
.put(ApiType.Draft, ChooseCardNameAi.class)
.put(ApiType.DrainMana, DrainManaAi.class)
.put(ApiType.Draw, DrawAi.class)
diff --git a/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java b/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java
new file mode 100644
index 00000000000..a9afdd1340d
--- /dev/null
+++ b/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java
@@ -0,0 +1,67 @@
+package forge.ai.ability;
+
+import forge.ai.AiPlayDecision;
+import forge.ai.ComputerUtil;
+import forge.ai.PlayerControllerAi;
+import forge.ai.SpellAbilityAi;
+import forge.card.CardStateName;
+import forge.game.ability.AbilityUtils;
+import forge.game.card.Card;
+import forge.game.player.Player;
+import forge.game.player.PlayerActionConfirmMode;
+import forge.game.spellability.LandAbility;
+import forge.game.spellability.Spell;
+import forge.game.spellability.SpellAbility;
+
+import java.util.Map;
+
+public class DiscoverAi extends SpellAbilityAi {
+
+ @Override
+ protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
+ if (ComputerUtil.preventRunAwayActivations(sa)) {
+ return false; // prevent infinite loop
+ }
+
+ return true;
+ }
+
+ /**
+ *
+ * doTriggerAINoCost
+ *
+ * @param sa
+ * a {@link forge.game.spellability.SpellAbility} object.
+ * @param mandatory
+ * a boolean.
+ *
+ * @return a boolean.
+ */
+ @Override
+ protected boolean doTriggerAINoCost(final Player ai, final SpellAbility sa, final boolean mandatory) {
+ return mandatory || checkApiLogic(ai, sa);
+ }
+
+ @Override
+ public boolean confirmAction(Player ai, SpellAbility sa, PlayerActionConfirmMode mode, String message, Map params) {
+ Card c = (Card)params.get("Card");
+ for (SpellAbility s : AbilityUtils.getBasicSpellsFromPlayEffect(c, ai, CardStateName.Original)) { // TODO: other states for split cards and MDFC?
+ if (s instanceof LandAbility) {
+ // return false or we get a ClassCastException later if the AI encounters MDFC with land backside
+ return false;
+ }
+ Spell spell = (Spell) s;
+ if (AiPlayDecision.WillPlay == ((PlayerControllerAi)ai.getController()).getAi().canPlayFromEffectAI(spell, false, true)) {
+ // Before accepting, see if the spell has a valid number of targets (it should at this point).
+ // Proceeding past this point if the spell is not correctly targeted will result
+ // in "Failed to add to stack" error and the card disappearing from the game completely.
+ if (!spell.isTargetNumberValid()) {
+ // if we won't be able to pay the cost, don't choose the card
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java
index ca1648ba882..a8e03769fc8 100644
--- a/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java
+++ b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java
@@ -28,6 +28,7 @@
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -76,6 +77,8 @@ public void resolve(SpellAbility sa) {
changeZone(exiled, ZoneType.Exile, game, sa);
// Cast it without paying its mana cost or put it into your hand.
+ Map params = new HashMap<>();
+ params.put("Card", found);
if (found != null) {
String prompt = Localizer.getInstance().getMessage("lblDiscoverChoice",
CardTranslation.getTranslatedName(found.getName()));
@@ -83,7 +86,7 @@ public void resolve(SpellAbility sa) {
List options =
Arrays.asList(StringUtils.capitalize(Localizer.getInstance().getMessage("lblCast")),
StringUtils.capitalize(Localizer.getInstance().getMessage("lblHandZone")));
- final boolean play = p.getController().confirmAction(sa, null, prompt, options, found, null);
+ final boolean play = p.getController().confirmAction(sa, null, prompt, options, found, params);
boolean cancel = false;
if (play) {