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 e28d28e06fb..1b3743f929c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -477,23 +477,13 @@ public class PumpAi extends PumpAiBase { list = ComputerUtil.getSafeTargets(ai, sa, list); } - if ("Snapcaster".equals(sa.getParam("AILogic"))) { // can afford to and will play snap-casted spell - AiController aic = ((PlayerControllerAi) ai.getController()).getAi(); - Card targetSnapcast = null; - for (Card c : list) { - for (SpellAbility ab : c.getSpellAbilities()) { - final boolean play = AiPlayDecision.WillPlay == aic.canPlaySa(ab); - final boolean pay = ComputerUtilCost.canPayCost(ab, ai); - if (play && pay) { - targetSnapcast = c; - break; - } - } - } - if (targetSnapcast == null) { + if ("Snapcaster".equals(sa.getParam("AILogic"))) { + if (!doTargetSpellToPlayLogic(ai, list, sa, false)) { + return false; + } + } else if ("PlaySpellForFree".equals(sa.getParam("AILogic"))) { + if (!doTargetSpellToPlayLogic(ai, list, sa, true)) { return false; - } else { - sa.getTargets().add(targetSnapcast); } } @@ -530,6 +520,32 @@ public class PumpAi extends PumpAiBase { return true; } // pumpTgtAI() + private boolean doTargetSpellToPlayLogic(final Player ai, CardCollection options, final SpellAbility sa, final boolean withoutPayingManaCost) { + // determine and target a card with a SA that the AI can afford and will play + AiController aic = ((PlayerControllerAi) ai.getController()).getAi(); + Card targetSpellCard = null; + for (Card c : options) { + for (SpellAbility ab : c.getSpellAbilities()) { + SpellAbility abTest = withoutPayingManaCost ? ab.copyWithNoManaCost() : ab.copy(); + // at this point, we're assuming that card will be castable from whichever zone it's in by the AI player. + abTest.setActivatingPlayer(ai); + abTest.getRestrictions().setZone(c.getZone().getZoneType()); + final boolean play = AiPlayDecision.WillPlay == aic.canPlaySa(abTest); + final boolean pay = ComputerUtilCost.canPayCost(abTest, ai); + if (play && pay) { + targetSpellCard = c; + break; + } + } + } + if (targetSpellCard == null) { + return false; + } else { + sa.getTargets().add(targetSpellCard); + } + return true; + } + private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa) { final Game game = ai.getGame(); final TargetRestrictions tgt = sa.getTargetRestrictions(); diff --git a/forge-gui/res/cardsfolder/g/goblin_dark_dwellers.txt b/forge-gui/res/cardsfolder/g/goblin_dark_dwellers.txt index 9e554dbda55..d8e8f7b82e3 100644 --- a/forge-gui/res/cardsfolder/g/goblin_dark_dwellers.txt +++ b/forge-gui/res/cardsfolder/g/goblin_dark_dwellers.txt @@ -4,7 +4,7 @@ Types:Creature Goblin PT:4/4 K:Menace T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters the battlefield, you may cast target instant or sorcery card with converted mana cost 3 or less from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead. -SVar:TrigPump:AB$ Pump | Cost$ 0 | TgtZone$ Graveyard | ValidTgts$ Instant.YouCtrl+cmcLE3,Sorcery.YouCtrl+cmcLE3 | TgtPrompt$ Choose target instant or sorcery card with converted mana cost 3 or less from your graveyard |KW$ HIDDEN If CARDNAME would be put into a graveyard, exile it instead. | PumpZone$ Graveyard | SubAbility$ TrigPlay +SVar:TrigPump:AB$ Pump | Cost$ 0 | TgtZone$ Graveyard | ValidTgts$ Instant.YouCtrl+cmcLE3,Sorcery.YouCtrl+cmcLE3 | TgtPrompt$ Choose target instant or sorcery card with converted mana cost 3 or less from your graveyard | KW$ HIDDEN If CARDNAME would be put into a graveyard, exile it instead. | PumpZone$ Graveyard | AILogic$ PlaySpellForFree | SubAbility$ TrigPlay SVar:TrigPlay:DB$ Play | Defined$ Targeted | WithoutManaCost$ True | Optional$ True SVar:Picture:http://www.wizards.com/global/images/magic/general/goblin_dark_dwellers.jpg Oracle:Menace\nWhen Goblin Dark-Dwellers enters the battlefield, you may cast target instant or sorcery card with converted mana cost 3 or less from your graveyard without paying its mana cost. If that card would be put into your graveyard this turn, exile it instead. diff --git a/forge-gui/res/cardsfolder/s/snapcaster_mage.txt b/forge-gui/res/cardsfolder/s/snapcaster_mage.txt index 86a2e216077..376294b5ddd 100644 --- a/forge-gui/res/cardsfolder/s/snapcaster_mage.txt +++ b/forge-gui/res/cardsfolder/s/snapcaster_mage.txt @@ -4,7 +4,7 @@ Types:Creature Human Wizard PT:2/1 K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigRearrange | TriggerDescription$ When CARDNAME enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost. (You may cast that card from your graveyard for its flashback cost. Then exile it.) -SVar:TrigRearrange:AB$ Pump | Cost$ 0 | ValidTgts$ Instant.YouCtrl,Sorcery.YouCtrl | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card | KW$ Flashback | PumpZone$ Graveyard +SVar:TrigRearrange:AB$ Pump | Cost$ 0 | ValidTgts$ Instant.YouCtrl,Sorcery.YouCtrl | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card | KW$ Flashback | PumpZone$ Graveyard | AILogic$ Snapcaster SVar:RemAIDeck:True SVar:Picture:http://www.wizards.com/global/images/magic/general/snapcaster_mage.jpg Oracle:Flash\nWhen Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost. (You may cast that card from your graveyard for its flashback cost. Then exile it.)