diff --git a/src/main/java/forge/card/mana/ManaCostBeingPaid.java b/src/main/java/forge/card/mana/ManaCostBeingPaid.java index 9cb5a7ef730..224309c1312 100644 --- a/src/main/java/forge/card/mana/ManaCostBeingPaid.java +++ b/src/main/java/forge/card/mana/ManaCostBeingPaid.java @@ -41,6 +41,8 @@ public class ManaCostBeingPaid { private int cntX = 0; private final ArrayList manaNeededToAvoidNegativeEffect = new ArrayList(); private final ArrayList manaPaidToAvoidNegativeEffect = new ArrayList(); + + private final ManaCost originalCost; // manaCost can be like "0", "3", "G", "GW", "10", "3 GW", "10 GW" // or "split hybrid mana" like "2/G 2/G", "2/B 2/B 2/B" @@ -59,6 +61,7 @@ public class ManaCostBeingPaid { } public ManaCostBeingPaid(ManaCost manaCost) { + originalCost = manaCost; if ( null == manaCost ) return; @@ -645,4 +648,8 @@ public class ManaCostBeingPaid { public final ArrayList getManaPaidToAvoidNegativeEffect() { return this.manaPaidToAvoidNegativeEffect; } + + public ManaCost getStartingCost() { + return originalCost; + } } diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index 98b87c34c3e..e6dcffbdc54 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -88,6 +88,14 @@ public class InputControl extends MyObservable implements java.io.Serializable { */ public final void removeInput(Input inp) { Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop(); + +// StackTraceElement[] trace = Thread.currentThread().getStackTrace(); +// System.out.printf("%s > Remove input %s -- called from %s%n", FThreads.isEDT() ? "EDT" : "TRD", topMostInput, trace[2].toString()); +// if( trace[2].toString().contains("InputBase.stop")) +// for(StackTraceElement se : trace) { +// System.out.println(se.toString()); +// } + if( topMostInput != inp ) throw new RuntimeException("Inputs adding/removal into stack is imbalanced! Check your code again!"); diff --git a/src/main/java/forge/control/input/InputPayManaBase.java b/src/main/java/forge/control/input/InputPayManaBase.java index 9fd4e078434..3d452c45a29 100644 --- a/src/main/java/forge/control/input/InputPayManaBase.java +++ b/src/main/java/forge/control/input/InputPayManaBase.java @@ -9,7 +9,6 @@ import java.util.Map; import forge.Card; import forge.CardUtil; import forge.Constant; -import forge.FThreads; import forge.Singletons; import forge.card.MagicColor; import forge.card.ability.ApiType; @@ -129,7 +128,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I this.manaCost = mp.payManaFromPool(saPaidFor, manaCost, manaStr); - onManaAbilityPlayed(saPaidFor.getActivatingPlayer(), null); + onManaAbilityPlayed(null); } /** @@ -299,28 +298,30 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I // save off color needed for use by any mana and reflected mana subchosen.getManaPart().setExpressChoice(colorsNeeded); + final SpellAbility finallyChosen = chosen; // System.out.println("Chosen sa=" + chosen + " of " + chosen.getSourceCard() + " to pay mana"); Player p = chosen.getActivatingPlayer(); - p.getGame().getActionPlay().playManaAbilityAsPayment(chosen, p, this); + p.getGame().getActionPlay().playManaAbilityAsPayment(finallyChosen, p, new Runnable( ) { + @Override public void run() { + onManaAbilityPlayed(finallyChosen); + } + }); + // EDT that removes lockUI from stack will call our showMessage() method + } + + + public void onManaAbilityPlayed(final SpellAbility saPaymentSrc) { + if ( saPaymentSrc != null) // null comes when they've paid from pool + this.manaCost = whoPays.getManaPool().payManaFromAbility(saPaidFor, manaCost, saPaymentSrc); + + onManaAbilityPaid(); } - public void onManaAbilityPlayed(final Player p, final SpellAbility saPaymentSrc) { - if ( saPaymentSrc != null) // null comes when they've paid from pool - this.manaCost = p.getManaPool().payManaFromAbility(saPaidFor, manaCost, saPaymentSrc); - - onManaAbilityPaid(); - - FThreads.invokeInEDT(new Runnable( ) { - @Override - public void run() { - if (manaCost.isPaid()) { - bPaid = true; - done(); - } else if (Singletons.getModel().getMatch().getInput().getInput() == InputPayManaBase.this) { - showMessage(); - } - } - }); + protected final void checkIfAlredyPaid() { + if (manaCost.isPaid()) { + bPaid = true; + done(); + } } protected void onManaAbilityPaid() {} // some inputs overload it @@ -328,7 +329,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I @Override public String toString() { - return "PayManaBase (" + manaCost.toString() + ")"; + return String.format("PayManaBase %s (out of %s)", manaCost.toString(), manaCost.getStartingCost() ); } protected void handleConvokedCards(boolean isCancelled) { diff --git a/src/main/java/forge/control/input/InputPayManaExecuteCommands.java b/src/main/java/forge/control/input/InputPayManaExecuteCommands.java index d65f1657405..ed09164bf3d 100644 --- a/src/main/java/forge/control/input/InputPayManaExecuteCommands.java +++ b/src/main/java/forge/control/input/InputPayManaExecuteCommands.java @@ -23,7 +23,6 @@ import forge.card.mana.ManaCostBeingPaid; import forge.card.spellability.SpellAbility; import forge.game.GameState; import forge.game.player.Player; -import forge.gui.match.CMatchUI; import forge.view.ButtonUtil; //if cost is paid, Command.execute() is called @@ -174,6 +173,7 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp msg.append("\n(Click on your life total to pay life for phyrexian mana.)"); } - CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString()); + showMessage(msg.toString()); + checkIfAlredyPaid(); } } diff --git a/src/main/java/forge/control/input/InputPayManaOfCostPayment.java b/src/main/java/forge/control/input/InputPayManaOfCostPayment.java index 4d32e437216..b241ebf074a 100644 --- a/src/main/java/forge/control/input/InputPayManaOfCostPayment.java +++ b/src/main/java/forge/control/input/InputPayManaOfCostPayment.java @@ -72,9 +72,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase { } showMessage(msg.toString()); - if (manaCost.isPaid()) { - bPaid = true; - this.done(); - } + checkIfAlredyPaid(); } } diff --git a/src/main/java/forge/control/input/InputPayManaSimple.java b/src/main/java/forge/control/input/InputPayManaSimple.java index f47f65dc82e..712f0ebfe4d 100644 --- a/src/main/java/forge/control/input/InputPayManaSimple.java +++ b/src/main/java/forge/control/input/InputPayManaSimple.java @@ -23,7 +23,6 @@ import forge.card.spellability.SpellAbility; import forge.game.GameState; import forge.game.player.Player; import forge.game.zone.ZoneType; -import forge.gui.match.CMatchUI; import forge.view.ButtonUtil; //pays the cost of a card played from the player's hand @@ -133,7 +132,8 @@ public class InputPayManaSimple extends InputPayManaBase { msg.append("\n(Click on your life total to pay life for phyrexian mana.)"); } - CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString()); + // has its own variant of checkIfPaid + showMessage(msg.toString()); if (this.manaCost.isPaid() && !new ManaCostBeingPaid(this.originalManaCost).isPaid()) { this.originalCard.setSunburstValue(this.manaCost.getSunburst()); this.done(); diff --git a/src/main/java/forge/control/input/InputPayManaX.java b/src/main/java/forge/control/input/InputPayManaX.java index ca7b231b176..50bd5efce55 100644 --- a/src/main/java/forge/control/input/InputPayManaX.java +++ b/src/main/java/forge/control/input/InputPayManaX.java @@ -5,7 +5,6 @@ import forge.card.cost.CostPartMana; import forge.card.mana.ManaCostBeingPaid; import forge.card.spellability.SpellAbility; import forge.game.GameState; -import forge.gui.match.CMatchUI; import forge.view.ButtonUtil; public class InputPayManaX extends InputPayManaBase { @@ -34,18 +33,15 @@ public class InputPayManaX extends InputPayManaBase { */ @Override public boolean isPaid() { - // only cancel if partially paid an X value - // or X is 0, and x can't be 0 - - //return !( xPaid == 0 && !costMana.canXbe0() || this.colorX.equals("") && !this.manaCost.toString().equals(strX) ); // return !( xPaid == 0 && !costMana.canXbe0()) && !(this.colorX.equals("") && !this.manaCost.toString().equals(strX)); - return ( xPaid > 0 || costMana.canXbe0()) && (!this.colorX.equals("") || this.manaCost.toString().equals(strX)); } @Override public void showMessage() { + // only cancel if partially paid an X value + // or X is 0, and x can't be 0 if (!isPaid()) { ButtonUtil.enableOnlyCancel(); } else { @@ -59,7 +55,7 @@ public class InputPayManaX extends InputPayManaBase { msg.append(" X Can't be 0."); } - CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString()); + showMessage(msg.toString()); } // selectCard diff --git a/src/main/java/forge/game/GameActionPlay.java b/src/main/java/forge/game/GameActionPlay.java index c9b7eaa1f5d..220821cf1cd 100644 --- a/src/main/java/forge/game/GameActionPlay.java +++ b/src/main/java/forge/game/GameActionPlay.java @@ -23,7 +23,6 @@ import forge.card.spellability.SpellAbilityRequirements; import forge.card.spellability.Target; import forge.card.spellability.TargetSelection; import forge.card.staticability.StaticAbility; -import forge.control.input.InputPayManaBase; import forge.control.input.InputPayManaSimple; import forge.game.ai.ComputerUtilCard; import forge.game.player.Player; @@ -518,14 +517,14 @@ public class GameActionPlay { * @param manaCost * @param saPaidFor */ - public void playManaAbilityAsPayment(final SpellAbility chosen, final Player p, final InputPayManaBase inputPayManaBase) { + public void playManaAbilityAsPayment(final SpellAbility chosen, final Player p, final Runnable beforeUnlock) {; Runnable proc = new Runnable() { @Override public void run() { - p.getGame().getActionPlay().playSpellAbility(chosen, p); - inputPayManaBase.onManaAbilityPlayed(p, chosen); + playSpellAbility(chosen, p); + beforeUnlock.run(); } - }; + }; FThreads.invokeInNewThread(proc, true); } } diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index fa78df4e5b3..dfbcc7edb9c 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -573,7 +573,7 @@ public final class GameActionUtil { if (!((CostPartMana) part).getManaToPay().equals("0")) // non-zero costs require input dontRemove = true; } else - throw new RuntimeException("GameActionUtil.payCostDuringAbilityResolve - An unhadled type of cost has ocurred: " + part.getClass()); + throw new RuntimeException("GameActionUtil.payCostDuringAbilityResolve - An unhandled type of cost has ocurred: " + part.getClass()); if ( !hasPaid )