widely changed costs, not tested

This commit is contained in:
Maxmtg
2013-03-25 23:44:11 +00:00
parent 18e59f30a5
commit 9fc0c5c508
25 changed files with 485 additions and 329 deletions

View File

@@ -19,7 +19,6 @@
package forge.card.ability.ai; package forge.card.ability.ai;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Random; import java.util.Random;
import forge.Card; import forge.Card;
@@ -72,8 +71,7 @@ public class DrawAi extends SpellAbilityAi {
if (part instanceof CostDiscard) { if (part instanceof CostDiscard) {
CostDiscard cd = (CostDiscard) part; CostDiscard cd = (CostDiscard) part;
cd.decideAIPayment((AIPlayer) ai, sa, sa.getSourceCard(), null); cd.decideAIPayment((AIPlayer) ai, sa, sa.getSourceCard(), null);
List<Card> discards = cd.getList(); for (Card discard : cd.getList()) {
for (Card discard : discards) {
if (!ComputerUtil.isWorseThanDraw(ai, discard)) { if (!ComputerUtil.isWorseThanDraw(ai, discard)) {
return false; return false;
} }

View File

@@ -103,10 +103,11 @@ public class CostDamage extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final int life = activator.getLife(); final int life = activator.getLife();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
if (c == null) { if (c == null) {
@@ -124,10 +125,10 @@ public class CostDamage extends CostPart {
if (GuiDialog.confirm(source, sb.toString()) && activator.canPayLife(c)) { if (GuiDialog.confirm(source, sb.toString()) && activator.canPayLife(c)) {
activator.addDamage(c, source); activator.addDamage(c, source);
this.setLastPaidAmount(c);
} else { } else {
payment.setCancel(true); return false;
} }
return true;
} }
/* /*

View File

@@ -28,6 +28,7 @@ import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
@@ -56,6 +57,7 @@ public class CostDiscard extends CostPartWithList {
private static final long serialVersionUID = -329993322080934435L; private static final long serialVersionUID = -329993322080934435L;
private int nDiscard = 0; private int nDiscard = 0;
private boolean sameName; private boolean sameName;
private String firstName = null;
private final SpellAbility sa; private final SpellAbility sa;
@@ -69,8 +71,7 @@ public class CostDiscard extends CostPartWithList {
* @param sp * @param sp
* @param discType * @param discType
*/ */
public InputPayCostDiscard(SpellAbility sa, List<Card> handList, CostDiscard part, CostPayment payment, int nNeeded, String discType) { public InputPayCostDiscard(SpellAbility sa, List<Card> handList, CostDiscard part, int nNeeded, String discType) {
super(payment);
this.sa = sa; this.sa = sa;
this.handList = handList; this.handList = handList;
this.part = part; this.part = part;
@@ -111,18 +112,18 @@ public class CostDiscard extends CostPartWithList {
public void selectCard(final Card card) { public void selectCard(final Card card) {
Zone zone = Singletons.getModel().getGame().getZoneOf(card); Zone zone = Singletons.getModel().getGame().getZoneOf(card);
if (zone.is(ZoneType.Hand) && handList.contains(card)) { if (zone.is(ZoneType.Hand) && handList.contains(card)) {
if (!sameName || part.getList().isEmpty() if (!sameName || part.getList().isEmpty()|| firstName.equals(card.getName()) ) {
|| part.getList().get(0).getName().equals(card.getName())) { if( part.getList().isEmpty() )
firstName = card.getName();
// send in List<Card> for Typing // send in List<Card> for Typing
card.getController().discard(card, sa); part.executePayment(sa, card);
part.addToList(card);
handList.remove(card); handList.remove(card);
this.nDiscard++; this.nDiscard++;
// in case no more cards in hand // in case no more cards in hand
if (this.nDiscard == nNeeded) { if (this.nDiscard == nNeeded) {
this.done(); this.done();
} else if (sa.getActivatingPlayer().getZone(ZoneType.Hand).size() == 0) { } else if (sa.getActivatingPlayer().getZone(ZoneType.Hand).isEmpty()) {
// really // really
// shouldn't // shouldn't
// happen // happen
@@ -247,7 +248,7 @@ public class CostDiscard extends CostPartWithList {
@Override @Override
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
for (final Card c : this.getList()) { for (final Card c : this.getList()) {
ai.discard(c, ability); executePayment(ability, c);
} }
} }
@@ -259,8 +260,9 @@ public class CostDiscard extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final Card source = ability.getSourceCard();
List<Card> handList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand)); List<Card> handList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand));
String discardType = this.getType(); String discardType = this.getType();
final String amount = this.getAmount(); final String amount = this.getAmount();
@@ -268,23 +270,22 @@ public class CostDiscard extends CostPartWithList {
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
if (!handList.contains(source)) { if (!handList.contains(source)) {
payment.setCancel(true); return false;
} }
activator.discard(source, ability); executePayment(ability, source);
payment.setPaidPart(this); return true;
//this.addToList(source); //this.addToList(source);
} else if (discardType.equals("Hand")) { } else if (discardType.equals("Hand")) {
this.setList(handList); this.setList(handList);
activator.discardHand(ability); activator.discardHand(ability);
payment.setPaidPart(this); return true;
} else if (discardType.equals("LastDrawn")) { } else if (discardType.equals("LastDrawn")) {
final Card lastDrawn = activator.getLastDrawnCard(); final Card lastDrawn = activator.getLastDrawnCard();
this.addToList(lastDrawn);
if (!handList.contains(lastDrawn)) { if (!handList.contains(lastDrawn)) {
payment.setCancel(true); return false;
} }
activator.discard(lastDrawn, ability); executePayment(ability, lastDrawn);
payment.setPaidPart(this); return true;
} else { } else {
Integer c = this.convertAmount(); Integer c = this.convertAmount();
@@ -300,7 +301,7 @@ public class CostDiscard extends CostPartWithList {
} }
this.setList(activator.discardRandom(c, ability)); this.setList(activator.discardRandom(c, ability));
payment.setPaidPart(this); return true;
} else { } else {
String type = new String(discardType); String type = new String(discardType);
boolean sameName = false; boolean sameName = false;
@@ -335,11 +336,11 @@ public class CostDiscard extends CostPartWithList {
} }
} }
FThreads.setInputAndWait(new InputPayCostDiscard(ability, handList, this, payment, c, discardType)); InputPayment inp = new InputPayCostDiscard(ability, handList, this, c, discardType);
FThreads.setInputAndWait(inp);
return inp.isPaid();
} }
} }
if ( !payment.isCanceled())
this.addListToHash(ability, "Discarded");
} }
/* /*
@@ -396,6 +397,23 @@ public class CostDiscard extends CostPartWithList {
return this.getList() != null; return this.getList() != null;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
this.addToList(targetCard);
targetCard.getController().discard(targetCard, ability);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Discarded";
}
// Inputs // Inputs
} }

View File

@@ -23,15 +23,17 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CardPredicates; import forge.CardPredicates;
import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance; import forge.card.spellability.SpellAbilityStackInstance;
import forge.control.input.InputSynchronized; import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.MagicStack;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.GuiDialog; import forge.gui.GuiDialog;
@@ -65,8 +67,7 @@ public class CostExile extends CostPartWithList {
* @param payment * @param payment
* @param part * @param part
*/ */
private InputExileFrom(SpellAbility sa, String type, int nNeeded, CostPayment payment, CostExile part) { private InputExileFrom(SpellAbility sa, String type, int nNeeded, CostExile part) {
super(payment);
this.sa = sa; this.sa = sa;
this.type = type; this.type = type;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -91,8 +92,7 @@ public class CostExile extends CostPartWithList {
if (c != null) { if (c != null) {
this.typeList.remove(c); this.typeList.remove(c);
part.addToList(c); part.executePayment(sa, c);
Singletons.getModel().getGame().getAction().exile(c);
if (i == (nNeeded - 1)) { if (i == (nNeeded - 1)) {
this.done(); this.done();
} }
@@ -125,8 +125,7 @@ public class CostExile extends CostPartWithList {
* @param nNeeded * @param nNeeded
* @param payableZone * @param payableZone
*/ */
private InputExileFromSame(List<Card> list, CostExile part, CostPayment payment, int nNeeded, List<Player> payableZone) { private InputExileFromSame(List<Card> list, CostExile part, int nNeeded, List<Player> payableZone) {
super(payment);
this.list = list; this.list = list;
this.part = part; this.part = part;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -160,8 +159,7 @@ public class CostExile extends CostPartWithList {
if (c != null) { if (c != null) {
this.typeList.remove(c); this.typeList.remove(c);
part.addToList(c); part.executePayment(null, c);
Singletons.getModel().getGame().getAction().exile(c);
if (i == (nNeeded - 1)) { if (i == (nNeeded - 1)) {
this.done(); this.done();
} }
@@ -195,8 +193,7 @@ public class CostExile extends CostPartWithList {
* @param nNeeded * @param nNeeded
* @param part * @param part
*/ */
private InputExileFromStack(CostPayment payment, SpellAbility sa, String type, int nNeeded, CostExile part) { private InputExileFromStack(SpellAbility sa, String type, int nNeeded, CostExile part) {
super(payment);
this.sa = sa; this.sa = sa;
this.type = type; this.type = type;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -211,10 +208,11 @@ public class CostExile extends CostPartWithList {
saList = new ArrayList<SpellAbility>(); saList = new ArrayList<SpellAbility>();
descList = new ArrayList<String>(); descList = new ArrayList<String>();
final MagicStack stack = sa.getActivatingPlayer().getGame().getStack();
for (int i = 0; i < Singletons.getModel().getGame().getStack().size(); i++) { for (int i = 0; i < stack.size(); i++) {
final Card stC = Singletons.getModel().getGame().getStack().peekAbility(i).getSourceCard(); final Card stC = stack.peekAbility(i).getSourceCard();
final SpellAbility stSA = Singletons.getModel().getGame().getStack().peekAbility(i).getRootAbility(); final SpellAbility stSA = stack.peekAbility(i).getRootAbility();
if (stC.isValid(type.split(";"), sa.getActivatingPlayer(), sa.getSourceCard()) && stSA.isSpell()) { if (stC.isValid(type.split(";"), sa.getActivatingPlayer(), sa.getSourceCard()) && stSA.isSpell()) {
this.saList.add(stSA); this.saList.add(stSA);
if (stC.isCopiedSpell()) { if (stC.isCopiedSpell()) {
@@ -236,16 +234,19 @@ public class CostExile extends CostPartWithList {
if (o != null) { if (o != null) {
final SpellAbility toExile = this.saList.get(descList.indexOf(o)); final SpellAbility toExile = this.saList.get(descList.indexOf(o));
final Card c = toExile.getSourceCard(); final Card c = toExile.getSourceCard();
this.saList.remove(toExile); this.saList.remove(toExile);
part.addToList(c);
if (!c.isCopiedSpell()) { if (!c.isCopiedSpell()) {
Singletons.getModel().getGame().getAction().exile(c); part.executePayment(sa, c);
} } else
part.addToList(c);
if (i == (nNeeded - 1)) { if (i == (nNeeded - 1)) {
this.done(); this.done();
} }
final SpellAbilityStackInstance si = Singletons.getModel().getGame().getStack().getInstanceFromSpellAbility(toExile); final SpellAbilityStackInstance si = stack.getInstanceFromSpellAbility(toExile);
Singletons.getModel().getGame().getStack().remove(si); stack.remove(si);
} else { } else {
this.cancel(); this.cancel();
break; break;
@@ -275,8 +276,7 @@ public class CostExile extends CostPartWithList {
* @param nNeeded * @param nNeeded
* @param sa * @param sa
*/ */
private InputExileType(CostExile part, CostPayment payment, String type, int nNeeded, SpellAbility sa) { private InputExileType(CostExile part, String type, int nNeeded, SpellAbility sa) {
super(payment);
this.part = part; this.part = part;
this.type = type; this.type = type;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -312,8 +312,7 @@ public class CostExile extends CostPartWithList {
public void selectCard(final Card card) { public void selectCard(final Card card) {
if (this.typeList.contains(card)) { if (this.typeList.contains(card)) {
this.nExiles++; this.nExiles++;
part.addToList(card); part.executePayment(sa, card);
Singletons.getModel().getGame().getAction().exile(card);
this.typeList.remove(card); this.typeList.remove(card);
// in case nothing else to exile // in case nothing else to exile
if (this.nExiles == nNeeded) { if (this.nExiles == nNeeded) {
@@ -343,8 +342,7 @@ public class CostExile extends CostPartWithList {
* @param part * @param part
* @param sa * @param sa
*/ */
private InputExileThis(CostPayment payment, CostExile part, SpellAbility sa) { private InputExileThis(CostExile part, SpellAbility sa) {
super(payment);
this.part = part; this.part = part;
this.sa = sa; this.sa = sa;
} }
@@ -354,9 +352,7 @@ public class CostExile extends CostPartWithList {
if ( sa.getActivatingPlayer().getZone(part.getFrom()).contains(card)) { if ( sa.getActivatingPlayer().getZone(part.getFrom()).contains(card)) {
boolean choice = GuiDialog.confirm(card, card.getName() + " - Exile?"); boolean choice = GuiDialog.confirm(card, card.getName() + " - Exile?");
if (choice) { if (choice) {
Singletons.getModel().getGame().getAction().exile(card); part.executePayment(sa, card);
part.addToList(card);
part.addListToHash(sa, "Exiled");
done(); done();
return; return;
} }
@@ -539,8 +535,9 @@ public class CostExile extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
List<Card> list; List<Card> list;
@@ -552,11 +549,10 @@ public class CostExile extends CostPartWithList {
} }
if (this.getType().equals("All")) { if (this.getType().equals("All")) {
this.setList(list);
for (final Card card : list) { for (final Card card : list) {
Singletons.getModel().getGame().getAction().exile(card); executePayment(ability, card);
} }
payment.setPaidPart(this); return true;
} }
list = CardLists.getValidCards(list, this.getType().split(";"), activator, source); list = CardLists.getValidCards(list, this.getType().split(";"), activator, source);
if (c == null) { if (c == null) {
@@ -571,16 +567,16 @@ public class CostExile extends CostPartWithList {
} }
} }
InputSynchronized target = null; InputPayment target = null;
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
target = new InputExileThis(payment, this, ability); target = new InputExileThis(this, ability);
} else if (this.from.equals(ZoneType.Battlefield) || this.from.equals(ZoneType.Hand)) { } else if (this.from.equals(ZoneType.Battlefield) || this.from.equals(ZoneType.Hand)) {
target = new InputExileType(this, payment, this.getType(), c, ability); target = new InputExileType(this, this.getType(), c, ability);
} else if (this.from.equals(ZoneType.Stack)) { } else if (this.from.equals(ZoneType.Stack)) {
target = new InputExileFromStack(payment, ability, this.getType(), c, this); target = new InputExileFromStack(ability, this.getType(), c, this);
} else if (this.from.equals(ZoneType.Library)) { } else if (this.from.equals(ZoneType.Library)) {
// this does not create input // this does not create input
CostExile.exileFromTop(ability, this, payment, c); return exileFromTop(ability, c);
} else if (this.sameZone) { } else if (this.sameZone) {
List<Player> players = game.getPlayers(); List<Player> players = game.getPlayers();
List<Player> payableZone = new ArrayList<Player>(); List<Player> payableZone = new ArrayList<Player>();
@@ -592,13 +588,13 @@ public class CostExile extends CostPartWithList {
payableZone.add(p); payableZone.add(p);
} }
} }
target = new InputExileFromSame(list, this, payment, c, payableZone); target = new InputExileFromSame(list, this, c, payableZone);
} else { } else {
target = new InputExileFrom(ability, this.getType(), c, payment, this); target = new InputExileFrom(ability, this.getType(), c, this);
} }
target.awaitLatchRelease(); FThreads.setInputAndWait(target);
if(!payment.isCanceled()) return target.isPaid();
addListToHash(ability, "Exiled");
} }
/* /*
@@ -661,30 +657,43 @@ public class CostExile extends CostPartWithList {
* @param nNeeded * @param nNeeded
* the n needed * the n needed
*/ */
public static void exileFromTop(final SpellAbility sa, final CostExile part, final CostPayment payment, public boolean exileFromTop(final SpellAbility sa, final int nNeeded) {
final int nNeeded) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Exile ").append(nNeeded).append(" cards from the top of your library?"); sb.append("Exile ").append(nNeeded).append(" cards from the top of your library?");
final List<Card> list = sa.getActivatingPlayer().getCardsIn(ZoneType.Library, nNeeded); final List<Card> list = sa.getActivatingPlayer().getCardsIn(ZoneType.Library, nNeeded);
if (list.size() > nNeeded) { if (list.size() > nNeeded) {
// I don't believe this is possible // I don't believe this is possible
payment.cancelCost(); return false;
return;
} }
final boolean doExile = GuiDialog.confirm(sa.getSourceCard(), sb.toString()); final boolean doExile = GuiDialog.confirm(sa.getSourceCard(), sb.toString());
if (doExile) { if (doExile) {
final Iterator<Card> itr = list.iterator(); final Iterator<Card> itr = list.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
final Card c = itr.next(); executePayment(sa, itr.next());
part.addToList(c);
Singletons.getModel().getGame().getAction().exile(c);
} }
part.addListToHash(sa, "Exiled"); return true;
payment.setPaidPart(part);
} else { } else {
payment.cancelCost(); return false;
} }
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
addToList(targetCard);
ability.getActivatingPlayer().getGame().getAction().exile(targetCard);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
// TODO Auto-generated method stub
return "Exiled";
}
} }

View File

@@ -137,7 +137,8 @@ public class CostGainLife extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Card source = ability.getSourceCard();
final String amount = this.getAmount(); final String amount = this.getAmount();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final int life = activator.getLife(); final int life = activator.getLife();
@@ -172,13 +173,13 @@ public class CostGainLife extends CostPart {
for(int playersLeft = cntPlayers; playersLeft > 0; playersLeft--) { for(int playersLeft = cntPlayers; playersLeft > 0; playersLeft--) {
final Player chosenToGain = GuiChoose.oneOrNone(sb.toString(), oppsThatCanGainLife); final Player chosenToGain = GuiChoose.oneOrNone(sb.toString(), oppsThatCanGainLife);
if (null == chosenToGain) { if (null == chosenToGain) {
payment.setCancel(true); return false;
return;
} else { } else {
final Player chosen = chosenToGain; final Player chosen = chosenToGain;
chosen.gainLife(c, null); chosen.gainLife(c, null);
} }
} }
return true;
} }
/* /*

View File

@@ -126,9 +126,10 @@ public class CostMill extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
final Card source = ability.getSourceCard();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
if (c == null) { if (c == null) {
@@ -144,26 +145,22 @@ public class CostMill extends CostPartWithList {
if ((list == null) || (list.size() > c)) { if ((list == null) || (list.size() > c)) {
// I don't believe this is possible // I don't believe this is possible
payment.cancelCost(); return false;
return;
} }
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("Mill ").append(c).append(" cards from your library?"); sb.append("Mill ").append(c).append(" cards from your library?");
final boolean doMill = GuiDialog.confirm(source, sb.toString()); if ( false == GuiDialog.confirm(source, sb.toString()) )
if (doMill) { return false;
this.resetList(); this.resetList();
final Iterator<Card> itr = list.iterator(); final Iterator<Card> itr = list.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
final Card card = itr.next(); final Card card = itr.next();
this.addToList(card); executePayment(ability, card);
Singletons.getModel().getGame().getAction().moveToGraveyard(card);
}
this.addListToHash(ability, "Milled");
} else {
payment.cancelCost();
} }
return true;
} }
/* /*
@@ -192,4 +189,21 @@ public class CostMill extends CostPartWithList {
return sb.toString(); return sb.toString();
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
this.addToList(targetCard);
ability.getActivatingPlayer().getGame().getAction().moveToGraveyard(targetCard);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Milled";
}
} }

View File

@@ -200,7 +200,7 @@ public abstract class CostPart {
* @param game * @param game
* @return true, if successful * @return true, if successful
*/ */
public abstract void payHuman(SpellAbility ability, Card source, CostPayment payment, GameState game); public abstract boolean payHuman(SpellAbility ability, GameState game);
/* /*
* (non-Javadoc) * (non-Javadoc)

View File

@@ -25,6 +25,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayManaOfCostPayment; import forge.control.input.InputPayManaOfCostPayment;
import forge.control.input.InputPayManaX; import forge.control.input.InputPayManaX;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtilMana; import forge.game.ai.ComputerUtilMana;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
@@ -205,7 +206,8 @@ public class CostPartMana extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Card source = ability.getSourceCard();
int manaToAdd = 0; int manaToAdd = 0;
if (!this.hasNoXManaCost()) { if (!this.hasNoXManaCost()) {
// if X cost is a defined value, other than xPaid // if X cost is a defined value, other than xPaid
@@ -217,12 +219,19 @@ public class CostPartMana extends CostPart {
if (!"0".equals(this.getManaToPay()) || manaToAdd > 0) { if (!"0".equals(this.getManaToPay()) || manaToAdd > 0) {
FThreads.setInputAndWait(new InputPayManaOfCostPayment(game, this, ability, payment, manaToAdd)); InputPayment inpPayment = new InputPayManaOfCostPayment(game, this, ability, manaToAdd);
FThreads.setInputAndWait(inpPayment);
if(!inpPayment.isPaid())
return false;
} }
if (this.getXMana() > 0) { if (this.getXMana() > 0) {
source.setXManaCostPaid(0); source.setXManaCostPaid(0);
FThreads.setInputAndWait(new InputPayManaX(game, ability, payment, this)); InputPayment inpPayment = new InputPayManaX(game, ability, this);
FThreads.setInputAndWait(inpPayment);
if(!inpPayment.isPaid())
return false;
} }
return true;
} }

View File

@@ -17,8 +17,9 @@
*/ */
package forge.card.cost; package forge.card.cost;
import java.util.ArrayList; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import forge.Card; import forge.Card;
import forge.CardUtil; import forge.CardUtil;
@@ -30,14 +31,16 @@ import forge.card.spellability.SpellAbility;
public abstract class CostPartWithList extends CostPart { public abstract class CostPartWithList extends CostPart {
/** The list. */ /** The list. */
private List<Card> list = null; private Set<Card> list = new HashSet<Card>();
// set is here because executePayment() adds card to list, while ai's decide payment does the same thing.
// set allows to avoid duplication
/** /**
* Gets the list. * Gets the list.
* *
* @return the list * @return the list
*/ */
public final List<Card> getList() { public final Set<Card> getList() {
return this.list; return this.list;
} }
@@ -48,14 +51,15 @@ public abstract class CostPartWithList extends CostPart {
* the new list * the new list
*/ */
public final void setList(final List<Card> setList) { public final void setList(final List<Card> setList) {
this.list = setList; this.list.clear();
list.addAll(setList);
} }
/** /**
* Reset list. * Reset list.
*/ */
public final void resetList() { public final void resetList() {
this.setList(new ArrayList<Card>()); this.list.clear();
} }
/** /**
@@ -65,10 +69,7 @@ public abstract class CostPartWithList extends CostPart {
* the c * the c
*/ */
public final void addToList(final Card c) { public final void addToList(final Card c) {
if (this.getList() == null) { this.list.add(c);
this.resetList();
}
this.getList().add(c);
} }
/** /**
@@ -106,4 +107,12 @@ public abstract class CostPartWithList extends CostPart {
super(amount, type, description); super(amount, type, description);
this.resetList(); this.resetList();
} }
public abstract void executePayment(SpellAbility ability, Card targetCard);
/**
* TODO: Write javadoc for this method.
* @return
*/
public abstract String getHashForList();
} }

View File

@@ -123,7 +123,8 @@ public class CostPayLife extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Card source = ability.getSourceCard();
final String amount = this.getAmount(); final String amount = this.getAmount();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final int life = activator.getLife(); final int life = activator.getLife();
@@ -149,10 +150,10 @@ public class CostPayLife extends CostPart {
if (activator.canPayLife(c) && GuiDialog.confirm(source, sb.toString())) { if (activator.canPayLife(c) && GuiDialog.confirm(source, sb.toString())) {
activator.payLife(c, null); activator.payLife(c, null);
this.setLastPaidAmount(c);
} else { } else {
payment.setCancel(true); return false;
} }
return true;
} }
/* /*

View File

@@ -38,7 +38,6 @@ import forge.game.player.Player;
public class CostPayment { public class CostPayment {
private Cost cost = null; private Cost cost = null;
private SpellAbility ability = null; private SpellAbility ability = null;
private Card card = null;
private SpellAbilityRequirements req = null; private SpellAbilityRequirements req = null;
private boolean bCancel = false; private boolean bCancel = false;
private final ArrayList<CostPart> paidCostParts = new ArrayList<CostPart>(); private final ArrayList<CostPart> paidCostParts = new ArrayList<CostPart>();
@@ -74,7 +73,7 @@ public class CostPayment {
* @return a {@link forge.Card} object. * @return a {@link forge.Card} object.
*/ */
public final Card getCard() { public final Card getCard() {
return this.card; return this.ability.getSourceCard();
} }
/** /**
@@ -135,7 +134,6 @@ public class CostPayment {
public CostPayment(final Cost cost, final SpellAbility abil, final GameState game) { public CostPayment(final Cost cost, final SpellAbility abil, final GameState game) {
this.cost = cost; this.cost = cost;
this.ability = abil; this.ability = abil;
this.card = abil.getSourceCard();
this.game = game; this.game = game;
} }
@@ -212,9 +210,12 @@ public class CostPayment {
continue; continue;
} }
part.payHuman(this.ability, this.card, this, game); if ( false == part.payHuman(getAbility(), game) ) {
if ( isCanceled() ) return; this.setCancel(true);
return;
}
if( part instanceof CostPartWithList )
((CostPartWithList) part).addListToHash(ability, ((CostPartWithList) part).getHashForList());
setPaidPart(part); setPaidPart(part);
} }
this.resetUndoList(); this.resetUndoList();
@@ -258,7 +259,7 @@ public class CostPayment {
public final void cancelPayment() { public final void cancelPayment() {
for (final CostPart part : this.paidCostParts) { for (final CostPart part : this.paidCostParts) {
if (part.isUndoable()) { if (part.isUndoable()) {
part.refund(this.card); part.refund(this.getCard());
} }
} }

View File

@@ -21,9 +21,10 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.CounterType; import forge.CounterType;
import forge.FThreads;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputSynchronized; import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
@@ -57,8 +58,7 @@ public class CostPutCounter extends CostPartWithList {
* @param payment * @param payment
* @param sa * @param sa
*/ */
public InputPayCostPutCounter(String type, CostPutCounter costPutCounter, int nNeeded, CostPayment payment, SpellAbility sa) { public InputPayCostPutCounter(String type, CostPutCounter costPutCounter, int nNeeded, SpellAbility sa) {
super(payment);
this.type = type; this.type = type;
this.costPutCounter = costPutCounter; this.costPutCounter = costPutCounter;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -90,9 +90,7 @@ public class CostPutCounter extends CostPartWithList {
public void selectCard(final Card card) { public void selectCard(final Card card) {
if (this.typeList.contains(card)) { if (this.typeList.contains(card)) {
this.nPut++; this.nPut++;
costPutCounter.addToList(card); costPutCounter.executePayment(sa, card);
card.addCounter(costPutCounter.getCounter(), 1, false);
if (nNeeded == this.nPut) { if (nNeeded == this.nPut) {
this.done(); this.done();
} else { } else {
@@ -220,17 +218,14 @@ public class CostPutCounter extends CostPartWithList {
*/ */
@Override @Override
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
Integer c = this.convertAmount(); Integer c = getNumberOfCounters(ability);
if (c == null) {
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
}
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
source.addCounter(this.getCounter(), c, false); executePayment(ability, source, c);
} else { } else {
// Put counter on chosen card // Put counter on chosen card
for (final Card card : this.getList()) { for (final Card card : this.getList()) {
card.addCounter(this.getCounter(), 1, false); executePayment(ability, card);
} }
} }
} }
@@ -243,21 +238,26 @@ public class CostPutCounter extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
Integer c = this.convertAmount(); final Card source = ability.getSourceCard();
if (c == null) { Integer c = getNumberOfCounters(ability);
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
}
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
source.addCounter(this.getCounter(), c, false); executePayment(ability, source, c);
this.addToList(source); return true;
} else { } else {
InputSynchronized inp = new InputPayCostPutCounter(this.getType(), this, c, payment, ability); InputPayment inp = new InputPayCostPutCounter(this.getType(), this, c, ability);
inp.awaitLatchRelease(); FThreads.setInputAndWait(inp);
return inp.isPaid();
} }
if ( !payment.isCanceled()) }
addListToHash(ability, "CounterPut");
private Integer getNumberOfCounters(final SpellAbility ability) {
Integer c = this.convertAmount();
if (c == null) {
c = AbilityUtils.calculateAmount(ability.getSourceCard(), this.getAmount(), ability);
}
return c;
} }
/* /*
@@ -274,13 +274,7 @@ public class CostPutCounter extends CostPartWithList {
this.addToList(source); this.addToList(source);
return true; return true;
} else { } else {
Integer c = this.convertAmount(); final List<Card> typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source);
if (c == null) {
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
}
final List<Card> typeList =
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source);
Card card = null; Card card = null;
if (this.getType().equals("Creature.YouCtrl")) { if (this.getType().equals("Creature.YouCtrl")) {
@@ -292,4 +286,23 @@ public class CostPutCounter extends CostPartWithList {
} }
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard){
executePayment(ability, targetCard, 1);
}
public void executePayment(SpellAbility ability, Card targetCard, int c) {
targetCard.addCounter(this.getCounter(), c, false);
this.addToList(targetCard);
}
@Override
public String getHashForList() {
return "CounterPut";
}
} }

View File

@@ -25,7 +25,7 @@ import forge.CounterType;
import forge.FThreads; import forge.FThreads;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputSynchronized; import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
@@ -66,8 +66,7 @@ public class CostRemoveCounter extends CostPartWithList {
* @param type * @param type
* @param costRemoveCounter * @param costRemoveCounter
*/ */
public InputPayCostRemoveCounterType(CostPayment payment, int nNeeded, SpellAbility sa, String type, CostRemoveCounter costRemoveCounter) { public InputPayCostRemoveCounterType(int nNeeded, SpellAbility sa, String type, CostRemoveCounter costRemoveCounter) {
super(payment);
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
this.sa = sa; this.sa = sa;
this.type = type; this.type = type;
@@ -99,8 +98,7 @@ public class CostRemoveCounter extends CostPartWithList {
if (this.typeList.contains(card)) { if (this.typeList.contains(card)) {
if (card.getCounters(costRemoveCounter.getCounter()) > 0) { if (card.getCounters(costRemoveCounter.getCounter()) > 0) {
this.nRemove++; this.nRemove++;
costRemoveCounter.addToList(card); costRemoveCounter.executePayment(sa, card);
card.subtractCounter(costRemoveCounter.getCounter(), 1);
if (nNeeded == this.nRemove) { if (nNeeded == this.nRemove) {
this.done(); this.done();
@@ -133,9 +131,8 @@ public class CostRemoveCounter extends CostPartWithList {
* @param nNeeded * @param nNeeded
* @param payment * @param payment
*/ */
public InputPayCostRemoveCounterFrom(CostRemoveCounter costRemoveCounter, String type, SpellAbility sa, public InputPayCostRemoveCounterFrom(CostRemoveCounter costRemoveCounter, String type, SpellAbility sa, int nNeeded) {
int nNeeded, CostPayment payment) {
super(payment);
this.costRemoveCounter = costRemoveCounter; this.costRemoveCounter = costRemoveCounter;
this.type = type; this.type = type;
this.sa = sa; this.sa = sa;
@@ -153,20 +150,18 @@ public class CostRemoveCounter extends CostPartWithList {
this.typeList = CardLists.getValidCards(this.typeList, type.split(";"), sa.getActivatingPlayer(), sa.getSourceCard()); this.typeList = CardLists.getValidCards(this.typeList, type.split(";"), sa.getActivatingPlayer(), sa.getSourceCard());
for (int i = 0; i < nNeeded; i++) { for (int i = 0; i < nNeeded; i++) {
if (this.typeList.size() == 0) { if (this.typeList.isEmpty()) {
this.cancel(); this.cancel();
} }
final Card o = GuiChoose final Card o = GuiChoose.oneOrNone("Remove counter(s) from a card in " + costRemoveCounter.getZone(), this.typeList);
.oneOrNone("Remove counter(s) from a card in " + costRemoveCounter.getZone(), this.typeList);
if (o != null) { if (o != null) {
final Card card = o; final Card card = o;
if (card.getCounters(costRemoveCounter.getCounter()) > 0) { if (card.getCounters(costRemoveCounter.getCounter()) > 0) {
this.nRemove++; this.nRemove++;
costRemoveCounter.addToList(card); costRemoveCounter.executePayment(sa, card);
card.subtractCounter(costRemoveCounter.getCounter(), 1);
if (card.getCounters(costRemoveCounter.getCounter()) == 0) { if (card.getCounters(costRemoveCounter.getCounter()) == 0) {
this.typeList.remove(card); this.typeList.remove(card);
@@ -361,8 +356,9 @@ public class CostRemoveCounter extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
int maxCounters = 0; int maxCounters = 0;
@@ -377,16 +373,14 @@ public class CostRemoveCounter extends CostPartWithList {
} }
} }
final InputSynchronized inp; final InputPayment inp;
if (this.getZone().equals(ZoneType.Battlefield)) { if (this.getZone().equals(ZoneType.Battlefield)) {
inp = new InputPayCostRemoveCounterType(payment, c, ability, this.getType(), this); inp = new InputPayCostRemoveCounterType(c, ability, this.getType(), this);
} else { } else {
inp = new InputPayCostRemoveCounterFrom(this, this.getType(), ability, c, payment); inp = new InputPayCostRemoveCounterFrom(this, this.getType(), ability, c);
} }
FThreads.setInputAndWait(inp); FThreads.setInputAndWait(inp);
if ( !payment.isCanceled() ) return inp.isPaid();
addListToHash(ability, "CounterRemove");
return;
} }
maxCounters = source.getCounters(this.counter); maxCounters = source.getCounters(this.counter);
@@ -404,14 +398,13 @@ public class CostRemoveCounter extends CostPartWithList {
} }
} }
if (maxCounters >= c) { if (maxCounters < c) return false;
this.addToList(source); this.addToList(source);
source.setSVar("CostCountersRemoved", "Number$" + Integer.toString(c)); source.setSVar("CostCountersRemoved", "Number$" + Integer.toString(c));
source.subtractCounter(this.counter, c); executePayment(ability, source, c);
this.setLastPaidAmount(c); return true;
} else {
payment.setCancel(true);
}
} }
/* /*
@@ -457,4 +450,24 @@ public class CostRemoveCounter extends CostPartWithList {
} }
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
executePayment(ability, targetCard, 1);
}
public void executePayment(SpellAbility ability, Card targetCard, int n) {
addToList(targetCard);
targetCard.subtractCounter(getCounter(), n);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "CounterRemove";
}
} }

View File

@@ -22,7 +22,6 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.FThreads; import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards; import forge.control.input.InputSelectCards;
@@ -121,7 +120,7 @@ public class CostReturn extends CostPartWithList {
@Override @Override
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
for (final Card c : this.getList()) { for (final Card c : this.getList()) {
Singletons.getModel().getGame().getAction().moveToHand(c); executePayment(ability, c);
} }
} }
@@ -133,8 +132,9 @@ public class CostReturn extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final List<Card> list = activator.getCardsIn(ZoneType.Battlefield); final List<Card> list = activator.getCardsIn(ZoneType.Battlefield);
@@ -152,27 +152,24 @@ public class CostReturn extends CostPartWithList {
if (card.getController() == ability.getActivatingPlayer() && card.isInPlay()) { if (card.getController() == ability.getActivatingPlayer() && card.isInPlay()) {
boolean confirm = GuiDialog.confirm(card, card.getName() + " - Return to Hand?"); boolean confirm = GuiDialog.confirm(card, card.getName() + " - Return to Hand?");
if (confirm) { if (confirm) {
addToList(card); executePayment(ability, card);
game.getAction().moveToHand(card);
} else {
payment.cancelCost();
} }
return confirm;
} }
} else { } else {
List<Card> validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard()); List<Card> validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
InputSelectCards inp = new InputSelectCardsFromList(c, c, validCards); InputSelectCards inp = new InputSelectCardsFromList(c, c, validCards);
inp.setMessage("Return %d " + this.getType() + " card(s) to hand"); inp.setMessage("Return %d " + this.getType() + " " + this.getType() + " card(s) to hand");
FThreads.setInputAndWait(inp); FThreads.setInputAndWait(inp);
if (inp.hasCancelled()) if (inp.hasCancelled())
payment.setCancel(true); return false;
else
for(Card crd : inp.getSelected())
game.getAction().moveToHand(crd);
}
if (!payment.isCanceled()) for(Card crd : inp.getSelected())
addListToHash(ability, "Returned"); executePayment(ability, crd);
return true;
}
return false;
} }
/* /*
@@ -194,13 +191,30 @@ public class CostReturn extends CostPartWithList {
} }
this.setList(ComputerUtil.chooseReturnType(ai, this.getType(), source, ability.getTargetCard(), c)); this.setList(ComputerUtil.chooseReturnType(ai, this.getType(), source, ability.getTargetCard(), c));
if (this.getList() == null) { if (this.getList().isEmpty()) {
return false; return false;
} }
} }
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
addToList(targetCard);
ability.getActivatingPlayer().getGame().getAction().moveToHand(targetCard);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Returned";
}
// Inputs // Inputs

View File

@@ -25,13 +25,13 @@ import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
/** /**
@@ -63,9 +63,7 @@ public class CostReveal extends CostPartWithList {
* @param payment * @param payment
* @param nNeeded * @param nNeeded
*/ */
public InputPayReveal(CostReveal part, String discType, List<Card> handList, SpellAbility sa, public InputPayReveal(CostReveal part, String discType, List<Card> handList, SpellAbility sa, int nNeeded) {
CostPayment payment, int nNeeded) {
super(payment);
this.part = part; this.part = part;
this.discType = discType; this.discType = discType;
this.handList = handList; this.handList = handList;
@@ -95,7 +93,7 @@ public class CostReveal extends CostPartWithList {
sb.append(nNeeded - this.nReveal); sb.append(nNeeded - this.nReveal);
sb.append(" remaining."); sb.append(" remaining.");
} }
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString()); showMessage(sb.toString());
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
} }
@@ -105,7 +103,7 @@ public class CostReveal extends CostPartWithList {
if (zone.is(ZoneType.Hand) && handList.contains(card)) { if (zone.is(ZoneType.Hand) && handList.contains(card)) {
// send in List<Card> for Typing // send in List<Card> for Typing
handList.remove(card); handList.remove(card);
part.addToList(card); part.executePayment(sa, card);
this.nReveal++; this.nReveal++;
// in case no more cards in hand // in case no more cards in hand
@@ -222,6 +220,8 @@ public class CostReveal extends CostPartWithList {
@Override @Override
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
GuiChoose.oneOrNone("Revealed cards:", this.getList()); GuiChoose.oneOrNone("Revealed cards:", this.getList());
for(Card c: getList()) // should not throw concurrent modification here - no items should be added.
executePayment(ability, c);
} }
/* /*
@@ -232,15 +232,19 @@ public class CostReveal extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
final Card source = ability.getSourceCard();
final String amount = this.getAmount(); final String amount = this.getAmount();
this.resetList(); this.resetList();
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
this.addToList(source); executePayment(ability, source);
return true;
} else if (this.getType().equals("Hand")) { } else if (this.getType().equals("Hand")) {
this.setList(new ArrayList<Card>(activator.getCardsIn(ZoneType.Hand))); for(Card c : activator.getCardsIn(ZoneType.Hand))
executePayment(ability, c);
return true;
} else { } else {
Integer num = this.convertAmount(); Integer num = this.convertAmount();
@@ -255,13 +259,13 @@ public class CostReveal extends CostPartWithList {
num = AbilityUtils.calculateAmount(source, amount, ability); num = AbilityUtils.calculateAmount(source, amount, ability);
} }
} }
if (num > 0) { if ( num == 0 ) return true;
FThreads.setInputAndWait(new InputPayReveal(this, this.getType(), handList, ability, payment, num));
InputPayment inp = new InputPayReveal(this, this.getType(), handList, ability, num);
FThreads.setInputAndWait(inp);
return inp.isPaid();
} }
} }
if ( !payment.isCanceled())
this.addListToHash(ability, "Revealed");
}
/* /*
* (non-Javadoc) * (non-Javadoc)
@@ -296,6 +300,23 @@ public class CostReveal extends CostPartWithList {
return sb.toString(); return sb.toString();
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
addToList(targetCard);
// write code to actually reveal card
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Revealed";
}
// Inputs // Inputs

View File

@@ -22,9 +22,9 @@ import java.util.List;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.FThreads; import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
@@ -59,9 +59,7 @@ public class CostSacrifice extends CostPartWithList {
* @param payment * @param payment
* @param typeList * @param typeList
*/ */
public InputPayCostSacrificeFromList(CostSacrifice part, SpellAbility sa, int nNeeded, CostPayment payment, public InputPayCostSacrificeFromList(CostSacrifice part, SpellAbility sa, int nNeeded, List<Card> typeList) {
List<Card> typeList) {
super(payment);
this.part = part; this.part = part;
this.sa = sa; this.sa = sa;
this.nNeeded = nNeeded; this.nNeeded = nNeeded;
@@ -90,13 +88,12 @@ public class CostSacrifice extends CostPartWithList {
public void selectCard(final Card card) { public void selectCard(final Card card) {
if (typeList.contains(card)) { if (typeList.contains(card)) {
this.nSacrifices++; this.nSacrifices++;
part.addToList(card); part.executePayment(sa, card);
Singletons.getModel().getGame().getAction().sacrifice(card, sa);
typeList.remove(card); typeList.remove(card);
// in case nothing else to sacrifice // in case nothing else to sacrifice
if (this.nSacrifices == nNeeded) { if (this.nSacrifices == nNeeded) {
this.done(); this.done();
} else if (typeList.size() == 0) { } else if (typeList.isEmpty()) {
// happen // happen
this.cancel(); this.cancel();
} else { } else {
@@ -197,7 +194,7 @@ public class CostSacrifice extends CostPartWithList {
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
this.addListToHash(ability, "Sacrificed"); this.addListToHash(ability, "Sacrificed");
for (final Card c : this.getList()) { for (final Card c : this.getList()) {
Singletons.getModel().getGame().getAction().sacrifice(c, ability); executePayment(ability, c);
} }
} }
@@ -209,8 +206,9 @@ public class CostSacrifice extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard();
final String type = this.getType(); final String type = this.getType();
final Player activator = ability.getActivatingPlayer(); final Player activator = ability.getActivatingPlayer();
List<Card> list = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield)); List<Card> list = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
@@ -220,22 +218,19 @@ public class CostSacrifice extends CostPartWithList {
} }
if (this.payCostFromSource()) { if (this.payCostFromSource()) {
final Card card = ability.getSourceCard(); if (source.getController() == ability.getActivatingPlayer() && source.isInPlay()) {
if (card.getController() == ability.getActivatingPlayer() && card.isInPlay()) { if (!GuiDialog.confirm(source, source.getName() + " - Sacrifice?"))
if (GuiDialog.confirm(card, card.getName() + " - Sacrifice?")) { return false;
this.addToList(card); executePayment(ability, source);
Singletons.getModel().getGame().getAction().sacrifice(card, ability); return true;
} else {
payment.cancelCost();
}
} }
} else if (amount.equals("All")) { } else if (amount.equals("All")) {
this.setList(list); this.setList(list);
// TODO Ask First // TODO Ask First
for (final Card card : list) { for (final Card card : list) {
payment.getAbility().addCostToHashList(card, "Sacrificed"); executePayment(ability, card);
Singletons.getModel().getGame().getAction().sacrifice(card, ability);
} }
return true;
} else { } else {
Integer c = this.convertAmount(); Integer c = this.convertAmount();
if (c == null) { if (c == null) {
@@ -247,13 +242,13 @@ public class CostSacrifice extends CostPartWithList {
} }
} }
if (0 == c.intValue()) { if (0 == c.intValue()) {
return; return true;
} }
FThreads.setInputAndWait(new InputPayCostSacrificeFromList(this, ability, c, payment, list)); InputPayment inp = new InputPayCostSacrificeFromList(this, ability, c, list);
FThreads.setInputAndWait(inp);
return inp.isPaid();
} }
return false;
if( !payment.isCanceled())
addListToHash(ability, "Sacrificed");
} }
/* /*
@@ -294,6 +289,23 @@ public class CostSacrifice extends CostPartWithList {
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
this.addToList(targetCard);
ability.getActivatingPlayer().getGame().getAction().sacrifice(targetCard, ability);
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Sacrificed";
}
// Inputs // Inputs
} }

View File

@@ -93,12 +93,13 @@ public class CostTap extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
// if (!canPay(ability, source, ability.getActivatingPlayer(), // if (!canPay(ability, source, ability.getActivatingPlayer(),
// payment.getCost())) // payment.getCost()))
// return false; // return false;
source.tap(); ability.getSourceCard().tap();
return true;
} }
/* /*

View File

@@ -26,13 +26,13 @@ import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
/** /**
@@ -59,8 +59,7 @@ public class CostTapType extends CostPartWithList {
* @param cardList * @param cardList
* @param payment * @param payment
*/ */
public InputPayCostTapType(CostTapType tapType, int nCards, List<Card> cardList, CostPayment payment) { public InputPayCostTapType(CostTapType tapType, int nCards, List<Card> cardList) {
super(payment);
this.tapType = tapType; this.tapType = tapType;
this.nCards = nCards; this.nCards = nCards;
this.cardList = cardList; this.cardList = cardList;
@@ -70,8 +69,7 @@ public class CostTapType extends CostPartWithList {
public void showMessage() { public void showMessage() {
final int left = nCards - this.nTapped; final int left = nCards - this.nTapped;
CMatchUI.SINGLETON_INSTANCE showMessage("Select a " + tapType.getDescription() + " to tap (" + left + " left)");
.showMessage("Select a " + tapType.getDescription() + " to tap (" + left + " left)");
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
if (nCards == 0) { if (nCards == 0) {
this.done(); this.done();
@@ -85,8 +83,7 @@ public class CostTapType extends CostPartWithList {
Zone zone = Singletons.getModel().getGame().getZoneOf(card); Zone zone = Singletons.getModel().getGame().getZoneOf(card);
if (zone.is(ZoneType.Battlefield) && cardList.contains(card) && card.isUntapped()) { if (zone.is(ZoneType.Battlefield) && cardList.contains(card) && card.isUntapped()) {
// send in List<Card> for Typing // send in List<Card> for Typing
card.tap(); tapType.executePayment(null, card);
tapType.addToList(card);
cardList.remove(card); cardList.remove(card);
this.nTapped++; this.nTapped++;
@@ -211,11 +208,12 @@ public class CostTapType extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
List<Card> typeList = new ArrayList<Card>(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield)); List<Card> typeList = new ArrayList<Card>(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield));
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard()); typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
typeList = CardLists.filter(typeList, Presets.UNTAPPED); typeList = CardLists.filter(typeList, Presets.UNTAPPED);
final String amount = this.getAmount(); final String amount = this.getAmount();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount(); Integer c = this.convertAmount();
if (c == null) { if (c == null) {
final String sVar = ability.getSVar(amount); final String sVar = ability.getSVar(amount);
@@ -226,9 +224,9 @@ public class CostTapType extends CostPartWithList {
c = AbilityUtils.calculateAmount(source, amount, ability); c = AbilityUtils.calculateAmount(source, amount, ability);
} }
} }
FThreads.setInputAndWait(new InputPayCostTapType(this, c, typeList, payment)); InputPayment inp = new InputPayCostTapType(this, c, typeList);
if( !payment.isCanceled()) FThreads.setInputAndWait(inp);
addListToHash(ability, "Tapped"); return inp.isPaid();
} }
/* /*
@@ -266,6 +264,23 @@ public class CostTapType extends CostPartWithList {
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
addToList(targetCard);
targetCard.tap();
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Tapped";
}
// Inputs // Inputs
} }

View File

@@ -114,17 +114,15 @@ public class CostUnattach extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
this.resetList(); final Card source = ability.getSourceCard();
Player activator = ability.getActivatingPlayer(); Player activator = ability.getActivatingPlayer();
Card cardToUnattach = findCardToUnattach(source, activator, ability); Card cardToUnattach = findCardToUnattach(source, activator, ability);
if (cardToUnattach != null && GuiDialog.confirm(source, String.format("Unattach %s?", cardToUnattach.toString()))) { if (cardToUnattach != null && GuiDialog.confirm(source, String.format("Unattach %s?", cardToUnattach.toString()))) {
Card equippingCard = cardToUnattach.getEquipping().get(0); executePayment(ability, cardToUnattach);
cardToUnattach.unEquipCard(equippingCard); return true;
this.addToList(cardToUnattach);
this.addListToHash(ability, "Unattached");
} else { } else {
payment.setCancel(true); return false;
} }
} }
@@ -160,4 +158,18 @@ public class CostUnattach extends CostPartWithList {
this.resetList(); this.resetList();
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
targetCard.unEquipCard(targetCard.getEquipping().get(0));
this.addToList(targetCard);
}
@Override
public String getHashForList() {
return "Unattached";
}
} }

View File

@@ -92,12 +92,13 @@ public class CostUntap extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
// if (!canPay(ability, source, ability.getActivatingPlayer(), // if (!canPay(ability, source, ability.getActivatingPlayer(),
// payment.getCost())) // payment.getCost()))
// return false; // return false;
source.untap(); ability.getSourceCard().untap();
return true;
} }
/* /*

View File

@@ -25,13 +25,13 @@ import forge.FThreads;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState; import forge.game.GameState;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer; import forge.game.player.AIPlayer;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
/** /**
@@ -59,8 +59,7 @@ public class CostUntapType extends CostPartWithList {
* @param sa * @param sa
* @param payment * @param payment
*/ */
public InputPayCostUntapY(int nCards, List<Card> cardList, CostUntapType untapType, CostPayment payment) { public InputPayCostUntapY(int nCards, List<Card> cardList, CostUntapType untapType) {
super(payment);
this.nCards = nCards; this.nCards = nCards;
this.cardList = cardList; this.cardList = cardList;
this.untapType = untapType; this.untapType = untapType;
@@ -77,8 +76,7 @@ public class CostUntapType extends CostPartWithList {
} }
final int left = nCards - this.nUntapped; final int left = nCards - this.nUntapped;
CMatchUI.SINGLETON_INSTANCE showMessage("Select a " + untapType.getDescription() + " to untap (" + left + " left)");
.showMessage("Select a " + untapType.getDescription() + " to untap (" + left + " left)");
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
} }
@@ -228,12 +226,13 @@ public class CostUntapType extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment) * forge.Card, forge.card.cost.Cost_Payment)
*/ */
@Override @Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) { public final boolean payHuman(final SpellAbility ability, final GameState game) {
final boolean untap = payment.getCost().hasUntapCost(); final boolean canUntapSource = false; // payment.getCost().hasUntapCost(); - only Crackleburr uses this
List<Card> typeList = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield); List<Card> typeList = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard()); typeList = CardLists.getValidCards(typeList, this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
typeList = CardLists.filter(typeList, Presets.TAPPED); typeList = CardLists.filter(typeList, Presets.TAPPED);
if (untap) { final Card source = ability.getSourceCard();
if (canUntapSource) {
typeList.remove(source); typeList.remove(source);
} }
final String amount = this.getAmount(); final String amount = this.getAmount();
@@ -247,10 +246,9 @@ public class CostUntapType extends CostPartWithList {
c = AbilityUtils.calculateAmount(source, amount, ability); c = AbilityUtils.calculateAmount(source, amount, ability);
} }
} }
FThreads.setInputAndWait(new InputPayCostUntapY(c, typeList, this, payment)); InputPayment inp = new InputPayCostUntapY(c, typeList, this);
FThreads.setInputAndWait(inp);
if ( !payment.isCanceled() ) return inp.isPaid();
addListToHash(ability, "Untapped");
} }
/* /*
@@ -291,6 +289,23 @@ public class CostUntapType extends CostPartWithList {
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
*/
@Override
public void executePayment(SpellAbility ability, Card targetCard) {
addToList(targetCard);
targetCard.untap();
}
/* (non-Javadoc)
* @see forge.card.cost.CostPartWithList#getHashForList()
*/
@Override
public String getHashForList() {
return "Untapped";
}
// Inputs // Inputs
} }

View File

@@ -1,23 +1,15 @@
package forge.card.cost; package forge.card.cost;
import forge.control.input.InputPayment;
import forge.control.input.InputSyncronizedBase; import forge.control.input.InputSyncronizedBase;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
abstract class InputPayCostBase extends InputSyncronizedBase { abstract class InputPayCostBase extends InputSyncronizedBase implements InputPayment {
private static final long serialVersionUID = -2967434867139585579L; private static final long serialVersionUID = -2967434867139585579L;
boolean bPaid = false;
private final CostPayment payment;
/**
* TODO: Write javadoc for Constructor.
* @param cdl
* @param payment
*/
public InputPayCostBase(CostPayment payment0) {
payment = payment0;
}
@Override @Override
final public void selectButtonCancel() { final public void selectButtonCancel() {
@@ -25,11 +17,13 @@ abstract class InputPayCostBase extends InputSyncronizedBase {
} }
final protected void done() { final protected void done() {
bPaid = true;
this.stop(); this.stop();
} }
final public void cancel() { final public void cancel() {
payment.cancelCost();
this.stop(); this.stop();
} }
final public boolean isPaid() { return bPaid; }
} }

View File

@@ -28,7 +28,7 @@ import forge.gui.match.views.VMessage;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public abstract class InputPayManaBase extends InputSyncronizedBase { public abstract class InputPayManaBase extends InputSyncronizedBase implements InputPayment {
private static final long serialVersionUID = -9133423708688480255L; private static final long serialVersionUID = -9133423708688480255L;
@@ -39,9 +39,11 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
protected ManaCostBeingPaid manaCost; protected ManaCostBeingPaid manaCost;
protected final SpellAbility saPaidFor; protected final SpellAbility saPaidFor;
boolean bPaid = false;
protected InputPayManaBase(final GameState game, SpellAbility saToPayFor) { protected InputPayManaBase(final GameState game, SpellAbility saToPayFor) {
this.game = game; this.game = game;
this.whoPays = Singletons.getControl().getPlayer(); this.whoPays = saToPayFor.getActivatingPlayer();
this.saPaidFor = saToPayFor; this.saPaidFor = saToPayFor;
} }
@@ -312,6 +314,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
@Override @Override
public void run() { public void run() {
if (manaCost.isPaid()) { if (manaCost.isPaid()) {
bPaid = true;
done(); done();
} else if (Singletons.getModel().getMatch().getInput().getInput() == InputPayManaBase.this) { } else if (Singletons.getModel().getMatch().getInput().getInput() == InputPayManaBase.this) {
showMessage(); showMessage();
@@ -333,10 +336,11 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
for (final Card c : saPaidFor.getTappedForConvoke()) { for (final Card c : saPaidFor.getTappedForConvoke()) {
c.setTapped(false); c.setTapped(false);
if (!isCancelled) if (!isCancelled)
c.tap(); c.tap(); // that will tap cards with all the triggers, it's no good to call this from EDT
} }
saPaidFor.clearTappedForConvoke(); saPaidFor.clearTappedForConvoke();
} }
} }
public boolean isPaid() { return bPaid; }
} }

View File

@@ -3,45 +3,23 @@ package forge.control.input;
import forge.Card; import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.card.cost.CostPartMana; import forge.card.cost.CostPartMana;
import forge.card.cost.CostPayment;
import forge.card.mana.ManaCostBeingPaid; import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.GameState; import forge.game.GameState;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
public class InputPayManaOfCostPayment extends InputPayManaBase { public class InputPayManaOfCostPayment extends InputPayManaBase {
private final CostPartMana costMana; public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, int toAdd) {
// I would kill the one who made 2 classes like above
private final String originalManaCost;
private final int manaToAdd;
private final CostPayment payment;
public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, final CostPayment payment, int toAdd) {
super(game, spellAbility); super(game, spellAbility);
manaCost = new ManaCostBeingPaid(costMana.getManaToPay()); manaCost = new ManaCostBeingPaid(costMana.getManaToPay());
manaCost.increaseColorlessMana(toAdd); manaCost.increaseColorlessMana(toAdd);
this.costMana = costMana;
originalManaCost = costMana.getMana();
manaToAdd = toAdd;
this.payment = payment;
} }
private static final long serialVersionUID = 3467312982164195091L; private static final long serialVersionUID = 3467312982164195091L;
private int phyLifeToLose = 0; private int phyLifeToLose = 0;
private void resetManaCost() {
this.manaCost = new ManaCostBeingPaid(this.originalManaCost);
this.phyLifeToLose = 0;
}
@Override @Override
public void selectPlayer(final Player player) { public void selectPlayer(final Player player) {
if (player == whoPays) { if (player == whoPays) {
@@ -61,11 +39,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
} }
source.setColorsPaid(this.manaCost.getColorsPaid()); source.setColorsPaid(this.manaCost.getColorsPaid());
source.setSunburstValue(this.manaCost.getSunburst()); source.setSunburstValue(this.manaCost.getSunburst());
this.resetManaCost();
if (costMana.hasNoXManaCost() || (manaToAdd > 0)) {
payment.setPaidPart(costMana);
}
// If this is a spell with convoke, re-tap all creatures used for it. // If this is a spell with convoke, re-tap all creatures used for it.
// This is done to make sure Taps triggers go off at the right time // This is done to make sure Taps triggers go off at the right time
@@ -79,9 +52,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
@Override @Override
public void selectButtonCancel() { public void selectButtonCancel() {
handleConvokedCards(true); handleConvokedCards(true);
this.resetManaCost();
payment.cancelCost();
stop(); stop();
} }
@@ -89,7 +59,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
public void showMessage() { public void showMessage() {
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
final String displayMana = manaCost.toString().replace("X", "").trim(); final String displayMana = manaCost.toString().replace("X", "").trim();
CMatchUI.SINGLETON_INSTANCE.showMessage("Pay Mana Cost: " + displayMana);
final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + displayMana); final StringBuilder msg = new StringBuilder("Pay Mana Cost: " + displayMana);
if (this.phyLifeToLose > 0) { if (this.phyLifeToLose > 0) {
@@ -102,8 +71,9 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
msg.append("\n(Click on your life total to pay life for phyrexian mana.)"); msg.append("\n(Click on your life total to pay life for phyrexian mana.)");
} }
CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString()); showMessage(msg.toString());
if (manaCost.isPaid()) { if (manaCost.isPaid()) {
bPaid = true;
this.done(); this.done();
} }
} }

View File

@@ -2,7 +2,6 @@ package forge.control.input;
import forge.Card; import forge.Card;
import forge.card.cost.CostPartMana; import forge.card.cost.CostPartMana;
import forge.card.cost.CostPayment;
import forge.card.mana.ManaCostBeingPaid; import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.GameState; import forge.game.GameState;
@@ -16,14 +15,12 @@ public class InputPayManaX extends InputPayManaBase {
private final String strX; private final String strX;
private String colorsPaid; private String colorsPaid;
private final CostPartMana costMana; private final CostPartMana costMana;
private final CostPayment payment;
public InputPayManaX(final GameState game, final SpellAbility sa0, final CostPayment payment0, final CostPartMana costMana0) public InputPayManaX(final GameState game, final SpellAbility sa0, final CostPartMana costMana0)
{ {
super(game, sa0); super(game, sa0);
payment = payment0;
xPaid = 0; xPaid = 0;
colorX = saPaidFor.hasParam("XColor") ? saPaidFor.getParam("XColor") : ""; colorX = saPaidFor.hasParam("XColor") ? saPaidFor.getParam("XColor") : "";
colorsPaid = saPaidFor.getSourceCard().getColorsPaid(); colorsPaid = saPaidFor.getSourceCard().getColorsPaid();
@@ -32,12 +29,25 @@ public class InputPayManaX extends InputPayManaBase {
manaCost = new ManaCostBeingPaid(strX); manaCost = new ManaCostBeingPaid(strX);
} }
/* (non-Javadoc)
* @see forge.control.input.InputPayManaBase#isPaid()
*/
@Override @Override
public void showMessage() { public boolean isPaid() {
if (xPaid == 0 && !costMana.canXbe0() || this.colorX.equals("") && !this.manaCost.toString().equals(strX)) {
ButtonUtil.enableOnlyCancel();
// only cancel if partially paid an X value // only cancel if partially paid an X value
// or X is 0, and x can't be 0 // 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() {
if (!isPaid()) {
ButtonUtil.enableOnlyCancel();
} else { } else {
ButtonUtil.enableAllFocusOk(); ButtonUtil.enableAllFocusOk();
} }
@@ -55,6 +65,7 @@ public class InputPayManaX extends InputPayManaBase {
// selectCard // selectCard
@Override @Override
public void selectCard(final Card card) { public void selectCard(final Card card) {
// don't allow here the cards that produce only wrong colors
activateManaAbility(card, this.colorX.isEmpty() ? this.manaCost : new ManaCostBeingPaid(this.colorX)); activateManaAbility(card, this.colorX.isEmpty() ? this.manaCost : new ManaCostBeingPaid(this.colorX));
} }
@@ -72,7 +83,6 @@ public class InputPayManaX extends InputPayManaBase {
@Override @Override
public void selectButtonCancel() { public void selectButtonCancel() {
payment.cancelCost();
this.stop(); this.stop();
} }
@@ -89,10 +99,10 @@ public class InputPayManaX extends InputPayManaBase {
@Override @Override
protected void done() { protected void done() {
payment.getCard().setXManaCostPaid(this.xPaid); final Card card = saPaidFor.getSourceCard();
payment.setPaidPart(costMana); card.setXManaCostPaid(this.xPaid);
payment.getCard().setColorsPaid(this.colorsPaid); card.setColorsPaid(this.colorsPaid);
payment.getCard().setSunburstValue(this.colorsPaid.length()); card.setSunburstValue(this.colorsPaid.length());
this.stop(); this.stop();
} }
} }