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

View File

@@ -103,10 +103,11 @@ public class CostDamage extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment)
*/
@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 Player activator = ability.getActivatingPlayer();
final int life = activator.getLife();
final Card source = ability.getSourceCard();
Integer c = this.convertAmount();
if (c == null) {
@@ -124,10 +125,10 @@ public class CostDamage extends CostPart {
if (GuiDialog.confirm(source, sb.toString()) && activator.canPayLife(c)) {
activator.addDamage(c, source);
this.setLastPaidAmount(c);
} else {
payment.setCancel(true);
return false;
}
return true;
}
/*

View File

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

View File

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

View File

@@ -126,9 +126,10 @@ public class CostMill extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment)
*/
@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();
Integer c = this.convertAmount();
final Card source = ability.getSourceCard();
final Player activator = ability.getActivatingPlayer();
if (c == null) {
@@ -144,26 +145,22 @@ public class CostMill extends CostPartWithList {
if ((list == null) || (list.size() > c)) {
// I don't believe this is possible
payment.cancelCost();
return;
return false;
}
final StringBuilder sb = new StringBuilder();
sb.append("Mill ").append(c).append(" cards from your library?");
final boolean doMill = GuiDialog.confirm(source, sb.toString());
if (doMill) {
this.resetList();
final Iterator<Card> itr = list.iterator();
while (itr.hasNext()) {
final Card card = itr.next();
this.addToList(card);
Singletons.getModel().getGame().getAction().moveToGraveyard(card);
}
this.addListToHash(ability, "Milled");
} else {
payment.cancelCost();
if ( false == GuiDialog.confirm(source, sb.toString()) )
return false;
this.resetList();
final Iterator<Card> itr = list.iterator();
while (itr.hasNext()) {
final Card card = itr.next();
executePayment(ability, card);
}
return true;
}
/*
@@ -192,4 +189,21 @@ public class CostMill extends CostPartWithList {
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,8 +200,8 @@ public abstract class CostPart {
* @param game
* @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)
*

View File

@@ -25,6 +25,7 @@ import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayManaOfCostPayment;
import forge.control.input.InputPayManaX;
import forge.control.input.InputPayment;
import forge.game.GameState;
import forge.game.ai.ComputerUtilMana;
import forge.game.player.AIPlayer;
@@ -205,7 +206,8 @@ public class CostPartMana extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment)
*/
@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;
if (!this.hasNoXManaCost()) {
// 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) {
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) {
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;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import forge.Card;
import forge.CardUtil;
@@ -30,14 +31,16 @@ import forge.card.spellability.SpellAbility;
public abstract class CostPartWithList extends CostPart {
/** 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.
*
* @return the list
*/
public final List<Card> getList() {
public final Set<Card> getList() {
return this.list;
}
@@ -48,14 +51,15 @@ public abstract class CostPartWithList extends CostPart {
* the new list
*/
public final void setList(final List<Card> setList) {
this.list = setList;
this.list.clear();
list.addAll(setList);
}
/**
* Reset list.
*/
public final void resetList() {
this.setList(new ArrayList<Card>());
this.list.clear();
}
/**
@@ -65,10 +69,7 @@ public abstract class CostPartWithList extends CostPart {
* the c
*/
public final void addToList(final Card c) {
if (this.getList() == null) {
this.resetList();
}
this.getList().add(c);
this.list.add(c);
}
/**
@@ -91,7 +92,7 @@ public abstract class CostPartWithList extends CostPart {
*/
public CostPartWithList() {
}
/**
* Instantiates a new cost part with list.
*
@@ -106,4 +107,12 @@ public abstract class CostPartWithList extends CostPart {
super(amount, type, description);
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)
*/
@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 Player activator = ability.getActivatingPlayer();
final int life = activator.getLife();
@@ -149,10 +150,10 @@ public class CostPayLife extends CostPart {
if (activator.canPayLife(c) && GuiDialog.confirm(source, sb.toString())) {
activator.payLife(c, null);
this.setLastPaidAmount(c);
} else {
payment.setCancel(true);
return false;
}
return true;
}
/*

View File

@@ -38,7 +38,6 @@ import forge.game.player.Player;
public class CostPayment {
private Cost cost = null;
private SpellAbility ability = null;
private Card card = null;
private SpellAbilityRequirements req = null;
private boolean bCancel = false;
private final ArrayList<CostPart> paidCostParts = new ArrayList<CostPart>();
@@ -74,7 +73,7 @@ public class CostPayment {
* @return a {@link forge.Card} object.
*/
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) {
this.cost = cost;
this.ability = abil;
this.card = abil.getSourceCard();
this.game = game;
}
@@ -212,9 +210,12 @@ public class CostPayment {
continue;
}
part.payHuman(this.ability, this.card, this, game);
if ( isCanceled() ) return;
if ( false == part.payHuman(getAbility(), game) ) {
this.setCancel(true);
return;
}
if( part instanceof CostPartWithList )
((CostPartWithList) part).addListToHash(ability, ((CostPartWithList) part).getHashForList());
setPaidPart(part);
}
this.resetUndoList();
@@ -258,7 +259,7 @@ public class CostPayment {
public final void cancelPayment() {
for (final CostPart part : this.paidCostParts) {
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.CardLists;
import forge.CounterType;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSynchronized;
import forge.control.input.InputPayment;
import forge.game.GameState;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.AIPlayer;
@@ -57,8 +58,7 @@ public class CostPutCounter extends CostPartWithList {
* @param payment
* @param sa
*/
public InputPayCostPutCounter(String type, CostPutCounter costPutCounter, int nNeeded, CostPayment payment, SpellAbility sa) {
super(payment);
public InputPayCostPutCounter(String type, CostPutCounter costPutCounter, int nNeeded, SpellAbility sa) {
this.type = type;
this.costPutCounter = costPutCounter;
this.nNeeded = nNeeded;
@@ -90,9 +90,7 @@ public class CostPutCounter extends CostPartWithList {
public void selectCard(final Card card) {
if (this.typeList.contains(card)) {
this.nPut++;
costPutCounter.addToList(card);
card.addCounter(costPutCounter.getCounter(), 1, false);
costPutCounter.executePayment(sa, card);
if (nNeeded == this.nPut) {
this.done();
} else {
@@ -220,17 +218,14 @@ public class CostPutCounter extends CostPartWithList {
*/
@Override
public final void payAI(final AIPlayer ai, final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
Integer c = this.convertAmount();
if (c == null) {
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
}
Integer c = getNumberOfCounters(ability);
if (this.payCostFromSource()) {
source.addCounter(this.getCounter(), c, false);
executePayment(ability, source, c);
} else {
// Put counter on chosen card
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)
*/
@Override
public final void payHuman(final SpellAbility ability, final Card source, final CostPayment payment, final GameState game) {
Integer c = this.convertAmount();
if (c == null) {
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
}
public final boolean payHuman(final SpellAbility ability, final GameState game) {
final Card source = ability.getSourceCard();
Integer c = getNumberOfCounters(ability);
if (this.payCostFromSource()) {
source.addCounter(this.getCounter(), c, false);
this.addToList(source);
executePayment(ability, source, c);
return true;
} else {
InputSynchronized inp = new InputPayCostPutCounter(this.getType(), this, c, payment, ability);
inp.awaitLatchRelease();
InputPayment inp = new InputPayCostPutCounter(this.getType(), this, c, ability);
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);
return true;
} else {
Integer c = this.convertAmount();
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);
final List<Card> typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ai, source);
Card card = null;
if (this.getType().equals("Creature.YouCtrl")) {
@@ -292,4 +286,23 @@ public class CostPutCounter extends CostPartWithList {
}
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.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSynchronized;
import forge.control.input.InputPayment;
import forge.game.GameState;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
@@ -66,8 +66,7 @@ public class CostRemoveCounter extends CostPartWithList {
* @param type
* @param costRemoveCounter
*/
public InputPayCostRemoveCounterType(CostPayment payment, int nNeeded, SpellAbility sa, String type, CostRemoveCounter costRemoveCounter) {
super(payment);
public InputPayCostRemoveCounterType(int nNeeded, SpellAbility sa, String type, CostRemoveCounter costRemoveCounter) {
this.nNeeded = nNeeded;
this.sa = sa;
this.type = type;
@@ -99,8 +98,7 @@ public class CostRemoveCounter extends CostPartWithList {
if (this.typeList.contains(card)) {
if (card.getCounters(costRemoveCounter.getCounter()) > 0) {
this.nRemove++;
costRemoveCounter.addToList(card);
card.subtractCounter(costRemoveCounter.getCounter(), 1);
costRemoveCounter.executePayment(sa, card);
if (nNeeded == this.nRemove) {
this.done();
@@ -133,9 +131,8 @@ public class CostRemoveCounter extends CostPartWithList {
* @param nNeeded
* @param payment
*/
public InputPayCostRemoveCounterFrom(CostRemoveCounter costRemoveCounter, String type, SpellAbility sa,
int nNeeded, CostPayment payment) {
super(payment);
public InputPayCostRemoveCounterFrom(CostRemoveCounter costRemoveCounter, String type, SpellAbility sa, int nNeeded) {
this.costRemoveCounter = costRemoveCounter;
this.type = type;
this.sa = sa;
@@ -153,20 +150,18 @@ public class CostRemoveCounter extends CostPartWithList {
this.typeList = CardLists.getValidCards(this.typeList, type.split(";"), sa.getActivatingPlayer(), sa.getSourceCard());
for (int i = 0; i < nNeeded; i++) {
if (this.typeList.size() == 0) {
if (this.typeList.isEmpty()) {
this.cancel();
}
final Card o = GuiChoose
.oneOrNone("Remove counter(s) from a card in " + costRemoveCounter.getZone(), this.typeList);
final Card o = GuiChoose.oneOrNone("Remove counter(s) from a card in " + costRemoveCounter.getZone(), this.typeList);
if (o != null) {
final Card card = o;
if (card.getCounters(costRemoveCounter.getCounter()) > 0) {
this.nRemove++;
costRemoveCounter.addToList(card);
card.subtractCounter(costRemoveCounter.getCounter(), 1);
costRemoveCounter.executePayment(sa, card);
if (card.getCounters(costRemoveCounter.getCounter()) == 0) {
this.typeList.remove(card);
@@ -361,8 +356,9 @@ public class CostRemoveCounter extends CostPartWithList {
* forge.Card, forge.card.cost.Cost_Payment)
*/
@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 Card source = ability.getSourceCard();
Integer c = this.convertAmount();
int maxCounters = 0;
@@ -377,16 +373,14 @@ public class CostRemoveCounter extends CostPartWithList {
}
}
final InputSynchronized inp;
final InputPayment inp;
if (this.getZone().equals(ZoneType.Battlefield)) {
inp = new InputPayCostRemoveCounterType(payment, c, ability, this.getType(), this);
inp = new InputPayCostRemoveCounterType(c, ability, this.getType(), this);
} else {
inp = new InputPayCostRemoveCounterFrom(this, this.getType(), ability, c, payment);
inp = new InputPayCostRemoveCounterFrom(this, this.getType(), ability, c);
}
FThreads.setInputAndWait(inp);
if ( !payment.isCanceled() )
addListToHash(ability, "CounterRemove");
return;
return inp.isPaid();
}
maxCounters = source.getCounters(this.counter);
@@ -404,14 +398,13 @@ public class CostRemoveCounter extends CostPartWithList {
}
}
if (maxCounters >= c) {
this.addToList(source);
source.setSVar("CostCountersRemoved", "Number$" + Integer.toString(c));
source.subtractCounter(this.counter, c);
this.setLastPaidAmount(c);
} else {
payment.setCancel(true);
}
if (maxCounters < c) return false;
this.addToList(source);
source.setSVar("CostCountersRemoved", "Number$" + Integer.toString(c));
executePayment(ability, source, c);
return true;
}
/*
@@ -457,4 +450,24 @@ public class CostRemoveCounter extends CostPartWithList {
}
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.CardLists;
import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -121,7 +120,7 @@ public class CostReturn extends CostPartWithList {
@Override
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()) {
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)
*/
@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 Card source = ability.getSourceCard();
Integer c = this.convertAmount();
final Player activator = ability.getActivatingPlayer();
final List<Card> list = activator.getCardsIn(ZoneType.Battlefield);
@@ -152,27 +152,24 @@ public class CostReturn extends CostPartWithList {
if (card.getController() == ability.getActivatingPlayer() && card.isInPlay()) {
boolean confirm = GuiDialog.confirm(card, card.getName() + " - Return to Hand?");
if (confirm) {
addToList(card);
game.getAction().moveToHand(card);
} else {
payment.cancelCost();
executePayment(ability, card);
}
return confirm;
}
} else {
List<Card> validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
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);
if (inp.hasCancelled())
payment.setCancel(true);
else
for(Card crd : inp.getSelected())
game.getAction().moveToHand(crd);
return false;
for(Card crd : inp.getSelected())
executePayment(ability, crd);
return true;
}
if (!payment.isCanceled())
addListToHash(ability, "Returned");
return false;
}
/*
@@ -194,13 +191,30 @@ public class CostReturn extends CostPartWithList {
}
this.setList(ComputerUtil.chooseReturnType(ai, this.getType(), source, ability.getTargetCard(), c));
if (this.getList() == null) {
if (this.getList().isEmpty()) {
return false;
}
}
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

View File

@@ -25,13 +25,13 @@ import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayment;
import forge.game.GameState;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil;
/**
@@ -63,9 +63,7 @@ public class CostReveal extends CostPartWithList {
* @param payment
* @param nNeeded
*/
public InputPayReveal(CostReveal part, String discType, List<Card> handList, SpellAbility sa,
CostPayment payment, int nNeeded) {
super(payment);
public InputPayReveal(CostReveal part, String discType, List<Card> handList, SpellAbility sa, int nNeeded) {
this.part = part;
this.discType = discType;
this.handList = handList;
@@ -95,7 +93,7 @@ public class CostReveal extends CostPartWithList {
sb.append(nNeeded - this.nReveal);
sb.append(" remaining.");
}
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
showMessage(sb.toString());
ButtonUtil.enableOnlyCancel();
}
@@ -105,7 +103,7 @@ public class CostReveal extends CostPartWithList {
if (zone.is(ZoneType.Hand) && handList.contains(card)) {
// send in List<Card> for Typing
handList.remove(card);
part.addToList(card);
part.executePayment(sa, card);
this.nReveal++;
// in case no more cards in hand
@@ -222,6 +220,8 @@ public class CostReveal extends CostPartWithList {
@Override
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());
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)
*/
@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 Card source = ability.getSourceCard();
final String amount = this.getAmount();
this.resetList();
if (this.payCostFromSource()) {
this.addToList(source);
executePayment(ability, source);
return true;
} 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 {
Integer num = this.convertAmount();
@@ -255,12 +259,12 @@ public class CostReveal extends CostPartWithList {
num = AbilityUtils.calculateAmount(source, amount, ability);
}
}
if (num > 0) {
FThreads.setInputAndWait(new InputPayReveal(this, this.getType(), handList, ability, payment, num));
}
if ( num == 0 ) return true;
InputPayment inp = new InputPayReveal(this, this.getType(), handList, ability, num);
FThreads.setInputAndWait(inp);
return inp.isPaid();
}
if ( !payment.isCanceled())
this.addListToHash(ability, "Revealed");
}
/*
@@ -296,6 +300,23 @@ public class CostReveal extends CostPartWithList {
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

View File

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

View File

@@ -93,12 +93,13 @@ public class CostTap extends CostPart {
* forge.Card, forge.card.cost.Cost_Payment)
*/
@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(),
// payment.getCost()))
// return false;
source.tap();
ability.getSourceCard().tap();
return true;
}
/*

View File

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

View File

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

View File

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

View File

@@ -1,35 +1,29 @@
package forge.card.cost;
import forge.control.input.InputPayment;
import forge.control.input.InputSyncronizedBase;
/**
* TODO: Write javadoc for this type.
*
*/
abstract class InputPayCostBase extends InputSyncronizedBase {
abstract class InputPayCostBase extends InputSyncronizedBase implements InputPayment {
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
final public void selectButtonCancel() {
this.cancel();
}
final protected void done() {
bPaid = true;
this.stop();
}
final public void cancel() {
payment.cancelCost();
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.
*
*/
public abstract class InputPayManaBase extends InputSyncronizedBase {
public abstract class InputPayManaBase extends InputSyncronizedBase implements InputPayment {
private static final long serialVersionUID = -9133423708688480255L;
@@ -39,9 +39,11 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
protected ManaCostBeingPaid manaCost;
protected final SpellAbility saPaidFor;
boolean bPaid = false;
protected InputPayManaBase(final GameState game, SpellAbility saToPayFor) {
this.game = game;
this.whoPays = Singletons.getControl().getPlayer();
this.whoPays = saToPayFor.getActivatingPlayer();
this.saPaidFor = saToPayFor;
}
@@ -312,6 +314,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
@Override
public void run() {
if (manaCost.isPaid()) {
bPaid = true;
done();
} else if (Singletons.getModel().getMatch().getInput().getInput() == InputPayManaBase.this) {
showMessage();
@@ -333,10 +336,11 @@ public abstract class InputPayManaBase extends InputSyncronizedBase {
for (final Card c : saPaidFor.getTappedForConvoke()) {
c.setTapped(false);
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();
}
}
}
public boolean isPaid() { return bPaid; }
}

View File

@@ -3,45 +3,23 @@ package forge.control.input;
import forge.Card;
import forge.Singletons;
import forge.card.cost.CostPartMana;
import forge.card.cost.CostPayment;
import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility;
import forge.game.GameState;
import forge.game.player.Player;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil;
public class InputPayManaOfCostPayment extends InputPayManaBase {
private final CostPartMana costMana;
// 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) {
public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, int toAdd) {
super(game, spellAbility);
manaCost = new ManaCostBeingPaid(costMana.getManaToPay());
manaCost.increaseColorlessMana(toAdd);
this.costMana = costMana;
originalManaCost = costMana.getMana();
manaToAdd = toAdd;
this.payment = payment;
}
private static final long serialVersionUID = 3467312982164195091L;
private int phyLifeToLose = 0;
private void resetManaCost() {
this.manaCost = new ManaCostBeingPaid(this.originalManaCost);
this.phyLifeToLose = 0;
}
@Override
public void selectPlayer(final Player player) {
if (player == whoPays) {
@@ -61,11 +39,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
}
source.setColorsPaid(this.manaCost.getColorsPaid());
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.
// This is done to make sure Taps triggers go off at the right time
@@ -79,9 +52,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
@Override
public void selectButtonCancel() {
handleConvokedCards(true);
this.resetManaCost();
payment.cancelCost();
stop();
}
@@ -89,7 +59,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
public void showMessage() {
ButtonUtil.enableOnlyCancel();
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);
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.)");
}
CMatchUI.SINGLETON_INSTANCE.showMessage(msg.toString());
showMessage(msg.toString());
if (manaCost.isPaid()) {
bPaid = true;
this.done();
}
}

View File

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