diff --git a/src/main/java/forge/card/ability/effects/PlayEffect.java b/src/main/java/forge/card/ability/effects/PlayEffect.java index 251ffb3ed01..1130ba752b4 100644 --- a/src/main/java/forge/card/ability/effects/PlayEffect.java +++ b/src/main/java/forge/card/ability/effects/PlayEffect.java @@ -114,9 +114,8 @@ public class PlayEffect extends SpellAbilityEffect { for (SpellAbility s : c.getBasicSpells()) { Spell spell = (Spell) s; s.setActivatingPlayer(controller); - SpellAbilityRestriction res = s.getRestrictions(); // timing restrictions still apply - if (res.checkTimingRestrictions(c, s) && spell.canPlayFromEffectAI(false, true)) { + if (s.getRestrictions().checkTimingRestrictions(c, s) && spell.canPlayFromEffectAI(false, true)) { sas.add(s); } } @@ -206,6 +205,8 @@ public class PlayEffect extends SpellAbilityEffect { if (sa.hasParam("WithoutManaCost")) { if (controller.isHuman()) { + // controller.getGame().getActionPlay().playSpellAbilityForFree(tgtSA); + final SpellAbility newSA = tgtSA.copy(); final Cost cost = new Cost(tgtCard, "", false); if (newSA.getPayCosts() != null) { diff --git a/src/main/java/forge/game/ai/AiController.java b/src/main/java/forge/game/ai/AiController.java index dbba372c178..fac40936c61 100644 --- a/src/main/java/forge/game/ai/AiController.java +++ b/src/main/java/forge/game/ai/AiController.java @@ -19,6 +19,7 @@ package forge.game.ai; import java.security.InvalidParameterException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -38,6 +39,7 @@ import forge.card.ability.ApiType; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.CostDiscard; import forge.card.cost.CostPart; +import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellPermanent; import forge.game.GameActionUtil; @@ -731,5 +733,34 @@ public class AiController { public boolean getBooleanProperty(AiProps propName) { return Boolean.parseBoolean(AiProfileUtil.getAIProp(getPlayer().getLobbyPlayer(), propName)); } + + /** Returns the spell ability which has already been played - use it for reference only */ + public SpellAbility chooseAndPlaySa(boolean mandatory, boolean withoutPayingManaCost, final SpellAbility... list) { + return chooseAndPlaySa(Arrays.asList(list), mandatory, withoutPayingManaCost); + } + /** Returns the spell ability which has already been played - use it for reference only */ + public SpellAbility chooseAndPlaySa(final List choices, boolean mandatory, boolean withoutPayingManaCost) { + for (final SpellAbility sa : choices) { + //Spells + if (sa instanceof Spell) { + if (!((Spell) sa).canPlayFromEffectAI(mandatory, withoutPayingManaCost)) { + continue; + } + } else { + if (sa.canPlayAI()) { + continue; + } + } + + if ( withoutPayingManaCost ) + ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, sa, game); + else if (!ComputerUtilCost.canPayCost(sa, player)) + continue; + else + ComputerUtil.playStack(sa, player, game); + return sa; + } + return null; + } } diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index fa0f93d9635..2629514e34e 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -207,20 +207,21 @@ public class ComputerUtil { */ public static final void playStack(final SpellAbility sa, final AIPlayer ai, final GameState game) { sa.setActivatingPlayer(ai); - if (ComputerUtilCost.canPayCost(sa, ai)) { - final Card source = sa.getSourceCard(); - if (sa.isSpell() && !source.isCopiedSpell()) { - sa.setSourceCard(game.getAction().moveToStack(source)); - } - final Cost cost = sa.getPayCosts(); - if (cost == null) { - ComputerUtilMana.payManaCost(ai, sa); + if (!ComputerUtilCost.canPayCost(sa, ai)) + return; + + final Card source = sa.getSourceCard(); + if (sa.isSpell() && !source.isCopiedSpell()) { + sa.setSourceCard(game.getAction().moveToStack(source)); + } + final Cost cost = sa.getPayCosts(); + if (cost == null) { + ComputerUtilMana.payManaCost(ai, sa); + game.getStack().add(sa); + } else { + final CostPayment pay = new CostPayment(cost, sa, game); + if (pay.payComputerCosts(ai, game)) { game.getStack().add(sa); - } else { - final CostPayment pay = new CostPayment(cost, sa, game); - if (pay.payComputerCosts(ai, game)) { - game.getStack().add(sa); - } } } } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index a595e1c7445..90f7ef66703 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -3122,7 +3122,7 @@ public abstract class Player extends GameEntity implements Comparable { playForMiracleCost.setStackDescription(card.getName() + " - Cast via Miracle"); // TODO Convert this to a Trigger - final Ability miracleTrigger = new MiracleTrigger(card, ManaCost.ZERO, card, playForMiracleCost); + final Ability miracleTrigger = new MiracleTrigger(card, ManaCost.ZERO, playForMiracleCost); miracleTrigger.setStackDescription(card.getName() + " - Miracle."); miracleTrigger.setActivatingPlayer(card.getOwner()); miracleTrigger.setTrigger(true); @@ -3149,36 +3149,24 @@ public abstract class Player extends GameEntity implements Comparable { * */ private final class MiracleTrigger extends Ability { - private final Card card; private final SpellAbility miracle; /** * TODO: Write javadoc for Constructor. * @param sourceCard * @param manaCost - * @param card * @param miracle */ - private MiracleTrigger(Card sourceCard, ManaCost manaCost, Card card, SpellAbility miracle) { + private MiracleTrigger(Card sourceCard, ManaCost manaCost, SpellAbility miracle) { super(sourceCard, manaCost); - this.card = card; this.miracle = miracle; } @Override public void resolve() { - miracle.setActivatingPlayer(card.getOwner()); + miracle.setActivatingPlayer(getSourceCard().getOwner()); // pay miracle cost here. - if (card.getOwner().isHuman()) { - if (GuiDialog.confirm(card, card + " - Drawn. Pay Miracle Cost?")) { - game.getActionPlay().playSpellAbility(miracle, miracle.getActivatingPlayer()); - } - } else { - Spell spell = (Spell) miracle; - if (spell.canPlayFromEffectAI(false, false)) { - ComputerUtil.playStack(miracle, (AIPlayer) card.getOwner(), game); - } - } + getSourceCard().getOwner().getController().playMiracle(miracle, getSourceCard()); } } diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 083cebe6e3b..c9dcc71a99d 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -112,4 +112,6 @@ public abstract class PlayerController { /** p = target player, validCards - possible discards, min cards to discard */ public abstract List chooseCardsToDiscardFrom(Player p, SpellAbility sa, List validCards, int min); public abstract Card chooseCardToDredge(List dredgers); + + public abstract void playMiracle(SpellAbility miracle, Card card); } diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index 44a99c9d880..824188c2ff8 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -88,22 +88,7 @@ public class PlayerControllerAi extends PlayerController { public void playFromSuspend(Card c) { final List choices = c.getBasicSpells(); c.setSuspendCast(true); - for (final SpellAbility sa : choices) { - //Spells - if (sa instanceof Spell) { - Spell spell = (Spell) sa; - if (!spell.canPlayFromEffectAI(true, true)) { - continue; - } - } else { - if (sa.canPlayAI()) { - continue; - } - } - - ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, sa, game); - break; - } + getAi().chooseAndPlaySa(choices, true, true); } /* (non-Javadoc) @@ -112,24 +97,7 @@ public class PlayerControllerAi extends PlayerController { @Override public boolean playCascade(Card cascadedCard, Card source) { final List choices = cascadedCard.getBasicSpells(); - - for (final SpellAbility sa : choices) { - sa.setActivatingPlayer(getPlayer()); - //Spells - if (sa instanceof Spell) { - Spell spell = (Spell) sa; - if (!spell.canPlayFromEffectAI(false, true)) { - continue; - } - } else { - if (!sa.canPlayAI()) { - continue; - } - } - ComputerUtil.playSpellAbilityWithoutPayingManaCost(player, sa, game); - return true; - } - return false; + return null != getAi().chooseAndPlaySa(choices, false, true); } /** @@ -269,4 +237,9 @@ public class PlayerControllerAi extends PlayerController { return brains.chooseCardToDredge(dredgers); } + @Override + public void playMiracle(SpellAbility miracle, Card card) { + getAi().chooseAndPlaySa(false, false, miracle); + } + } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 17d590b5898..3db3aecae0a 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -338,4 +338,14 @@ public class PlayerControllerHuman extends PlayerController { } return null; } + + /* (non-Javadoc) + * @see forge.game.player.PlayerController#playMiracle(forge.card.spellability.SpellAbility, forge.Card) + */ + @Override + public void playMiracle(SpellAbility miracle, Card card) { + if (GuiDialog.confirm(card, card + " - Drawn. Play for Miracle Cost?")) { + game.getActionPlay().playSpellAbility(miracle, getPlayer()); + } + } }