From 19a1a7b173e9ccb8fa534206dad87e5bd23c3f08 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Mon, 25 Mar 2013 19:47:10 +0000 Subject: [PATCH] GameAction.payCostDuringAbilityResolve now returns a boolean indicating whether the cost was paid, all the paid/unpaid commands eliminated, since the code may be executed right after payCostDuringAbilityResolve under if's branches --- .../java/forge/card/ability/AbilityUtils.java | 106 ++++++------------ src/main/java/forge/game/GameAction.java | 24 +--- src/main/java/forge/game/GameActionUtil.java | 23 +--- .../java/forge/game/phase/CombatUtil.java | 41 ++----- src/main/java/forge/game/phase/Upkeep.java | 34 +----- 5 files changed, 58 insertions(+), 170 deletions(-) diff --git a/src/main/java/forge/card/ability/AbilityUtils.java b/src/main/java/forge/card/ability/AbilityUtils.java index 3cd3126e23b..e6a5beab7bc 100644 --- a/src/main/java/forge/card/ability/AbilityUtils.java +++ b/src/main/java/forge/card/ability/AbilityUtils.java @@ -10,7 +10,6 @@ import org.apache.commons.lang3.StringUtils; import forge.Card; import forge.CardLists; import forge.CardUtil; -import forge.Command; import forge.Constant; import forge.CounterType; import forge.Singletons; @@ -1036,6 +1035,19 @@ public class AbilityUtils { AbilityUtils.resolveApiAbility(abSub, usedStack, game); } + private static void resolveApiAbility(final SpellAbility sa, boolean usedStack, final GameState game) { + // check conditions + if (sa.getConditions().areMet(sa)) { + if (sa.isWrapper() || StringUtils.isBlank(sa.getParam("UnlessCost"))) { + sa.resolve(); + } else { + handleUnlessCost(sa, usedStack, game); + return; + } + } + resolveSubAbilities(sa, usedStack, game); + } + private static void handleUnlessCost(final SpellAbility sa, final boolean usedStack, final GameState game) { final Card source = sa.getSourceCard(); String unlessCost = sa.getParam("UnlessCost"); @@ -1047,7 +1059,8 @@ public class AbilityUtils { final String resolveSubs = sa.getParam("UnlessResolveSubs"); // no value means 'Always' final boolean execSubsWhenPaid = "WhenPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); final boolean execSubsWhenNotPaid = "WhenNotPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs); - + final boolean isSwitched = sa.hasParam("UnlessSwitched"); + // The cost if (unlessCost.equals("CardManaCost")) { unlessCost = source.getManaCost().toString(); @@ -1070,43 +1083,6 @@ public class AbilityUtils { //instead of just X for cards like Draco. } - final boolean isSwitched = sa.hasParam("UnlessSwitched"); - - Command paidCommand = new Command() { - private static final long serialVersionUID = 8094833091127334678L; - - @Override - public void execute() { - if (isSwitched && execSubsWhenNotPaid || execSubsWhenPaid) { - resolveSubAbilities(sa, usedStack, game); - } else if (usedStack) { - SpellAbility root = sa.getRootAbility(); - game.getStack().finishResolving(root, false); - } - } - }; - - Command unpaidCommand = new Command() { - private static final long serialVersionUID = 8094833091127334678L; - - @Override - public void execute() { - sa.resolve(); - if (isSwitched && execSubsWhenPaid || execSubsWhenNotPaid) { - resolveSubAbilities(sa, usedStack, game); - } else if (usedStack) { - SpellAbility root = sa.getRootAbility(); - game.getStack().finishResolving(root, false); - } - } - }; - - if (isSwitched) { - final Command dummy = paidCommand; - paidCommand = unpaidCommand; - unpaidCommand = dummy; - } - final Cost cost = new Cost(source, unlessCost, true); final Ability ability = new AbilityStatic(source, cost, null) { @Override @@ -1117,34 +1093,35 @@ public class AbilityUtils { boolean paid = false; for (Player payer : payers) { + ability.setActivatingPlayer(payer); + ability.setTarget(sa.getTarget()); if (payer.isComputer()) { - ability.setActivatingPlayer(payer); if (AbilityUtils.willAIPayForAbility(sa, payer, ability, paid, payers)) { - ability.setTarget(sa.getTarget()); ComputerUtil.playNoStack((AIPlayer) payer, ability, game); // Unless cost was payed - no resolve paid = true; } - } - } - boolean waitForInput = false; - for (Player payer : payers) { - if (payer.isHuman()) { + } else { // if it's paid by the AI already the human can pay, but it won't change anything - if (paid) { - unpaidCommand = paidCommand; - } - ability.setActivatingPlayer(payer); - ability.setTarget(sa.getTarget()); - GameActionUtil.payCostDuringAbilityResolve(payer, ability, cost, paidCommand, unpaidCommand, sa, game); - waitForInput = true; // wait for the human input - break; // multiple human players are not supported + paid = GameActionUtil.payCostDuringAbilityResolve(payer, ability, cost, sa, game); } } - if (!waitForInput) { - Command toExecute = paid ? paidCommand : unpaidCommand; - toExecute.execute(); - } + if ( paid ^ isSwitched ) { + if (isSwitched && execSubsWhenNotPaid || execSubsWhenPaid) { + resolveSubAbilities(sa, usedStack, game); + } else if (usedStack) { + SpellAbility root = sa.getRootAbility(); + game.getStack().finishResolving(root, false); + } + } else { + sa.resolve(); + if (isSwitched && execSubsWhenPaid || execSubsWhenNotPaid) { + resolveSubAbilities(sa, usedStack, game); + } else if (usedStack) { + SpellAbility root = sa.getRootAbility(); + game.getStack().finishResolving(root, false); + } + } } /** @@ -1221,19 +1198,6 @@ public class AbilityUtils { return false; } - private static void resolveApiAbility(final SpellAbility sa, boolean usedStack, final GameState game) { - // check conditions - if (sa.getConditions().areMet(sa)) { - if (sa.isWrapper() || StringUtils.isBlank(sa.getParam("UnlessCost"))) { - sa.resolve(); - } else { - handleUnlessCost(sa, usedStack, game); - return; - } - } - resolveSubAbilities(sa, usedStack, game); - } - /** *

