From 803b6331f476641b3769187510bd32e114482079 Mon Sep 17 00:00:00 2001 From: drdev Date: Wed, 4 Dec 2013 02:49:26 +0000 Subject: [PATCH] Fix so abilities using InputPayManaExecuteCommands work with Auto button --- .../main/java/forge/ai/ComputerUtilMana.java | 5 +- .../java/forge/game/player/HumanPlay.java | 191 +++++++++--------- .../main/java/forge/game/player/Player.java | 2 +- .../input/InputPayManaExecuteCommands.java | 21 +- 4 files changed, 98 insertions(+), 121 deletions(-) diff --git a/forge-gui/src/main/java/forge/ai/ComputerUtilMana.java b/forge-gui/src/main/java/forge/ai/ComputerUtilMana.java index 47e3a3a2436..f8035b0aff7 100644 --- a/forge-gui/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-gui/src/main/java/forge/ai/ComputerUtilMana.java @@ -96,10 +96,7 @@ public class ComputerUtilMana { } private static boolean payManaCost(final ManaCostBeingPaid cost, final SpellAbility sa, final Player ai, final boolean test, final int extraMana, boolean checkPlayable) { - final Card card = sa.getSourceCard(); - if (card != null) { - adjustManaCostToAvoidNegEffects(cost, card); - } + adjustManaCostToAvoidNegEffects(cost, sa.getSourceCard()); final ManaPool manapool = ai.getManaPool(); List unpaidShards = cost.getUnpaidShards(); diff --git a/forge-gui/src/main/java/forge/game/player/HumanPlay.java b/forge-gui/src/main/java/forge/game/player/HumanPlay.java index 9173acbe541..e134ca3faf0 100644 --- a/forge-gui/src/main/java/forge/game/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/game/player/HumanPlay.java @@ -67,7 +67,6 @@ import forge.util.Lang; * */ public class HumanPlay { - /** * TODO: Write javadoc for Constructor. */ @@ -93,59 +92,57 @@ public class HumanPlay { return; } - sa.setActivatingPlayer(p); - + final Card source = sa.getSourceCard(); - + source.setSplitStateToPlayAbility(sa); - + if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) { CharmEffect.makeChoices(sa); } - + sa = chooseOptionalAdditionalCosts(p, sa); - + if (sa == null) { return; } - + // Need to check PayCosts, and Ability + All SubAbilities for Target boolean newAbility = sa.getPayCosts() != null; SpellAbility ability = sa; while ((ability != null) && !newAbility) { final TargetRestrictions tgt = ability.getTargetRestrictions(); - + newAbility |= tgt != null; ability = ability.getSubAbility(); } - + // System.out.println("Playing:" + sa.getDescription() + " of " + sa.getSourceCard() + " new = " + newAbility); if (newAbility) { Cost abCost = sa.getPayCosts() == null ? new Cost("0", sa.isAbility()) : sa.getPayCosts(); CostPayment payment = new CostPayment(abCost, sa); - + final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, payment); req.playAbility(true, false, false); - } else { - if (payManaCostIfNeeded(p, sa)) { - if (sa.isSpell() && !source.isCopiedSpell()) { - sa.setSourceCard(p.getGame().getAction().moveToStack(source)); - } - p.getGame().getStack().add(sa); - } + } + else if (payManaCostIfNeeded(p, sa)) { + if (sa.isSpell() && !source.isCopiedSpell()) { + sa.setSourceCard(p.getGame().getAction().moveToStack(source)); + } + p.getGame().getStack().add(sa); } } /** * choose optional additional costs. For HUMAN only - * @param activator + * @param activator * * @param original * the original sa * @return an ArrayList. */ - static SpellAbility chooseOptionalAdditionalCosts(Player p, final SpellAbility original) { + static SpellAbility chooseOptionalAdditionalCosts(Player p, final SpellAbility original) { if (!original.isSpell()) { return original; } @@ -154,17 +151,18 @@ public class HumanPlay { } private static boolean payManaCostIfNeeded(final Player p, final SpellAbility sa) { - final ManaCostBeingPaid manaCost; + final ManaCostBeingPaid manaCost; if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) { manaCost = new ManaCostBeingPaid(ManaCost.ZERO); - } else { + } + else { manaCost = new ManaCostBeingPaid(sa.getPayCosts().getTotalMana()); manaCost.applySpellCostChange(sa, false); } - + boolean isPaid = manaCost.isPaid(); - - if( !isPaid ) { + + if (!isPaid) { InputPayMana inputPay = new InputPayManaSimple(p.getGame(), sa, manaCost); Singletons.getControl().getInputQueue().setInputAndWait(inputPay); isPaid = inputPay.isPaid(); @@ -180,9 +178,9 @@ public class HumanPlay { public static final void playCardWithoutPayingManaCost(Player player, Card c) { final List choices = c.getBasicSpells(); // TODO add Buyback, Kicker, ... , spells here - + SpellAbility sa = player.getController().getAbilityToPlay(choices); - + if (sa != null) { sa.setActivatingPlayer(player); playSaWithoutPayingManaCost(player.getGame(), sa, true); @@ -200,18 +198,19 @@ public class HumanPlay { public static final void playSaWithoutPayingManaCost(final Game game, final SpellAbility sa, boolean mayChooseNewTargets) { FThreads.assertExecutedByEdt(false); final Card source = sa.getSourceCard(); - + source.setSplitStateToPlayAbility(sa); - + if (sa.getPayCosts() != null) { if (sa.getApi() == ApiType.Charm && !sa.isWrapper() && !sa.isCopied()) { CharmEffect.makeChoices(sa); } final CostPayment payment = new CostPayment(sa.getPayCosts(), sa); - + final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, payment); req.playAbility(mayChooseNewTargets, true, false); - } else { + } + else { if (sa.isSpell()) { final Card c = sa.getSourceCard(); if (!c.isCopiedSpell()) { @@ -238,21 +237,19 @@ public class HumanPlay { public final static void playSpellAbilityNoStack(final Player player, final SpellAbility sa, boolean useOldTargets) { sa.setActivatingPlayer(player); - + if (sa.getPayCosts() != null) { final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, new CostPayment(sa.getPayCosts(), sa)); - + req.playAbility(!useOldTargets, false, true); - } else { - if (payManaCostIfNeeded(player, sa)) { - AbilityUtils.resolve(sa); - } - + } + else if (payManaCostIfNeeded(player, sa)) { + AbilityUtils.resolve(sa); } } // ------------------------------------------------------------------------ - + private static int getAmountFromPart(CostPart part, Card source, SpellAbility sourceAbility) { String amountString = part.getAmount(); return StringUtils.isNumeric(amountString) ? Integer.parseInt(amountString) : AbilityUtils.calculateAmount(source, amountString, sourceAbility); @@ -285,20 +282,18 @@ public class HumanPlay { * a {@link forge.Command} object. * @param sourceAbility TODO */ - public static boolean payCostDuringAbilityResolve(final Player p, final Card source, final Cost cost, SpellAbility sourceAbility - , String prompt) { - + public static boolean payCostDuringAbilityResolve(final Player p, final Card source, final Cost cost, SpellAbility sourceAbility, String prompt) { // Only human player pays this way Card current = null; // Used in spells with RepeatEach effect to distinguish cards, Cut the Tethers if (!source.getRemembered().isEmpty()) { - if (source.getRemembered().get(0) instanceof Card) { + if (source.getRemembered().get(0) instanceof Card) { current = (Card) source.getRemembered().get(0); } } if (!source.getImprinted().isEmpty()) { current = source.getImprinted().get(0); } - + final List parts = cost.getCostParts(); ArrayList remainingParts = new ArrayList(cost.getCostParts()); CostPart costPart = null; @@ -320,7 +315,7 @@ public class HumanPlay { //the following costs do not need inputs for (CostPart part : parts) { boolean mayRemovePart = true; - + if (part instanceof CostPayLife) { final int amount = getAmountFromPart(part, source, sourceAbility); if (!p.canPayLife(amount)) @@ -331,7 +326,6 @@ public class HumanPlay { p.payLife(amount, null); } - else if (part instanceof CostDraw) { final int amount = getAmountFromPart(part, source, sourceAbility); List res = new ArrayList(); @@ -361,13 +355,11 @@ public class HumanPlay { player.drawCards(amount); } } - else if (part instanceof CostGainLife) { if (!part.payHuman(sourceAbility, p.getGame())) { return false; } } - else if (part instanceof CostAddMana) { if (!GuiDialog.confirm(source, "Do you want to add " + ((CostAddMana) part).toString() @@ -378,7 +370,6 @@ public class HumanPlay { return false; } } - else if (part instanceof CostMill) { final int amount = getAmountFromPart(part, source, sourceAbility); final List list = p.getCardsIn(ZoneType.Library); @@ -388,7 +379,6 @@ public class HumanPlay { List listmill = p.getCardsIn(ZoneType.Library, amount); ((CostMill) part).executePayment(sourceAbility, listmill); } - else if (part instanceof CostFlipCoin) { final int amount = getAmountFromPart(part, source, sourceAbility); if (!GuiDialog.confirm(source, "Do you want to flip " + amount + " coin(s)?" + orString)) @@ -398,18 +388,16 @@ public class HumanPlay { FlipCoinEffect.flipCoinCall(p, sourceAbility, n); } } - else if (part instanceof CostDamage) { int amount = getAmountFromPartX(part, source, sourceAbility); if (!p.canPayLife(amount)) return false; - + if (false == GuiDialog.confirm(source, "Do you want " + source + " to deal " + amount + " damage to you?")) return false; - + p.addDamage(amount, source); } - else if (part instanceof CostPutCounter) { CounterType counterType = ((CostPutCounter) part).getCounter(); int amount = getAmountFromPartX(part, source, sourceAbility); @@ -420,7 +408,7 @@ public class HumanPlay { return false; } - if (!GuiDialog.confirm(source, "Do you want to put " + Lang.nounWithAmount(amount, counterType.getName() + " counter") + " on " + source + "?")) + if (!GuiDialog.confirm(source, "Do you want to put " + Lang.nounWithAmount(amount, counterType.getName() + " counter") + " on " + source + "?")) return false; source.addCounter(counterType, amount, false); @@ -428,23 +416,21 @@ public class HumanPlay { List list = p.getGame().getCardsIn(ZoneType.Battlefield); list = CardLists.getValidCards(list, part.getType().split(";"), p, source); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "add a counter." + orString); - if(!hasPaid) return false; + if (!hasPaid) return false; } } - else if (part instanceof CostRemoveCounter) { CounterType counterType = ((CostRemoveCounter) part).getCounter(); int amount = getAmountFromPartX(part, source, sourceAbility); - + if (!part.canPay(sourceAbility)) return false; - - if ( false == GuiDialog.confirm(source, "Do you want to remove " + Lang.nounWithAmount(amount, counterType.getName() + " counter") + " from " + source + "?")) + + if (false == GuiDialog.confirm(source, "Do you want to remove " + Lang.nounWithAmount(amount, counterType.getName() + " counter") + " from " + source + "?")) return false; - + source.subtractCounter(counterType, amount); } - else if (part instanceof CostRemoveAnyCounter) { int amount = getAmountFromPartX(part, source, sourceAbility); List list = new ArrayList(p.getCardsIn(ZoneType.Battlefield)); @@ -494,12 +480,11 @@ public class HumanPlay { amount--; } } - else if (part instanceof CostExile) { if ("All".equals(part.getType())) { if (false == GuiDialog.confirm(source, "Do you want to exile all cards in your graveyard?")) return false; - + List cards = new ArrayList(p.getCardsIn(ZoneType.Graveyard)); for (final Card card : cards) { p.getGame().getAction().exile(card); @@ -526,13 +511,12 @@ public class HumanPlay { final Card c = GuiChoose.oneOrNone("Exile from " + from, list); if (c == null) return false; - + list.remove(c); p.getGame().getAction().exile(c); } } } - else if (part instanceof CostPutCardToLib) { int amount = Integer.parseInt(((CostPutCardToLib) part).getAmount()); final ZoneType from = ((CostPutCardToLib) part).getFrom(); @@ -577,7 +561,8 @@ public class HumanPlay { return false; } } - } else if (from == ZoneType.Hand) { // Tainted Specter + } + else if (from == ZoneType.Hand) { // Tainted Specter boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "put into library." + orString); if (!hasPaid) { return false; @@ -585,52 +570,57 @@ public class HumanPlay { } return true; } - else if (part instanceof CostSacrifice) { int amount = Integer.parseInt(((CostSacrifice)part).getAmount()); List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "sacrifice." + orString); - if(!hasPaid) return false; - } else if (part instanceof CostGainControl) { + if (!hasPaid) return false; + } + else if (part instanceof CostGainControl) { int amount = Integer.parseInt(((CostGainControl)part).getAmount()); List list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield), part.getType(), p, source); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "gain control." + orString); - if(!hasPaid) return false; - } else if (part instanceof CostReturn) { + if (!hasPaid) return false; + } + else if (part instanceof CostReturn) { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source); int amount = getAmountFromPartX(part, source, sourceAbility); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "return to hand." + orString); - if(!hasPaid) return false; - } else if (part instanceof CostDiscard) { + if (!hasPaid) return false; + } + else if (part instanceof CostDiscard) { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), part.getType(), p, source); int amount = getAmountFromPartX(part, source, sourceAbility); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "discard." + orString); - if(!hasPaid) return false; - } else if (part instanceof CostReveal) { + if (!hasPaid) return false; + } + else if (part instanceof CostReveal) { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), part.getType(), p, source); int amount = getAmountFromPartX(part, source, sourceAbility); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "reveal." + orString); - if(!hasPaid) return false; - } else if (part instanceof CostTapType) { + if (!hasPaid) return false; + } + else if (part instanceof CostTapType) { List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source); list = CardLists.filter(list, Presets.UNTAPPED); int amount = getAmountFromPartX(part, source, sourceAbility); boolean hasPaid = payCostPart(sourceAbility, (CostPartWithList)part, amount, list, "tap." + orString); - if(!hasPaid) return false; + if (!hasPaid) return false; } - - else if (part instanceof CostPartMana ) { - if (!((CostPartMana) part).getManaToPay().isZero()) // non-zero costs require input - mayRemovePart = false; - } else { + else if (part instanceof CostPartMana) { + if (!((CostPartMana) part).getManaToPay().isZero()) { // non-zero costs require input + mayRemovePart = false; + } + } + else { throw new RuntimeException("GameActionUtil.payCostDuringAbilityResolve - An unhandled type of cost was met: " + part.getClass()); } - - if( mayRemovePart ) + + if (mayRemovePart) { remainingParts.remove(part); + } } - - + if (remainingParts.isEmpty()) { return true; } @@ -639,30 +629,32 @@ public class HumanPlay { } costPart = remainingParts.get(0); // check this is a mana cost - if (!(costPart instanceof CostPartMana )) + if (!(costPart instanceof CostPartMana)) { throw new RuntimeException("GameActionUtil.payCostDuringAbilityResolve - The remaining payment type is not Mana."); - - if (prompt == null) { - String promptCurrent = current == null ? "" : "Current Card: " + current + "\r\n"; - prompt = source + "\r\n" + promptCurrent; } - InputPayMana toSet = new InputPayManaExecuteCommands(p, prompt, cost.getCostMana().getManaToPay()); + + if (prompt == null) { + String promptCurrent = current == null ? "" : "Current Card: " + current; + prompt = source + "\n" + promptCurrent; + } + InputPayMana toSet = new InputPayManaExecuteCommands(source, p, prompt, cost.getCostMana().getManaToPay()); Singletons.getControl().getInputQueue().setInputAndWait(toSet); return toSet.isPaid(); } private static boolean payCostPart(SpellAbility sourceAbility, CostPartWithList cpl, int amount, List list, String actionName) { if (list.size() < amount) return false; // unable to pay (not enough cards) - + InputSelectCards inp = new InputSelectCardsFromList(amount, amount, list); inp.setMessage("Select %d " + cpl.getDescriptiveType() + " card(s) to " + actionName); inp.setCancelAllowed(true); - + Singletons.getControl().getInputQueue().setInputAndWait(inp); - if( inp.hasCancelled() || inp.getSelected().size() != amount) + if (inp.hasCancelled() || inp.getSelected().size() != amount) { return false; - - for(Card c : inp.getSelected()) { + } + + for (Card c : inp.getSelected()) { cpl.executePayment(sourceAbility, c); } if (sourceAbility != null) { @@ -670,5 +662,4 @@ public class HumanPlay { } return true; } - } diff --git a/forge-gui/src/main/java/forge/game/player/Player.java b/forge-gui/src/main/java/forge/game/player/Player.java index bcb7e9e9bce..aad9982095d 100644 --- a/forge-gui/src/main/java/forge/game/player/Player.java +++ b/forge-gui/src/main/java/forge/game/player/Player.java @@ -2947,7 +2947,7 @@ public class Player extends GameEntity implements Comparable { * @param proc */ public void runAsAi(Runnable proc) { - if (PlayerControllerAi.class.isInstance(controller)) { + if (controller instanceof PlayerControllerAi) { proc.run(); //can just run with current controller if it's an AI controller return; } diff --git a/forge-gui/src/main/java/forge/gui/input/InputPayManaExecuteCommands.java b/forge-gui/src/main/java/forge/gui/input/InputPayManaExecuteCommands.java index 9465aeb9126..2084f9e149a 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputPayManaExecuteCommands.java +++ b/forge-gui/src/main/java/forge/gui/input/InputPayManaExecuteCommands.java @@ -18,6 +18,7 @@ package forge.gui.input; import forge.card.mana.ManaCost; +import forge.game.card.Card; import forge.game.cost.Cost; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; @@ -45,36 +46,24 @@ public class InputPayManaExecuteCommands extends InputPayMana { private boolean bPaid = false; public boolean isPaid() { return bPaid; } - /** *

* Constructor for Input_PayManaCost_Ability. *

- * - * @param m - * a {@link java.lang.String} object. - * @param manaCost2 - * a {@link java.lang.String} object. - * @param paidCommand2 - * a {@link forge.Command} object. - * @param unpaidCommand2 - * a {@link forge.Command} object. */ - public InputPayManaExecuteCommands(final Player p, final String prompt, final ManaCost manaCost2) { - super(new SpellAbility(null, Cost.Zero) { + public InputPayManaExecuteCommands(final Card sourceCard, final Player p, final String prompt, final ManaCost manaCost0) { + super(new SpellAbility(sourceCard, Cost.Zero) { @Override public void resolve() {} @Override public Player getActivatingPlayer() { return p; } @Override public boolean canPlay() { return false; } }); - this.originalManaCost = manaCost2; + this.originalManaCost = manaCost0; this.phyLifeToLose = 0; this.message = prompt; this.manaCost = new ManaCostBeingPaid(this.originalManaCost); - } - @Override public void selectPlayer(final Player selectedPlayer) { if (player == selectedPlayer) { @@ -105,7 +94,7 @@ public class InputPayManaExecuteCommands extends InputPayMana { /** {@inheritDoc} */ @Override protected String getMessage() { - final StringBuilder msg = new StringBuilder(this.message + "Pay Mana Cost: " + this.manaCost); + final StringBuilder msg = new StringBuilder(this.message + "\n\nPay Mana Cost: " + this.manaCost); if (this.phyLifeToLose > 0) { msg.append(" ("); msg.append(this.phyLifeToLose);