mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Syncronous mana payment that used to execute commands
This commit is contained in:
@@ -23,6 +23,8 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
@@ -30,8 +32,8 @@ import com.google.common.collect.Iterables;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.FThreads;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Command;
|
||||
import forge.Constant;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardType;
|
||||
@@ -461,21 +463,13 @@ public class CardFactorySorceries {
|
||||
game.getAction().moveToPlay(newArtifact[0]);
|
||||
} else {
|
||||
final String diffCost = String.valueOf(newCMC - baseCMC);
|
||||
Singletons.getModel().getMatch().getInput().setInput(new InputPayManaExecuteCommands(game, "Pay difference in artifacts CMC", diffCost, new Command() {
|
||||
private static final long serialVersionUID = -8729850321341068049L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Singletons.getModel().getGame().getAction().moveToPlay(newArtifact[0]);
|
||||
}
|
||||
}, new Command() {
|
||||
private static final long serialVersionUID = -246036834856971935L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Singletons.getModel().getGame().getAction().moveToGraveyard(newArtifact[0]);
|
||||
}
|
||||
}));
|
||||
final CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay difference in artifacts CMC", diffCost, cdl);
|
||||
FThreads.setInputAndWait(inp, cdl);
|
||||
if ( inp.isPaid() )
|
||||
Singletons.getModel().getGame().getAction().moveToPlay(newArtifact[0]);
|
||||
else
|
||||
Singletons.getModel().getGame().getAction().moveToGraveyard(newArtifact[0]);
|
||||
}
|
||||
|
||||
// finally, shuffle library
|
||||
|
||||
@@ -44,7 +44,22 @@ public final class ManaCost implements Comparable<ManaCost> {
|
||||
public static final ManaCost NO_COST = new ManaCost(-1);
|
||||
public static final ManaCost ZERO = new ManaCost(0);
|
||||
public static final ManaCost ONE = new ManaCost(1);
|
||||
public static final ManaCost TWO = new ManaCost(2);
|
||||
public static final ManaCost THREE = new ManaCost(3);
|
||||
public static final ManaCost FOUR = new ManaCost(4);
|
||||
|
||||
public static ManaCost get(int cntColorless) {
|
||||
if(cntColorless >= 5 || cntColorless < 0) throw new IllegalArgumentException("Supports only 0-4");
|
||||
switch (cntColorless) {
|
||||
case 0: return ZERO;
|
||||
case 1: return ONE;
|
||||
case 2: return TWO;
|
||||
case 3: return THREE;
|
||||
case 4: return FOUR;
|
||||
default: return NO_COST;
|
||||
}
|
||||
}
|
||||
|
||||
// pass mana cost parser here
|
||||
private ManaCost(int cmc) {
|
||||
this.hasNoCost = cmc < 0;
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
package forge.control.input;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.CostDiscard;
|
||||
@@ -42,7 +42,7 @@ import forge.view.ButtonUtil;
|
||||
* @author Forge
|
||||
* @version $Id: InputPayManaCostAbility.java 15673 2012-05-23 14:01:35Z ArsenalNut $
|
||||
*/
|
||||
public class InputPayDiscardCostWithCommands extends Input {
|
||||
public class InputPayDiscardCostWithCommands extends Input implements InputPayment {
|
||||
/**
|
||||
* Constant <code>serialVersionUID=2685832214529141991L</code>.
|
||||
*/
|
||||
@@ -53,8 +53,10 @@ public class InputPayDiscardCostWithCommands extends Input {
|
||||
private List<Card> choiceList;
|
||||
private CostDiscard discardCost;
|
||||
private SpellAbility ability;
|
||||
private Command paid;
|
||||
private Command unpaid;
|
||||
private boolean bPaid;
|
||||
|
||||
private final CountDownLatch cdlDone;
|
||||
public final boolean isPaid() { return bPaid; }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -70,19 +72,16 @@ public class InputPayDiscardCostWithCommands extends Input {
|
||||
* @param unpaidCommand
|
||||
* a {@link forge.Command} object.
|
||||
*/
|
||||
public InputPayDiscardCostWithCommands(final CostDiscard cost, final SpellAbility sa, final Command paidCommand,
|
||||
final Command unpaidCommand) {
|
||||
public InputPayDiscardCostWithCommands(final CostDiscard cost, final SpellAbility sa, final CountDownLatch cdl) {
|
||||
final Card source = sa.getSourceCard();
|
||||
final Player human = Singletons.getControl().getPlayer();
|
||||
|
||||
this.cdlDone = cdl;
|
||||
this.ability = sa;
|
||||
this.discardCost = cost;
|
||||
this.choiceList = CardLists.getValidCards(human.getCardsIn(ZoneType.Hand), cost.getType().split(";"), human, source);
|
||||
String amountString = cost.getAmount();
|
||||
this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
|
||||
: CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
||||
this.paid = paidCommand;
|
||||
this.unpaid = unpaidCommand;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -168,7 +167,10 @@ public class InputPayDiscardCostWithCommands extends Input {
|
||||
Singletons.getControl().getPlayer().discard(selected, this.ability);
|
||||
}
|
||||
this.discardCost.addListToHash(ability, "Discarded");
|
||||
this.paid.execute();
|
||||
bPaid = true;
|
||||
cdlDone.countDown();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +184,8 @@ public class InputPayDiscardCostWithCommands extends Input {
|
||||
for (Card selected : this.discardCost.getList()) {
|
||||
selected.setUsedToPay(false);
|
||||
}
|
||||
this.unpaid.execute();
|
||||
bPaid = false;
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
@Override public void isClassUpdated() {
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
package forge.control.input;
|
||||
|
||||
import forge.Command;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
@@ -36,18 +37,19 @@ import forge.view.ButtonUtil;
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
public class InputPayManaExecuteCommands extends InputPayManaBase implements InputPayment {
|
||||
/**
|
||||
* Constant <code>serialVersionUID=3836655722696348713L</code>.
|
||||
*/
|
||||
private static final long serialVersionUID = 3836655722696348713L;
|
||||
|
||||
final private CountDownLatch cdlDone;
|
||||
|
||||
private String originalManaCost;
|
||||
private String message = "";
|
||||
|
||||
|
||||
private Command paidCommand;
|
||||
private Command unpaidCommand;
|
||||
private boolean bPaid = false;
|
||||
public boolean isPaid() { return bPaid; }
|
||||
|
||||
// only used for X costs:
|
||||
private boolean showOnlyOKButton = false;
|
||||
@@ -67,8 +69,8 @@ public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
* @param unpaidCommand2
|
||||
* a {@link forge.Command} object.
|
||||
*/
|
||||
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final Command paidCommand2, final Command unpaidCommand2) {
|
||||
this(game, prompt, manaCost2, paidCommand2, unpaidCommand2, false);
|
||||
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final CountDownLatch cdl) {
|
||||
this(game, prompt, manaCost2, cdl, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +89,7 @@ public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
* @param showOKButton
|
||||
* a boolean.
|
||||
*/
|
||||
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final Command paid, final Command unpaid, final boolean showOKButton) {
|
||||
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final CountDownLatch cdl, final boolean showOKButton) {
|
||||
super(game, new SpellAbility(null) {
|
||||
@Override
|
||||
public void resolve() {}
|
||||
@@ -98,10 +100,9 @@ public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
this.originalManaCost = manaCost2;
|
||||
this.phyLifeToLose = 0;
|
||||
this.message = prompt;
|
||||
this.cdlDone = cdl;
|
||||
|
||||
this.manaCost = new ManaCostBeingPaid(this.originalManaCost);
|
||||
this.paidCommand = paid;
|
||||
this.unpaidCommand = unpaid;
|
||||
this.showOnlyOKButton = showOKButton;
|
||||
}
|
||||
|
||||
@@ -134,19 +135,22 @@ public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
if (this.phyLifeToLose > 0) {
|
||||
Singletons.getControl().getPlayer().payLife(this.phyLifeToLose, null);
|
||||
}
|
||||
this.paidCommand.execute();
|
||||
this.resetManaCost();
|
||||
Singletons.getControl().getPlayer().getManaPool().clearManaPaid(this.saPaidFor, false);
|
||||
bPaid = true;
|
||||
this.stop();
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void selectButtonCancel() {
|
||||
this.unpaidCommand.execute();
|
||||
|
||||
this.resetManaCost();
|
||||
Singletons.getControl().getPlayer().getManaPool().refundManaPaid(this.saPaidFor, true);
|
||||
bPaid = false;
|
||||
this.stop();
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -154,7 +158,9 @@ public class InputPayManaExecuteCommands extends InputPayManaBase {
|
||||
public final void selectButtonOK() {
|
||||
if (this.showOnlyOKButton) {
|
||||
this.stop();
|
||||
this.unpaidCommand.execute();
|
||||
bPaid = false;
|
||||
cdlDone.countDown();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
package forge.control.input;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.CostReturn;
|
||||
@@ -41,7 +41,7 @@ import forge.view.ButtonUtil;
|
||||
* @author Forge
|
||||
* @version $Id: InputPayManaCostAbility.java 15673 2012-05-23 14:01:35Z ArsenalNut $
|
||||
*/
|
||||
public class InputPayReturnCost extends Input {
|
||||
public class InputPayReturnCost extends Input implements InputPayment {
|
||||
/**
|
||||
* Constant <code>serialVersionUID=2685832214529141991L</code>.
|
||||
*/
|
||||
@@ -52,8 +52,11 @@ public class InputPayReturnCost extends Input {
|
||||
private List<Card> choiceList;
|
||||
private CostReturn returnCost;
|
||||
private SpellAbility ability;
|
||||
private Command paid;
|
||||
private Command unpaid;
|
||||
|
||||
private boolean bPaid;
|
||||
public boolean isPaid() { return bPaid; }
|
||||
|
||||
private final CountDownLatch cdlDone;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -69,18 +72,16 @@ public class InputPayReturnCost extends Input {
|
||||
* @param unpaidCommand
|
||||
* a {@link forge.Command} object.
|
||||
*/
|
||||
public InputPayReturnCost(final CostReturn cost, final SpellAbility sa, final Command paidCommand,
|
||||
final Command unpaidCommand) {
|
||||
public InputPayReturnCost(final CostReturn cost, final SpellAbility sa, final CountDownLatch cdl) {
|
||||
final Card source = sa.getSourceCard();
|
||||
|
||||
this.cdlDone = cdl;
|
||||
this.ability = sa;
|
||||
this.returnCost = cost;
|
||||
this.choiceList = CardLists.getValidCards(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), Singletons.getControl().getPlayer(), source);
|
||||
String amountString = cost.getAmount();
|
||||
this.numRequired = amountString.matches("[0-9][0-9]?") ? Integer.parseInt(amountString)
|
||||
: CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
||||
this.paid = paidCommand;
|
||||
this.unpaid = unpaidCommand;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -168,7 +169,8 @@ public class InputPayReturnCost extends Input {
|
||||
Singletons.getModel().getGame().getAction().moveTo(ZoneType.Hand, selected);
|
||||
}
|
||||
this.returnCost.addListToHash(ability, "Returned");
|
||||
this.paid.execute();
|
||||
bPaid = true;
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +184,8 @@ public class InputPayReturnCost extends Input {
|
||||
for (Card selected : this.returnCost.getList()) {
|
||||
selected.setUsedToPay(false);
|
||||
}
|
||||
this.unpaid.execute();
|
||||
bPaid = false;
|
||||
cdlDone.countDown();
|
||||
}
|
||||
|
||||
@Override public void isClassUpdated() {
|
||||
|
||||
5
src/main/java/forge/control/input/InputPayment.java
Normal file
5
src/main/java/forge/control/input/InputPayment.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package forge.control.input;
|
||||
|
||||
public interface InputPayment {
|
||||
boolean isPaid();
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package forge.game;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -34,6 +35,7 @@ import forge.CardUtil;
|
||||
import forge.Command;
|
||||
import forge.Constant;
|
||||
import forge.CounterType;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
@@ -61,6 +63,7 @@ import forge.control.input.Input;
|
||||
import forge.control.input.InputPayDiscardCostWithCommands;
|
||||
import forge.control.input.InputPayManaExecuteCommands;
|
||||
import forge.control.input.InputPayReturnCost;
|
||||
import forge.control.input.InputPayment;
|
||||
import forge.game.event.CardDamagedEvent;
|
||||
import forge.game.event.LifeLossEvent;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -367,31 +370,6 @@ public final class GameActionUtil {
|
||||
ripple.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* payManaDuringAbilityResolve.
|
||||
* </p>
|
||||
*
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param spellManaCost
|
||||
* a {@link java.lang.String} object.
|
||||
* @param paid
|
||||
* a {@link forge.Command} object.
|
||||
* @param unpaid
|
||||
* a {@link forge.Command} object.
|
||||
*/
|
||||
public static void payManaDuringAbilityResolve(final String message, final ManaCost spellManaCost, final Command paid,
|
||||
final Command unpaid) {
|
||||
// temporarily disable the Resolve flag, so the user can payMana for the
|
||||
// resolving Ability
|
||||
GameState game = Singletons.getModel().getGame();
|
||||
final boolean bResolving = game.getStack().isResolving();
|
||||
game.getStack().setResolving(false);
|
||||
Singletons.getModel().getMatch().getInput().setInput(new InputPayManaExecuteCommands(game, message, spellManaCost.toString(), paid, unpaid));
|
||||
game.getStack().setResolving(bResolving);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* payCostDuringAbilityResolve.
|
||||
@@ -597,25 +575,28 @@ public final class GameActionUtil {
|
||||
// interface for sacrifice costs (instead of the menu-based one above).
|
||||
|
||||
//the following costs need inputs and can't be combined at the moment
|
||||
|
||||
|
||||
Input toSet = null;
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
if (costPart instanceof CostReturn) {
|
||||
toSet = new InputPayReturnCost((CostReturn) costPart, ability, paid, unpaid);
|
||||
toSet = new InputPayReturnCost((CostReturn) costPart, ability, cdl);
|
||||
}
|
||||
else if (costPart instanceof CostDiscard) {
|
||||
toSet = new InputPayDiscardCostWithCommands((CostDiscard) costPart, ability, paid, unpaid);
|
||||
toSet = new InputPayDiscardCostWithCommands((CostDiscard) costPart, ability, cdl);
|
||||
}
|
||||
else if (costPart instanceof CostPartMana) {
|
||||
toSet = new InputPayManaExecuteCommands(game, source + "\r\n", ability.getManaCost().toString(), paid, unpaid);
|
||||
toSet = new InputPayManaExecuteCommands(game, source + "\r\n", ability.getManaCost().toString(), cdl);
|
||||
}
|
||||
|
||||
|
||||
if (toSet != null) {
|
||||
// temporarily disable the Resolve flag, so the user can payMana for the
|
||||
// resolving Ability
|
||||
final boolean bResolving = Singletons.getModel().getGame().getStack().isResolving();
|
||||
Singletons.getModel().getGame().getStack().setResolving(false);
|
||||
Singletons.getModel().getMatch().getInput().setInput(toSet);
|
||||
Singletons.getModel().getGame().getStack().setResolving(bResolving);
|
||||
|
||||
FThreads.setInputAndWait(toSet, cdl);
|
||||
if (((InputPayment)toSet).isPaid() ) {
|
||||
paid.execute();
|
||||
} else {
|
||||
unpaid.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,14 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.FThreads;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Command;
|
||||
import forge.CounterType;
|
||||
@@ -40,6 +42,7 @@ import forge.card.spellability.AbilityManaPart;
|
||||
import forge.card.spellability.AbilityStatic;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputPayManaExecuteCommands;
|
||||
import forge.control.input.InputSelectManyCards;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.GameState;
|
||||
@@ -279,44 +282,35 @@ public class Upkeep extends Phase {
|
||||
final String[] k = ability.split(" pay ");
|
||||
final ManaCost upkeepCost = new ManaCost(new ManaCostParser(k[1]));
|
||||
|
||||
final Command unpaidCommand = new Command() {
|
||||
private static final long serialVersionUID = 8942537892273123542L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (c.getName().equals("Cosmic Horror")) {
|
||||
controller.addDamage(7, c);
|
||||
}
|
||||
game.getAction().destroy(c);
|
||||
}
|
||||
};
|
||||
|
||||
final Command paidCommand = Command.BLANK;
|
||||
|
||||
final Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Upkeep for ").append(c).append("\n");
|
||||
final String sb = "Upkeep for " + c;
|
||||
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final boolean isUpkeepPaid;
|
||||
if (controller.isHuman()) {
|
||||
GameActionUtil.payManaDuringAbilityResolve(sb.toString(), upkeepCost, paidCommand, unpaidCommand);
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString(), cdl);
|
||||
FThreads.setInputAndWait(inp, cdl);
|
||||
isUpkeepPaid = inp.isPaid();
|
||||
} else { // computer
|
||||
if (ComputerUtilCost.canPayCost(aiPaid, controller) && !c.hasKeyword("Indestructible")) {
|
||||
Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
|
||||
isUpkeepPaid = ComputerUtilCost.canPayCost(aiPaid, controller) && !c.hasKeyword("Indestructible");
|
||||
if (isUpkeepPaid) {
|
||||
ComputerUtil.playNoStack((AIPlayer)controller, aiPaid, game);
|
||||
} else {
|
||||
if (c.getName().equals("Cosmic Horror")) {
|
||||
controller.addDamage(7, c);
|
||||
}
|
||||
game.getAction().destroy(c);
|
||||
}
|
||||
}
|
||||
if( !isUpkeepPaid ) {
|
||||
if (c.getName().equals("Cosmic Horror")) {
|
||||
controller.addDamage(7, c);
|
||||
}
|
||||
game.getAction().destroy(c);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
upkeepAbility.setActivatingPlayer(controller);
|
||||
upkeepAbility.setStackDescription(sb.toString());
|
||||
upkeepAbility.setDescription(sb.toString());
|
||||
upkeepAbility.setStackDescription(sb);
|
||||
upkeepAbility.setDescription(sb);
|
||||
|
||||
game.getStack().addSimultaneousStackEntry(upkeepAbility);
|
||||
} // destroy
|
||||
@@ -386,34 +380,26 @@ public class Upkeep extends Phase {
|
||||
final String[] l = k[1].split(" pay ");
|
||||
final ManaCost upkeepCost = new ManaCost(new ManaCostParser(l[1]));
|
||||
|
||||
final Command unpaidCommand = new Command() {
|
||||
private static final long serialVersionUID = 1238166187561501928L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
controller.addDamage(upkeepDamage, c);
|
||||
}
|
||||
};
|
||||
|
||||
final Command paidCommand = Command.BLANK;
|
||||
|
||||
final Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Damage upkeep for ").append(c).append("\n");
|
||||
final String sb = "Damage upkeep for " + c;
|
||||
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
boolean isUpkeepPaid = false;
|
||||
if (controller.isHuman()) {
|
||||
GameActionUtil.payManaDuringAbilityResolve(sb.toString(), upkeepCost, paidCommand, unpaidCommand);
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString(), cdl);
|
||||
FThreads.setInputAndWait(inp, cdl);
|
||||
isUpkeepPaid = inp.isPaid();
|
||||
} else { // computers
|
||||
if (ComputerUtilCost.canPayCost(aiPaid, controller)
|
||||
&& (ComputerUtilCombat.predictDamageTo(controller, upkeepDamage, c, false) > 0)) {
|
||||
final Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
|
||||
if (ComputerUtilCost.canPayCost(aiPaid, controller) && ComputerUtilCombat.predictDamageTo(controller, upkeepDamage, c, false) > 0) {
|
||||
ComputerUtil.playNoStack((AIPlayer)controller, aiPaid, game);
|
||||
} else {
|
||||
controller.addDamage(upkeepDamage, c);
|
||||
isUpkeepPaid = true;
|
||||
}
|
||||
}
|
||||
if (!isUpkeepPaid) {
|
||||
controller.addDamage(upkeepDamage, c);
|
||||
}
|
||||
}
|
||||
};
|
||||
upkeepAbility.setActivatingPlayer(controller);
|
||||
@@ -617,9 +603,7 @@ public class Upkeep extends Phase {
|
||||
final Player player = game.getPhaseHandler().getPlayerTurn();
|
||||
final List<Card> cards = player.getCardsIn(ZoneType.Battlefield, "Demonic Hordes");
|
||||
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
|
||||
final Card c = cards.get(i);
|
||||
for (final Card c : cards) {
|
||||
|
||||
final Ability cost = new Ability(c, new ManaCost(new ManaCostParser("B B B"))) {
|
||||
@Override
|
||||
@@ -627,7 +611,7 @@ public class Upkeep extends Phase {
|
||||
}
|
||||
}; // end cost ability
|
||||
|
||||
final Ability noPay = new Ability(c, ManaCost.ZERO) {
|
||||
final Ability unpaidHordesAb = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final List<Card> playerLand = player.getLandsInPlay();
|
||||
@@ -648,36 +632,25 @@ public class Upkeep extends Phase {
|
||||
|
||||
final Player cp = c.getController();
|
||||
if (cp.isHuman()) {
|
||||
final String question = "Pay Demonic Hordes upkeep cost?";
|
||||
if (GuiDialog.confirm(c, question)) {
|
||||
final Ability pay = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
|
||||
final StringBuilder coststring = new StringBuilder();
|
||||
coststring.append("Pay cost for ").append(c).append("\r\n");
|
||||
GameActionUtil.payManaDuringAbilityResolve(coststring.toString(), cost.getManaCost(),
|
||||
Command.BLANK, Command.BLANK);
|
||||
}
|
||||
} // end resolve()
|
||||
}; // end pay ability
|
||||
pay.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
pay.setDescription("Demonic Hordes - Upkeep Cost");
|
||||
final Ability pay = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay Demonic Hordes upkeep cost", cost.getManaCost().toString(), cdl/*, true */);
|
||||
FThreads.setInputAndWait(inp, cdl);
|
||||
if ( !inp.isPaid() )
|
||||
unpaidHordesAb.resolve();
|
||||
}
|
||||
} // end resolve()
|
||||
}; // end pay ability
|
||||
pay.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
pay.setDescription("Demonic Hordes - Upkeep Cost");
|
||||
|
||||
game.getStack().addSimultaneousStackEntry(pay);
|
||||
|
||||
} // end choice
|
||||
else {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(c.getName()).append(" - is tapped and you must sacrifice a land of opponent's choice");
|
||||
noPay.setStackDescription(sb.toString());
|
||||
|
||||
game.getStack().addSimultaneousStackEntry(noPay);
|
||||
|
||||
}
|
||||
game.getStack().addSimultaneousStackEntry(pay);
|
||||
} // end human
|
||||
else { // computer
|
||||
noPay.setActivatingPlayer(cp);
|
||||
unpaidHordesAb.setActivatingPlayer(cp);
|
||||
if (ComputerUtilCost.canPayCost(cost, (AIPlayer) cp)) {
|
||||
final Ability computerPay = new Ability(c, ManaCost.ZERO) {
|
||||
@Override
|
||||
@@ -689,8 +662,8 @@ public class Upkeep extends Phase {
|
||||
|
||||
game.getStack().addSimultaneousStackEntry(computerPay);
|
||||
} else {
|
||||
noPay.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
game.getStack().addSimultaneousStackEntry(noPay);
|
||||
unpaidHordesAb.setStackDescription("Demonic Hordes - Upkeep Cost");
|
||||
game.getStack().addSimultaneousStackEntry(unpaidHordesAb);
|
||||
|
||||
}
|
||||
} // end computer
|
||||
|
||||
@@ -22,12 +22,14 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.FThreads;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
@@ -36,7 +38,6 @@ import forge.card.cardfactory.CardFactory;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
import forge.card.mana.ManaCostParser;
|
||||
import forge.card.spellability.Ability;
|
||||
import forge.card.spellability.AbilityStatic;
|
||||
import forge.card.spellability.AbilityTriggered;
|
||||
@@ -478,49 +479,38 @@ public class MagicStack extends MyObservable {
|
||||
} else if (sp.isXCost()) {
|
||||
// TODO: convert any X costs to use abCost so it happens earlier
|
||||
final SpellAbility sa = sp;
|
||||
final ManaCost mc = new ManaCost( new ManaCostParser(Integer.toString(sa.getXManaCost())));
|
||||
final Ability ability = new Ability(sp.getSourceCard(), mc) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final Card crd = this.getSourceCard();
|
||||
crd.addXManaCostPaid(1);
|
||||
}
|
||||
};
|
||||
|
||||
final Command unpaidCommand = new Command() {
|
||||
private static final long serialVersionUID = -3342222770086269767L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
MagicStack.this.push(sa);
|
||||
}
|
||||
};
|
||||
|
||||
final Command paidCommand = new Command() {
|
||||
private static final long serialVersionUID = -2224875229611007788L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ability.resolve();
|
||||
final Card crd = sa.getSourceCard();
|
||||
Singletons.getModel().getMatch().getInput().setInput(
|
||||
new InputPayManaExecuteCommands(game, "Pay X cost for " + crd.getName() + " (X="
|
||||
+ crd.getXManaCostPaid() + ")\r\n", ability.getManaCost().toString(), this, unpaidCommand,
|
||||
true));
|
||||
}
|
||||
};
|
||||
|
||||
final Card crd = sa.getSourceCard();
|
||||
final int xCost = sa.getXManaCost();
|
||||
Player player = sp.getSourceCard().getController();
|
||||
if (player.isHuman()) {
|
||||
Singletons.getModel().getMatch().getInput().setInput(
|
||||
new InputPayManaExecuteCommands(game, "Pay X cost for " + sp.getSourceCard().getName() + " (X="
|
||||
+ crd.getXManaCostPaid() + ")\r\n", ability.getManaCost().toString(), paidCommand,
|
||||
unpaidCommand, true));
|
||||
final Runnable payNextX = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final Card crd = sa.getSourceCard();
|
||||
|
||||
String message = "Pay X cost for " + crd.getName() + " (X=" + crd.getXManaCostPaid() + ")\r\n";
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, message, String.valueOf(xCost), cdl, true);
|
||||
FThreads.setInputAndWait(inp, cdl);
|
||||
if ( inp.isPaid() ) {
|
||||
crd.addXManaCostPaid(1);
|
||||
this.run();
|
||||
} else
|
||||
MagicStack.this.push(sa);
|
||||
}
|
||||
};
|
||||
payNextX.run();
|
||||
} else {
|
||||
// computer
|
||||
final int neededDamage = CardFactoryUtil.getNeededXDamage(sa);
|
||||
|
||||
final Ability ability = new Ability(sp.getSourceCard(), ManaCost.get(xCost)) {
|
||||
@Override
|
||||
public void resolve() {
|
||||
final Card crd = this.getSourceCard();
|
||||
crd.addXManaCostPaid(1);
|
||||
}
|
||||
};
|
||||
|
||||
while (ComputerUtilCost.canPayCost(ability, player) && (neededDamage != sa.getSourceCard().getXManaCostPaid())) {
|
||||
ComputerUtil.playNoStack((AIPlayer)player, ability, game);
|
||||
}
|
||||
@@ -548,37 +538,44 @@ public class MagicStack extends MyObservable {
|
||||
}
|
||||
};
|
||||
|
||||
final Command paidCommand = new Command() {
|
||||
private static final long serialVersionUID = -6037161763374971106L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ability.resolve();
|
||||
|
||||
final ManaCostBeingPaid manaCost = MagicStack.this.getMultiKickerSpellCostChange(ability);
|
||||
|
||||
if (manaCost.isPaid()) {
|
||||
this.execute();
|
||||
} else {
|
||||
String prompt;
|
||||
int mkCostPaid = game.getActionPlay().getCostCuttingGetMultiKickerManaCostPaid();
|
||||
String mkCostPaidColored = game.getActionPlay().getCostCuttingGetMultiKickerManaCostPaidColored();
|
||||
int mkMagnitude = sa.getSourceCard().getMultiKickerMagnitude();
|
||||
if ((mkCostPaid == 0) && mkCostPaidColored.equals("")) {
|
||||
prompt = String.format("Multikicker for %s\r\nTimes Kicked: %d\r\n", sa.getSourceCard(), mkMagnitude );
|
||||
} else {
|
||||
prompt = String.format("Multikicker for %s\r\nMana in Reserve: %s %s\r\nTimes Kicked: %d", sa.getSourceCard(),
|
||||
(mkCostPaid != 0) ? Integer.toString(mkCostPaid) : "", mkCostPaidColored, mkMagnitude);
|
||||
}
|
||||
Input toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), this, unpaidCommand);
|
||||
Singletons.getModel().getMatch().getInput().setInput(toSet);
|
||||
}
|
||||
}
|
||||
};
|
||||
Player activating = sp.getActivatingPlayer();
|
||||
|
||||
if (activating.isHuman()) {
|
||||
sa.getSourceCard().addMultiKickerMagnitude(-1);
|
||||
final Command paidCommand = new Command() {
|
||||
private static final long serialVersionUID = -6037161763374971106L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ability.resolve();
|
||||
|
||||
final ManaCostBeingPaid manaCost = MagicStack.this.getMultiKickerSpellCostChange(ability);
|
||||
|
||||
if (manaCost.isPaid()) {
|
||||
this.execute();
|
||||
} else {
|
||||
String prompt;
|
||||
int mkCostPaid = game.getActionPlay().getCostCuttingGetMultiKickerManaCostPaid();
|
||||
String mkCostPaidColored = game.getActionPlay().getCostCuttingGetMultiKickerManaCostPaidColored();
|
||||
int mkMagnitude = sa.getSourceCard().getMultiKickerMagnitude();
|
||||
if ((mkCostPaid == 0) && mkCostPaidColored.equals("")) {
|
||||
prompt = String.format("Multikicker for %s\r\nTimes Kicked: %d\r\n", sa.getSourceCard(), mkMagnitude );
|
||||
} else {
|
||||
prompt = String.format("Multikicker for %s\r\nMana in Reserve: %s %s\r\nTimes Kicked: %d", sa.getSourceCard(),
|
||||
(mkCostPaid != 0) ? Integer.toString(mkCostPaid) : "", mkCostPaidColored, mkMagnitude);
|
||||
}
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), cdl);
|
||||
FThreads.setInputAndWait(toSet, cdl);
|
||||
if ( toSet.isPaid() ) {
|
||||
this.execute();
|
||||
} else
|
||||
unpaidCommand.execute();
|
||||
Singletons.getModel().getMatch().getInput().setInput(toSet);
|
||||
}
|
||||
}
|
||||
};
|
||||
paidCommand.execute();
|
||||
} else {
|
||||
// computer
|
||||
@@ -603,38 +600,33 @@ public class MagicStack extends MyObservable {
|
||||
}
|
||||
};
|
||||
|
||||
final Command unpaidCommand = new Command() {
|
||||
private static final long serialVersionUID = -3180458633098297855L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
for (int i = 0; i < sp.getSourceCard().getReplicateMagnitude(); i++) {
|
||||
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final Command paidCommand = new Command() {
|
||||
private static final long serialVersionUID = 132624005072267304L;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ability.resolve();
|
||||
final ManaCostBeingPaid manaCost = MagicStack.this.getReplicateSpellCostChange(ability);
|
||||
if (manaCost.isPaid()) {
|
||||
this.execute();
|
||||
} else {
|
||||
String prompt = String.format("Replicate for %s\r\nTimes Replicated: %d\r\n", sa.getSourceCard(), sa.getSourceCard().getReplicateMagnitude());
|
||||
Input toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), this, unpaidCommand);
|
||||
Singletons.getModel().getMatch().getInput().setInput(toSet);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Player controller = sp.getSourceCard().getController();
|
||||
if (controller.isHuman()) {
|
||||
sa.getSourceCard().addReplicateMagnitude(-1);
|
||||
paidCommand.execute();
|
||||
final Runnable addMagnitude = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ability.resolve();
|
||||
final ManaCostBeingPaid manaCost = MagicStack.this.getReplicateSpellCostChange(ability);
|
||||
if (manaCost.isPaid()) {
|
||||
this.run();
|
||||
} else {
|
||||
String prompt = String.format("Replicate for %s\r\nTimes Replicated: %d\r\n", sa.getSourceCard(), sa.getSourceCard().getReplicateMagnitude());
|
||||
CountDownLatch cdl = new CountDownLatch(1);
|
||||
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), cdl);
|
||||
FThreads.setInputAndWait(toSet, cdl);
|
||||
if ( toSet.isPaid() ) {
|
||||
this.run();
|
||||
} else {
|
||||
for (int i = 0; i < sp.getSourceCard().getReplicateMagnitude(); i++) {
|
||||
CardFactory.copySpellontoStack(sp.getSourceCard(), sp.getSourceCard(), sp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addMagnitude.run();
|
||||
} else {
|
||||
// computer
|
||||
while (ComputerUtilCost.canPayCost(ability, controller)) {
|
||||
|
||||
Reference in New Issue
Block a user