* Parse non-mana X variables. diff --git a/src/main/java/forge/game/GameAction.java b/src/main/java/forge/game/GameAction.java index 1f9f173ab54..b96c156b628 100644 --- a/src/main/java/forge/game/GameAction.java +++ b/src/main/java/forge/game/GameAction.java @@ -486,24 +486,6 @@ public class GameAction { final String recoverCost = recoverable.getKeyword().get(recoverable.getKeywordPosition("Recover")).split(":")[1]; final Cost cost = new Cost(recoverable, recoverCost, true); - final Command paidCommand = new Command() { - private static final long serialVersionUID = -6357156873861051845L; - - @Override - public void execute() { - moveToHand(recoverable); - } - }; - - final Command unpaidCommand = new Command() { - private static final long serialVersionUID = -7354791599039157375L; - - @Override - public void execute() { - exile(recoverable); - } - }; - final SpellAbility abRecover = new AbilityActivated(recoverable, cost, null) { private static final long serialVersionUID = 8858061639236920054L; @@ -535,8 +517,10 @@ public class GameAction { Player p = recoverable.getController(); if (p.isHuman()) { - GameActionUtil.payCostDuringAbilityResolve(p, abRecover, abRecover.getPayCosts(), - paidCommand, unpaidCommand, null, game); + if ( GameActionUtil.payCostDuringAbilityResolve(p, abRecover, abRecover.getPayCosts(), null, game) ) + moveToHand(recoverable); + else + exile(recoverable); } else { // computer if (ComputerUtilCost.canPayCost(abRecover, p)) { ComputerUtil.playNoStack((AIPlayer)p, abRecover, game); diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index 94e361bbf35..7a6bcfae599 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -382,8 +382,7 @@ public final class GameActionUtil { * a {@link forge.Command} object. * @param sourceAbility TODO */ - public static void payCostDuringAbilityResolve(final Player p, final SpellAbility ability, final Cost cost, final Command paid, - final Command unpaid, SpellAbility sourceAbility, final GameState game) { + public static boolean payCostDuringAbilityResolve(final Player p, final SpellAbility ability, final Cost cost, SpellAbility sourceAbility, final GameState game) { final Card source = ability.getSourceCard(); final List parts = cost.getCostParts(); ArrayList remainingParts = new ArrayList(cost.getCostParts()); @@ -396,13 +395,9 @@ public final class GameActionUtil { orString = " (or: " + sourceAbility.getStackDescription() + ")"; } if (parts.isEmpty() || costPart.getAmount().equals("0")) { - if (GuiDialog.confirm(source, "Do you want to pay 0?" + orString)) { - paid.execute(); - } else { - unpaid.execute(); - } - return; + return GuiDialog.confirm(source, "Do you want to pay 0?" + orString); } + boolean hasPaid = true; //the following costs do not need inputs for (CostPart part : parts) { @@ -591,12 +586,10 @@ public final class GameActionUtil { GuiUtils.clearPanelSelections(); if (!hasPaid) { - unpaid.execute(); - return; + return false; } if (remainingParts.isEmpty()) { - paid.execute(); - return; + return true; } if (remainingParts.size() > 1) { throw new RuntimeException("GameActionUtil::payCostDuringAbilityResolve - Too many payment types - " + source); @@ -609,11 +602,7 @@ public final class GameActionUtil { InputPayment toSet = new InputPayManaExecuteCommands(game, source + "\r\n", ability.getManaCost()); FThreads.setInputAndWait(toSet); - if (toSet.isPaid() ) { - paid.execute(); - } else { - unpaid.execute(); - } + return toSet.isPaid(); } // not restricted to combat damage, not restricted to dealing damage to diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index ca05584df4a..d78e99e53df 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -1150,39 +1150,13 @@ public class CombatUtil { } }; - final Command unpaidCommand = new Command() { - - private static final long serialVersionUID = -6483405139208343935L; - - @Override - public void execute() { - game.getCombat().removeFromCombat(crd); - - if (bLast) { - PhaseUtil.handleAttackingTriggers(); - } - } - }; - - final Command paidCommand = new Command() { - private static final long serialVersionUID = -8303368287601871955L; - - @Override - public void execute() { - // if Propaganda is paid, tap this card - if (!crd.hasKeyword("Vigilance")) { - crd.tap(); - } - - if (bLast) { - PhaseUtil.handleAttackingTriggers(); - } - } - }; - ability.setActivatingPlayer(c.getController()); if (c.getController().isHuman()) { - GameActionUtil.payCostDuringAbilityResolve(c.getController(), ability, attackCost, paidCommand, unpaidCommand, null, game); + if ( GameActionUtil.payCostDuringAbilityResolve(c.getController(), ability, attackCost, null, game) ) { + if (!crd.hasKeyword("Vigilance")) { crd.tap(); } + } else { + game.getCombat().removeFromCombat(crd); + } } else { // computer if (ComputerUtilCost.canPayCost(ability, c.getController())) { ComputerUtil.playNoStack((AIPlayer)c.getController(), ability, game); @@ -1194,10 +1168,9 @@ public class CombatUtil { // during Declare_Attackers game.getCombat().removeFromCombat(crd); } - if (bLast) { - PhaseUtil.handleAttackingTriggers(); - } } + if (bLast) + PhaseUtil.handleAttackingTriggers(); } } diff --git a/src/main/java/forge/game/phase/Upkeep.java b/src/main/java/forge/game/phase/Upkeep.java index fe594f40c68..fe7fcf9e320 100644 --- a/src/main/java/forge/game/phase/Upkeep.java +++ b/src/main/java/forge/game/phase/Upkeep.java @@ -175,18 +175,6 @@ public class Upkeep extends Phase { for (int i = 0; i < list.size(); i++) { final Card c = list.get(i); if (c.hasStartOfKeyword("(Echo unpaid)")) { - - final Command paidCommand = Command.BLANK; - - final Command unpaidCommand = new Command() { - private static final long serialVersionUID = -7354791599039157375L; - - @Override - public void execute() { - game.getAction().sacrifice(c, null); - } - }; - final Ability blankAbility = Upkeep.BlankAbility(c, c.getEchoCost()); final StringBuilder sb = new StringBuilder(); @@ -199,7 +187,9 @@ public class Upkeep extends Phase { Player controller = c.getController(); if (controller.isHuman()) { Cost cost = new Cost(c, c.getEchoCost().trim(), true); - GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, cost, paidCommand, unpaidCommand, null, game); + if ( !GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, cost, null, game) ) + game.getAction().sacrifice(c, null);; + } else { // computer if (ComputerUtilCost.canPayCost(blankAbility, controller)) { ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game); @@ -332,18 +322,6 @@ public class Upkeep extends Phase { } final String upkeepCost = cost; - - final Command unpaidCommand = new Command() { - private static final long serialVersionUID = 5612348769167529102L; - - @Override - public void execute() { - game.getAction().sacrifice(c, null); - } - }; - - final Command paidCommand = Command.BLANK; - final Ability blankAbility = Upkeep.BlankAbility(c, upkeepCost); blankAbility.setActivatingPlayer(controller); @@ -351,11 +329,11 @@ public class Upkeep extends Phase { @Override public void resolve() { if (controller.isHuman()) { - GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(), - paidCommand, unpaidCommand, this, game); + if ( !GameActionUtil.payCostDuringAbilityResolve(controller, blankAbility, blankAbility.getPayCosts(), this, game)) + game.getAction().sacrifice(c, null); } else { // computer if (ComputerUtilCost.shouldPayCost(controller, c, upkeepCost) && ComputerUtilCost.canPayCost(blankAbility, controller)) { - ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game); + ComputerUtil.playNoStack((AIPlayer)controller, blankAbility, game); // this makes AI pay } else { game.getAction().sacrifice(c, null); }