mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Human payment for costs now uses visitor pattern... as a result the concrete Cost classes no longer depend on UI
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -15438,6 +15438,7 @@ forge-gui/src/main/java/forge/gui/menus/IMenuProvider.java -text
|
|||||||
forge-gui/src/main/java/forge/gui/menus/LayoutMenu.java -text
|
forge-gui/src/main/java/forge/gui/menus/LayoutMenu.java -text
|
||||||
forge-gui/src/main/java/forge/gui/menus/MenuUtil.java -text
|
forge-gui/src/main/java/forge/gui/menus/MenuUtil.java -text
|
||||||
forge-gui/src/main/java/forge/gui/package-info.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/gui/package-info.java svneol=native#text/plain
|
||||||
|
forge-gui/src/main/java/forge/gui/player/HumanCostDecision.java -text
|
||||||
forge-gui/src/main/java/forge/gui/player/HumanPlay.java -text
|
forge-gui/src/main/java/forge/gui/player/HumanPlay.java -text
|
||||||
forge-gui/src/main/java/forge/gui/player/LobbyPlayerHuman.java -text
|
forge-gui/src/main/java/forge/gui/player/LobbyPlayerHuman.java -text
|
||||||
forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java -text
|
forge-gui/src/main/java/forge/gui/player/PlayerControllerHuman.java -text
|
||||||
|
|||||||
@@ -525,7 +525,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (amount.equals("All")) {
|
if (amount.equals("All")) {
|
||||||
c = source.getCounters(cost.getCounter());
|
c = source.getCounters(cost.counter);
|
||||||
} else {
|
} else {
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||||
}
|
}
|
||||||
@@ -536,18 +536,18 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
|||||||
if (type.equals("OriginalHost")) {
|
if (type.equals("OriginalHost")) {
|
||||||
typeList = Lists.newArrayList(ability.getOriginalHost());
|
typeList = Lists.newArrayList(ability.getOriginalHost());
|
||||||
} else {
|
} else {
|
||||||
typeList = CardLists.getValidCards(ai.getCardsIn(cost.getZone()), type.split(";"), ai, source);
|
typeList = CardLists.getValidCards(ai.getCardsIn(cost.zone), type.split(";"), ai, source);
|
||||||
}
|
}
|
||||||
for (Card card : typeList) {
|
for (Card card : typeList) {
|
||||||
if (card.getCounters(cost.getCounter()) >= c) {
|
if (card.getCounters(cost.counter) >= c) {
|
||||||
return PaymentDecision.card(card);
|
return PaymentDecision.card(card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c > source.getCounters(cost.getCounter())) {
|
if (c > source.getCounters(cost.counter)) {
|
||||||
System.out.println("Not enough " + cost.getCounter() + " on " + source.getName());
|
System.out.println("Not enough " + cost.counter + " on " + source.getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class ComputerUtilCost {
|
|||||||
if (part instanceof CostRemoveCounter) {
|
if (part instanceof CostRemoveCounter) {
|
||||||
final CostRemoveCounter remCounter = (CostRemoveCounter) part;
|
final CostRemoveCounter remCounter = (CostRemoveCounter) part;
|
||||||
|
|
||||||
final CounterType type = remCounter.getCounter();
|
final CounterType type = remCounter.counter;
|
||||||
if (!part.payCostFromSource()) {
|
if (!part.payCostFromSource()) {
|
||||||
if (type.name().equals("P1P1")) {
|
if (type.name().equals("P1P1")) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import forge.card.ColorSet;
|
import forge.card.ColorSet;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.mana.Mana;
|
import forge.game.mana.Mana;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -51,21 +50,10 @@ public class CostAddMana extends CostPart {
|
|||||||
public final String toString() {
|
public final String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
final Integer i = this.convertAmount();
|
final Integer i = this.convertAmount();
|
||||||
sb.append("Add ").append(convertManaAmountType(i, this.getType()));
|
sb.append("Add ").append(StringUtils.repeat("{" + this.getType() + "}", i)).append(" to your mana pool");
|
||||||
sb.append(" to your mana pool");
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* convertManaAmountType.
|
|
||||||
* @param i
|
|
||||||
* @param type
|
|
||||||
* @return a String
|
|
||||||
*/
|
|
||||||
private String convertManaAmountType(Integer i, String type) {
|
|
||||||
return StringUtils.repeat("{" + type + "}", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@@ -78,23 +66,6 @@ public class CostAddMana extends CostPart {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
|
||||||
}
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payAsDecided(Player ai, PaymentDecision decision, SpellAbility sa) {
|
public boolean payAsDecided(Player ai, PaymentDecision decision, SpellAbility sa) {
|
||||||
Card source = sa.getSourceCard();
|
Card source = sa.getSourceCard();
|
||||||
|
|||||||
@@ -17,9 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import forge.card.CardType;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -50,20 +47,6 @@ public class CostChooseCreatureType extends CostPart {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
String choice = payer.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>(), true);
|
|
||||||
if( null == choice )
|
|
||||||
return null;
|
|
||||||
return PaymentDecision.type(choice);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa) {
|
public boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa) {
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -60,37 +58,6 @@ public class CostDamage extends CostPart {
|
|||||||
return payer.addDamage(decision.c, sa.getSourceCard());
|
return payer.addDamage(decision.c, sa.getSourceCard());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final int life = activator.getLife();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, life);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activator.canPayLife(c) && activator.getController().confirmPayment(this, "Pay " + c + " Life?")) {
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T accept(ICostVisitor<T> visitor) {
|
public <T> T accept(ICostVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -19,18 +19,12 @@ package forge.game.cost;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates;
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
import forge.util.Aggregates;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostDiscard.
|
* The Class CostDiscard.
|
||||||
@@ -82,8 +76,7 @@ public class CostDiscard extends CostPartWithList {
|
|||||||
desc.append("card");
|
desc.append("card");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
desc.append(this.getTypeDescription() == null ? this.getType() : this.getTypeDescription()).append(
|
desc.append(this.getTypeDescription() == null ? this.getType() : this.getTypeDescription()).append(" card");
|
||||||
" card");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), desc.toString()));
|
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), desc.toString()));
|
||||||
@@ -151,111 +144,6 @@ public class CostDiscard extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
List<Card> handList = new ArrayList<Card>(payer.getCardsIn(ZoneType.Hand));
|
|
||||||
String discardType = this.getType();
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
return handList.contains(source) ? PaymentDecision.card(source) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discardType.equals("Hand")) {
|
|
||||||
return PaymentDecision.card(handList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discardType.equals("LastDrawn")) {
|
|
||||||
final Card lastDrawn = payer.getLastDrawnCard();
|
|
||||||
return handList.contains(lastDrawn) ? PaymentDecision.card(lastDrawn) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
|
|
||||||
if (discardType.equals("Random")) {
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, handList.size());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PaymentDecision.card(Aggregates.random(handList, c));
|
|
||||||
}
|
|
||||||
if (discardType.contains("+WithSameName")) {
|
|
||||||
String type = discardType.replace("+WithSameName", "");
|
|
||||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source);
|
|
||||||
final List<Card> landList2 = handList;
|
|
||||||
handList = CardLists.filter(handList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
for (Card card : landList2) {
|
|
||||||
if (!card.equals(c) && card.getName().equals(c.getName())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (c == 0) { return PaymentDecision.card(Lists.<Card>newArrayList()); }
|
|
||||||
List<Card> discarded = new ArrayList<Card>();
|
|
||||||
while (c > 0) {
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, handList);
|
|
||||||
inp.setMessage("Select one of the cards with the same name to discard. Already chosen: " + discarded);
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final Card first = inp.getFirstSelected();
|
|
||||||
discarded.add(first);
|
|
||||||
handList = CardLists.filter(handList, CardPredicates.nameEquals(first.getName()));
|
|
||||||
handList.remove(first);
|
|
||||||
c--;
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(discarded);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String type = new String(discardType);
|
|
||||||
final String[] validType = type.split(";");
|
|
||||||
handList = CardLists.getValidCards(handList, validType, payer, source);
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, handList.size());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, handList);
|
|
||||||
inp.setMessage("Select %d more " + getDescriptiveType() + " to discard.");
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled() || inp.getSelected().size() != c) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package forge.game.cost;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -94,30 +93,6 @@ public class CostDraw extends CostPart {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!payer.getController().confirmPayment(this, "Draw " + c + " Card" + (c == 1 ? "" : "s"))) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T accept(ICostVisitor<T> visitor) {
|
public <T> T accept(ICostVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -18,14 +18,9 @@
|
|||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates;
|
import forge.game.card.CardPredicates;
|
||||||
@@ -33,9 +28,6 @@ import forge.game.player.Player;
|
|||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
import forge.util.Lang;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostExile.
|
* The Class CostExile.
|
||||||
@@ -52,7 +44,7 @@ public class CostExile extends CostPartWithList {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private ZoneType from = ZoneType.Battlefield;
|
public final ZoneType from;
|
||||||
public final boolean sameZone;
|
public final boolean sameZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,9 +74,7 @@ public class CostExile extends CostPartWithList {
|
|||||||
|
|
||||||
public CostExile(final String amount, final String type, final String description, final ZoneType from, final boolean sameZone) {
|
public CostExile(final String amount, final String type, final String description, final ZoneType from, final boolean sameZone) {
|
||||||
super(amount, type, description);
|
super(amount, type, description);
|
||||||
if (from != null) {
|
this.from = from != null ? from : ZoneType.Battlefield;
|
||||||
this.from = from;
|
|
||||||
}
|
|
||||||
this.sameZone = sameZone;
|
this.sameZone = sameZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,206 +196,6 @@ public class CostExile extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
final Game game = activator.getGame();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
String type = this.getType();
|
|
||||||
boolean fromTopGrave = false;
|
|
||||||
if (type.contains("FromTopGrave")) {
|
|
||||||
type = type.replace("FromTopGrave", "");
|
|
||||||
fromTopGrave = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> list;
|
|
||||||
if (this.from.equals(ZoneType.Stack)) {
|
|
||||||
list = new ArrayList<Card>();
|
|
||||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
|
||||||
list.add(si.getSourceCard());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (this.sameZone) {
|
|
||||||
list = new ArrayList<Card>(game.getCardsIn(this.from));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
list = new ArrayList<Card>(activator.getCardsIn(this.from));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
return source.getZone() == activator.getZone(from) && activator.getController().confirmPayment(this, "Exile " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.equals("All")) {
|
|
||||||
return PaymentDecision.card(list);
|
|
||||||
}
|
|
||||||
list = CardLists.getValidCards(list, type.split(";"), activator, source);
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, list.size());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.from == ZoneType.Battlefield || this.from == ZoneType.Hand) {
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
|
||||||
inp.setMessage("Exile %d card(s) from your" + from);
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
return inp.hasCancelled() ? null : PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.from == ZoneType.Stack) { return exileFromStack(ability, c); }
|
|
||||||
if (this.from == ZoneType.Library) { return exileFromTop(ability, activator, c); }
|
|
||||||
if (fromTopGrave) { return exileFromTopGraveType(ability, c, list); }
|
|
||||||
if (!this.sameZone) { return exileFromMiscZone(ability, c, list); }
|
|
||||||
|
|
||||||
List<Player> players = game.getPlayers();
|
|
||||||
List<Player> payableZone = new ArrayList<Player>();
|
|
||||||
for (Player p : players) {
|
|
||||||
List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
|
||||||
if (enoughType.size() < c) {
|
|
||||||
list.removeAll(enoughType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
payableZone.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exileFromSame(list, c, payableZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inputs
|
|
||||||
|
|
||||||
// Exile<Num/Type{/TypeDescription}>
|
|
||||||
// ExileFromHand<Num/Type{/TypeDescription}>
|
|
||||||
// ExileFromGrave<Num/Type{/TypeDescription}>
|
|
||||||
// ExileFromTop<Num/Type{/TypeDescription}> (of library)
|
|
||||||
// ExileSameGrave<Num/Type{/TypeDescription}>
|
|
||||||
|
|
||||||
private PaymentDecision exileFromSame(List<Card> list, int nNeeded, List<Player> payableZone) {
|
|
||||||
if (nNeeded == 0) {
|
|
||||||
return PaymentDecision.number(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player p = GuiChoose.oneOrNone(String.format("Exile from whose %s?", getFrom()), payableZone);
|
|
||||||
if (p == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
|
||||||
if(typeList.size() < nNeeded)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<Card> toExile = GuiChoose.many("Exile from " + getFrom(), "To be exiled", nNeeded, typeList, null);
|
|
||||||
return PaymentDecision.card(toExile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for Constructor.
|
|
||||||
* @param payment
|
|
||||||
* @param sa
|
|
||||||
* @param type
|
|
||||||
* @param nNeeded
|
|
||||||
* @param part
|
|
||||||
*/
|
|
||||||
private PaymentDecision exileFromStack(SpellAbility sa, int nNeeded) {
|
|
||||||
if (nNeeded == 0) {
|
|
||||||
return PaymentDecision.number(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Game game = sa.getActivatingPlayer().getGame();
|
|
||||||
ArrayList<SpellAbility> saList = new ArrayList<SpellAbility>();
|
|
||||||
ArrayList<String> descList = new ArrayList<String>();
|
|
||||||
|
|
||||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
|
||||||
final Card stC = si.getSourceCard();
|
|
||||||
final SpellAbility stSA = si.getSpellAbility().getRootAbility();
|
|
||||||
if (stC.isValid(getType().split(";"), sa.getActivatingPlayer(), sa.getSourceCard()) && stSA.isSpell()) {
|
|
||||||
saList.add(stSA);
|
|
||||||
if (stC.isCopiedSpell()) {
|
|
||||||
descList.add(stSA.getStackDescription() + " (Copied Spell)");
|
|
||||||
} else {
|
|
||||||
descList.add(stSA.getStackDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saList.size() < nNeeded) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> exiled = new ArrayList<Card>();
|
|
||||||
for (int i = 0; i < nNeeded; i++) {
|
|
||||||
//Have to use the stack descriptions here because some copied spells have no description otherwise
|
|
||||||
final String o = GuiChoose.oneOrNone("Exile from " + getFrom(), descList);
|
|
||||||
|
|
||||||
if (o != null) {
|
|
||||||
final SpellAbility toExile = saList.get(descList.indexOf(o));
|
|
||||||
final Card c = toExile.getSourceCard();
|
|
||||||
|
|
||||||
saList.remove(toExile);
|
|
||||||
descList.remove(o);
|
|
||||||
|
|
||||||
exiled.add(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(exiled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PaymentDecision exileFromTop(final SpellAbility sa, final Player payer, 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 = payer.getCardsIn(ZoneType.Library, nNeeded);
|
|
||||||
|
|
||||||
if (list.size() > nNeeded || !payer.getController().confirmPayment(this, "Exile " + Lang.nounWithAmount(nNeeded, "card") + " from the top of your library?")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PaymentDecision.card(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PaymentDecision exileFromMiscZone(SpellAbility sa, int nNeeded, List<Card> typeList) {
|
|
||||||
if (typeList.size() < nNeeded)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<Card> exiled = new ArrayList<Card>();
|
|
||||||
for (int i = 0; i < nNeeded; i++) {
|
|
||||||
final Card c = GuiChoose.oneOrNone("Exile from " + getFrom(), typeList);
|
|
||||||
|
|
||||||
if (c != null) {
|
|
||||||
typeList.remove(c);
|
|
||||||
exiled.add(c);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(exiled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PaymentDecision exileFromTopGraveType(SpellAbility sa, int nNeeded, List<Card> typeList) {
|
|
||||||
if (typeList.size() < nNeeded)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Collections.reverse(typeList);
|
|
||||||
return PaymentDecision.card(Lists.newArrayList(Iterables.limit(typeList, nNeeded)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import forge.game.card.CardLists;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is for the "ExiledMoveToGrave" Cost.
|
* This is for the "ExiledMoveToGrave" Cost.
|
||||||
@@ -104,32 +103,6 @@ public class CostExiledMoveToGrave extends CostPartWithList {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player activator = ability.getActivatingPlayer();
|
|
||||||
List<Card> list = activator.getGame().getCardsIn(ZoneType.Exile);
|
|
||||||
list = CardLists.getValidCards(list, this.getType().split(";"), activator, source);
|
|
||||||
|
|
||||||
if (list.size() < c)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(GuiChoose.many("Choose an exiled card to put into graveyard", "To graveyard", c, list, source));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.ability.effects.FlipCoinEffect;
|
import forge.game.ability.effects.FlipCoinEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -58,36 +57,6 @@ public class CostFlipCoin extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, this.getList().size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see forge.card.cost.CostPart#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
return Cost.convertAmountTypeToWords(this.convertAmount(), this.getAmount(), "Coin");
|
return Cost.convertAmountTypeToWords(this.convertAmount(), this.getAmount(), "Coin");
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import forge.game.card.CardLists;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostReturn.
|
* The Class CostReturn.
|
||||||
@@ -84,35 +83,6 @@ public class CostGainControl extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
final List<Card> list = payer.getCardsIn(ZoneType.Battlefield);
|
|
||||||
List<Card> validCards = CardLists.getValidCards(list, this.getType().split(";"), payer, source);
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, validCards);
|
|
||||||
final String desc = this.getTypeDescription() == null ? this.getType() : this.getTypeDescription();
|
|
||||||
inp.setMessage("Gain control of %d " + desc);
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,13 +20,9 @@ package forge.game.cost;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostGainLife.
|
* The Class CostGainLife.
|
||||||
@@ -45,6 +41,13 @@ public class CostGainLife extends CostPart {
|
|||||||
cntPlayers = qty;
|
cntPlayers = qty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cntPlayers
|
||||||
|
*/
|
||||||
|
public int getCntPlayers() {
|
||||||
|
return cntPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@@ -116,51 +119,6 @@ public class CostGainLife extends CostPart {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
|
|
||||||
final int life = activator.getLife();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, life);
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Player> oppsThatCanGainLife = new ArrayList<Player>();
|
|
||||||
for (final Player opp : getPotentialTargets(activator, source)) {
|
|
||||||
if (opp.canGainLife()) {
|
|
||||||
oppsThatCanGainLife.add(opp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cntPlayers == Integer.MAX_VALUE) // applied to all players who can gain
|
|
||||||
return PaymentDecision.players(oppsThatCanGainLife);
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:");
|
|
||||||
|
|
||||||
final Player chosenToGain = GuiChoose.oneOrNone(sb.toString(), oppsThatCanGainLife);
|
|
||||||
if (null == chosenToGain)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return PaymentDecision.players(Lists.newArrayList(chosenToGain));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public <T> T accept(ICostVisitor<T> visitor) {
|
public <T> T accept(ICostVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
|
|||||||
@@ -76,36 +76,6 @@ public class CostMill extends CostPartWithList {
|
|||||||
return i < zone.size();
|
return i < zone.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, this.getList().size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!activator.getController().confirmPayment(this, "Mill " + c + " card" + (c == 1 ? "" : "s") + " from your library?")) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(activator.getCardsIn(ZoneType.Library, c));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -151,20 +151,6 @@ public abstract class CostPart {
|
|||||||
|
|
||||||
public abstract <T> T accept(final ICostVisitor<T> visitor);
|
public abstract <T> T accept(final ICostVisitor<T> visitor);
|
||||||
|
|
||||||
/**
|
|
||||||
* Pay human.
|
|
||||||
*
|
|
||||||
* @param ability
|
|
||||||
* {@link forge.game.spellability.SpellAbility}
|
|
||||||
* @param source
|
|
||||||
* {@link forge.game.card.Card}
|
|
||||||
* @param payment
|
|
||||||
* {@link forge.game.cost.CostPayment}
|
|
||||||
* @param game
|
|
||||||
* @return true, if successful
|
|
||||||
*/
|
|
||||||
public abstract PaymentDecision payHuman(SpellAbility ability, Player humanPayer);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@@ -192,17 +178,6 @@ public abstract class CostPart {
|
|||||||
this.amount = amountIn;
|
this.amount = amountIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int chooseXValue(final Card card, final SpellAbility sa, final int maxValue) {
|
|
||||||
/*final String chosen = sa.getSVar("ChosenX");
|
|
||||||
if (chosen.length() > 0) {
|
|
||||||
return AbilityFactory.calculateAmount(card, "ChosenX", null);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
int chosenX = sa.getActivatingPlayer().getController().chooseNumber(sa, card.toString() + " - Choose a Value for X", 0, maxValue);
|
|
||||||
sa.setSVar("ChosenX", Integer.toString(chosenX));
|
|
||||||
card.setSVar("ChosenX", Integer.toString(chosenX));
|
|
||||||
return chosenX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa);
|
public abstract boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,10 +111,4 @@ public class CostPartMana extends CostPart {
|
|||||||
return payer.getController().payManaCost(this, pd, sa);
|
return payer.getController().payManaCost(this, pd, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PaymentDecision payHuman(SpellAbility ability, Player humanPayer) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return new PaymentDecision(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,41 +101,6 @@ public class CostPayLife extends CostPart {
|
|||||||
return ai.payLife(paidAmount, null);
|
return ai.payLife(paidAmount, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final int life = activator.getLife();
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.startsWith("XChoice")) {
|
|
||||||
int limit = life;
|
|
||||||
if (sVar.contains("LimitMax")) {
|
|
||||||
limit = AbilityUtils.calculateAmount(source, sVar.split("LimitMax.")[1], ability);
|
|
||||||
}
|
|
||||||
int maxLifePayment = limit < life ? limit : life;
|
|
||||||
c = chooseXValue(source, ability, maxLifePayment);
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activator.canPayLife(c) && activator.getController().confirmPayment(this, "Pay " + c + " Life?")) {
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T accept(ICostVisitor<T> visitor) {
|
public <T> T accept(ICostVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import forge.game.Game;
|
|||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.gui.player.HumanCostDecision;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -107,13 +108,13 @@ public class CostPayment {
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public boolean payCost(final Player payer) {
|
public boolean payCost(final Player payer) {
|
||||||
for (final CostPart part : this.cost.getCostParts()) {
|
HumanCostDecision hcd = new HumanCostDecision(payer, ability, ability.getSourceCard());
|
||||||
PaymentDecision pd = part.payHuman(this.ability, payer);
|
|
||||||
|
|
||||||
if ( null == pd ) {
|
for (final CostPart part : this.cost.getCostParts()) {
|
||||||
|
PaymentDecision pd = part.accept(hcd);
|
||||||
|
|
||||||
|
if ( null == pd || !part.payAsDecided(payer, pd, ability))
|
||||||
return false;
|
return false;
|
||||||
} else
|
|
||||||
part.payAsDecided(payer, pd, ability);
|
|
||||||
|
|
||||||
// abilities care what was used to pay for them
|
// abilities care what was used to pay for them
|
||||||
if( part instanceof CostPartWithList )
|
if( part instanceof CostPartWithList )
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import forge.game.card.CardPredicates;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is for the "PutCardToLib" Cost.
|
* This is for the "PutCardToLib" Cost.
|
||||||
@@ -39,8 +37,8 @@ public class CostPutCardToLib extends CostPartWithList {
|
|||||||
// PutCardToLibFromSameGrave<Num/LibPos/Type{/TypeDescription}>
|
// PutCardToLibFromSameGrave<Num/LibPos/Type{/TypeDescription}>
|
||||||
// PutCardToLibFromGrave<Num/LibPos/Type{/TypeDescription}>
|
// PutCardToLibFromGrave<Num/LibPos/Type{/TypeDescription}>
|
||||||
|
|
||||||
private ZoneType from = ZoneType.Hand;
|
public final ZoneType from;
|
||||||
private boolean sameZone = false;
|
public final boolean sameZone;
|
||||||
private String libPosition = "0";
|
private String libPosition = "0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,18 +80,14 @@ public class CostPutCardToLib extends CostPartWithList {
|
|||||||
* @param from
|
* @param from
|
||||||
* the from
|
* the from
|
||||||
*/
|
*/
|
||||||
public CostPutCardToLib(final String amount, final String libpos,
|
public CostPutCardToLib(final String amount, final String libpos, final String type, final String description, final ZoneType from) {
|
||||||
final String type, final String description, final ZoneType from) {
|
this(amount, libpos, type, description, from, false);
|
||||||
super(amount, type, description);
|
|
||||||
if (from != null) {
|
|
||||||
this.from = from;
|
|
||||||
}
|
|
||||||
this.libPosition = libpos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CostPutCardToLib(final String amount, final String libpos, final String type,
|
public CostPutCardToLib(final String amount, final String libpos, final String type, final String description, final ZoneType from, final boolean sameZone) {
|
||||||
final String description, final ZoneType from, final boolean sameZone) {
|
super(amount, type, description);
|
||||||
this(amount, libpos, type, description, from);
|
this.from = from == null ? ZoneType.Hand : from;
|
||||||
|
this.libPosition = libpos;
|
||||||
this.sameZone = sameZone;
|
this.sameZone = sameZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,113 +191,6 @@ public class CostPutCardToLib extends CostPartWithList {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
List<Card> list;
|
|
||||||
|
|
||||||
if (this.sameZone) {
|
|
||||||
list = new ArrayList<Card>(activator.getGame().getCardsIn(this.getFrom()));
|
|
||||||
} else {
|
|
||||||
list = new ArrayList<Card>(activator.getCardsIn(this.getFrom()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, this.getList().size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list = CardLists.getValidCards(list, this.getType().split(";"), activator, source);
|
|
||||||
|
|
||||||
if (this.from == ZoneType.Hand) {
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
|
||||||
inp.setMessage("Put %d card(s) from your " + from );
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
return inp.hasCancelled() ? null : PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.sameZone){
|
|
||||||
List<Player> players = activator.getGame().getPlayers();
|
|
||||||
List<Player> payableZone = new ArrayList<Player>();
|
|
||||||
for (Player p : players) {
|
|
||||||
List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
|
||||||
if (enoughType.size() < c) {
|
|
||||||
list.removeAll(enoughType);
|
|
||||||
} else {
|
|
||||||
payableZone.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return putFromSame(list, c, payableZone);
|
|
||||||
} else {//Graveyard
|
|
||||||
return putFromMiscZone(ability, c, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PutFromMiscZone
|
|
||||||
* @param sa
|
|
||||||
* @param nNeeded
|
|
||||||
* @param typeList
|
|
||||||
* @return a boolean
|
|
||||||
*/
|
|
||||||
private PaymentDecision putFromMiscZone(SpellAbility sa, int nNeeded, List<Card> typeList) {
|
|
||||||
if(typeList.size() < nNeeded)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<Card> chosen = new ArrayList<>();
|
|
||||||
for (int i = 0; i < nNeeded; i++) {
|
|
||||||
final Card c = GuiChoose.oneOrNone("Put from " + getFrom() + " to library", typeList);
|
|
||||||
|
|
||||||
if (c == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
typeList.remove(c);
|
|
||||||
chosen.add(c);
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(chosen);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PaymentDecision putFromSame(List<Card> list, int nNeeded, List<Player> payableZone) {
|
|
||||||
if (nNeeded == 0) {
|
|
||||||
return PaymentDecision.number(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player p = GuiChoose.oneOrNone(String.format("Put cards from whose %s?", getFrom()), payableZone);
|
|
||||||
if (p == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> typeList = CardLists.filter(list, CardPredicates.isOwner(p));
|
|
||||||
if(typeList.size() < nNeeded)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
List<Card> chosen = new ArrayList<>();
|
|
||||||
for (int i = 0; i < nNeeded; i++) {
|
|
||||||
final Card c = GuiChoose.oneOrNone("Put cards from " + getFrom() + " to Library", typeList);
|
|
||||||
if (c == null)
|
|
||||||
return null;
|
|
||||||
typeList.remove(c);
|
|
||||||
chosen.add(c);
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(chosen);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ import forge.game.card.CounterType;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
import forge.util.Lang;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostPutCounter.
|
* The Class CostPutCounter.
|
||||||
@@ -164,37 +162,7 @@ public class CostPutCounter extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public Integer getNumberOfCounters(final SpellAbility ability) {
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
Integer c = getNumberOfCounters(ability);
|
|
||||||
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
lastPaidAmount = c;
|
|
||||||
return PaymentDecision.number(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cards to use this branch: Scarscale Ritual, Wandering Mage - each adds only one counter
|
|
||||||
List<Card> typeList = CardLists.getValidCards(activator.getCardsIn(ZoneType.Battlefield), getType().split(";"), activator, ability.getSourceCard());
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, typeList);
|
|
||||||
inp.setMessage("Put " + Lang.nounWithAmount(c, getCounter().getName() + " counter") + " on " + getDescriptiveType());
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
|
|
||||||
if(inp.hasCancelled())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer getNumberOfCounters(final SpellAbility ability) {
|
|
||||||
Integer c = this.convertAmount();
|
Integer c = this.convertAmount();
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
c = AbilityUtils.calculateAmount(ability.getSourceCard(), this.getAmount(), ability);
|
c = AbilityUtils.calculateAmount(ability.getSourceCard(), this.getAmount(), ability);
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ import forge.game.card.CounterType;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostRemoveAnyCounter.
|
* The Class CostRemoveAnyCounter.
|
||||||
@@ -41,6 +39,13 @@ public class CostRemoveAnyCounter extends CostPartWithList {
|
|||||||
// Power Conduit and Chisei, Heart of Oceans
|
// Power Conduit and Chisei, Heart of Oceans
|
||||||
// Both cards have "Remove a counter from a permanent you control"
|
// Both cards have "Remove a counter from a permanent you control"
|
||||||
private CounterType counterType;
|
private CounterType counterType;
|
||||||
|
/**
|
||||||
|
* @param counterType the counterType to set
|
||||||
|
*/
|
||||||
|
public void setCounterType(CounterType counterType) {
|
||||||
|
this.counterType = counterType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new cost CostRemoveAnyCounter.
|
* Instantiates a new cost CostRemoveAnyCounter.
|
||||||
*
|
*
|
||||||
@@ -64,7 +69,7 @@ public class CostRemoveAnyCounter extends CostPartWithList {
|
|||||||
*
|
*
|
||||||
* @return the counter
|
* @return the counter
|
||||||
*/
|
*/
|
||||||
private CounterType getCounter() {
|
public CounterType getCounter() {
|
||||||
return this.counterType;
|
return this.counterType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,45 +111,6 @@ public class CostRemoveAnyCounter extends CostPartWithList {
|
|||||||
return i <= allCounters;
|
return i <= allCounters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
final String type = this.getType();
|
|
||||||
|
|
||||||
if (c == null) {
|
|
||||||
c = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> list = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
|
||||||
list = CardLists.getValidCards(list, type.split(";"), activator, source);
|
|
||||||
|
|
||||||
|
|
||||||
list = CardLists.filter(list, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card card) {
|
|
||||||
return card.hasCounters();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, list);
|
|
||||||
inp.setMessage("Select " + this.getDescriptiveType() + " to remove a counter");
|
|
||||||
inp.setCancelAllowed(false);
|
|
||||||
inp.showAndWait();
|
|
||||||
Card selected = inp.getFirstSelected();
|
|
||||||
final Map<CounterType, Integer> tgtCounters = selected.getCounters();
|
|
||||||
final ArrayList<CounterType> typeChoices = new ArrayList<CounterType>();
|
|
||||||
for (CounterType key : tgtCounters.keySet()) {
|
|
||||||
if (tgtCounters.get(key) > 0) {
|
|
||||||
typeChoices.add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String prompt = "Select type counters to remove";
|
|
||||||
counterType = GuiChoose.one(prompt, typeChoices);
|
|
||||||
|
|
||||||
return PaymentDecision.card(selected, counterType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -17,16 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.game.GameEntity;
|
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
@@ -34,8 +27,6 @@ import forge.game.card.CounterType;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.input.InputSelectManyBase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostRemoveCounter.
|
* The Class CostRemoveCounter.
|
||||||
@@ -48,170 +39,17 @@ public class CostRemoveCounter extends CostPartWithList {
|
|||||||
// Counter is tough),
|
// Counter is tough),
|
||||||
// Quillspike, Rift Elemental, Sage of Fables, Spike Rogue
|
// Quillspike, Rift Elemental, Sage of Fables, Spike Rogue
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this type.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static final class InputSelectCardToRemoveCounter extends InputSelectManyBase<Card> {
|
|
||||||
private static final long serialVersionUID = 2685832214519141903L;
|
|
||||||
|
|
||||||
private final Map<Card,Integer> cardsChosen;
|
public final CounterType counter;
|
||||||
private final CounterType counterType;
|
public final ZoneType zone;
|
||||||
private final List<Card> validChoices;
|
|
||||||
|
|
||||||
public InputSelectCardToRemoveCounter(int cntCounters, CounterType cType, List<Card> validCards) {
|
|
||||||
super(cntCounters, cntCounters);
|
|
||||||
this.validChoices = validCards;
|
|
||||||
counterType = cType;
|
|
||||||
cardsChosen = cntCounters > 0 ? new HashMap<Card, Integer>() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCardSelected(Card c, java.awt.event.MouseEvent triggerEvent) {
|
|
||||||
if (!isValidChoice(c) || c.getCounters(counterType) <= getTimesSelected(c)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tc = getTimesSelected(c);
|
|
||||||
cardsChosen.put(c, tc+1);
|
|
||||||
|
|
||||||
onSelectStateChanged(c, true);
|
|
||||||
refresh();
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasEnoughTargets() {
|
|
||||||
return hasAllTargets();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasAllTargets() {
|
|
||||||
int sum = getDistibutedCounters();
|
|
||||||
return sum >= max;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getMessage() {
|
|
||||||
return max == Integer.MAX_VALUE
|
|
||||||
? String.format(message, getDistibutedCounters())
|
|
||||||
: String.format(message, max - getDistibutedCounters());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getDistibutedCounters() {
|
|
||||||
int sum = 0;
|
|
||||||
for(Entry<Card, Integer> kv : cardsChosen.entrySet()) {
|
|
||||||
sum += kv.getValue().intValue();
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final boolean isValidChoice(GameEntity choice) {
|
|
||||||
return validChoices.contains(choice);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTimesSelected(Card c) {
|
|
||||||
return cardsChosen.containsKey(c) ? cardsChosen.get(c).intValue() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Card> getSelected() {
|
|
||||||
return cardsChosen.keySet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
final String type = this.getType();
|
|
||||||
|
|
||||||
String sVarAmount = ability.getSVar(amount);
|
|
||||||
cntRemoved = 1;
|
|
||||||
if (c != null)
|
|
||||||
cntRemoved = c.intValue();
|
|
||||||
else if (!"XChoice".equals(sVarAmount)) {
|
|
||||||
cntRemoved = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
int maxCounters = source.getCounters(this.counter);
|
|
||||||
if (amount.equals("All"))
|
|
||||||
cntRemoved = maxCounters;
|
|
||||||
else if ( c == null && "XChoice".equals(sVarAmount)) {
|
|
||||||
cntRemoved = chooseXValue(source, ability, maxCounters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxCounters < cntRemoved)
|
|
||||||
return null;
|
|
||||||
PaymentDecision res = PaymentDecision.card(source);
|
|
||||||
res.c = cntRemoved >= 0 ? cntRemoved : maxCounters;
|
|
||||||
return res;
|
|
||||||
} else if (type.equals("OriginalHost")) {
|
|
||||||
int maxCounters = ability.getOriginalHost().getCounters(this.counter);
|
|
||||||
if (amount.equals("All")) {
|
|
||||||
cntRemoved = maxCounters;
|
|
||||||
}
|
|
||||||
if (maxCounters < cntRemoved)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PaymentDecision res = PaymentDecision.card(ability.getOriginalHost());
|
|
||||||
res.c = cntRemoved >= 0 ? cntRemoved : maxCounters;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> validCards = CardLists.getValidCards(activator.getCardsIn(getZone()), type.split(";"), activator, source);
|
|
||||||
if (this.getZone().equals(ZoneType.Battlefield)) {
|
|
||||||
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(cntRemoved, getCounter(), validCards);
|
|
||||||
inp.setMessage("Remove %d " + getCounter().getName() + " counters from " + getDescriptiveType());
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if(inp.hasCancelled())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Have to hack here: remove all counters minus one, without firing any triggers,
|
|
||||||
// triggers will fire when last is removed by executePayment.
|
|
||||||
// They don't care how many were removed anyway
|
|
||||||
// int sum = 0;
|
|
||||||
for(Card crd : inp.getSelected()) {
|
|
||||||
int removed = inp.getTimesSelected(crd);
|
|
||||||
// sum += removed;
|
|
||||||
if(removed < 2) continue;
|
|
||||||
int oldVal = crd.getCounters().get(getCounter()).intValue();
|
|
||||||
crd.getCounters().put(getCounter(), Integer.valueOf(oldVal - removed + 1));
|
|
||||||
}
|
|
||||||
cntRemoved = 1;
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rift Elemental only - always removes 1 counter, so there will be no code for N counters.
|
|
||||||
List<Card> suspended = new ArrayList<Card>();
|
|
||||||
for(Card crd : validCards)
|
|
||||||
if(crd.getCounters( getCounter()) > 0 )
|
|
||||||
suspended.add(crd);
|
|
||||||
|
|
||||||
final Card card = GuiChoose.oneOrNone("Remove counter(s) from a card in " + getZone(), suspended);
|
|
||||||
return null == card ? null : PaymentDecision.card(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final CounterType counter;
|
|
||||||
private final ZoneType zone;
|
|
||||||
private int cntRemoved;
|
private int cntRemoved;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the counter.
|
* @param cntRemoved the cntRemoved to set
|
||||||
*
|
|
||||||
* @return the counter
|
|
||||||
*/
|
*/
|
||||||
public final CounterType getCounter() {
|
public void setCntRemoved(int cntRemoved) {
|
||||||
return this.counter;
|
this.cntRemoved = cntRemoved;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the zone
|
|
||||||
*/
|
|
||||||
public final ZoneType getZone() {
|
|
||||||
return zone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -293,7 +131,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean canPay(final SpellAbility ability) {
|
public final boolean canPay(final SpellAbility ability) {
|
||||||
final CounterType cntrs = this.getCounter();
|
final CounterType cntrs = this.counter;
|
||||||
final Player activator = ability.getActivatingPlayer();
|
final Player activator = ability.getActivatingPlayer();
|
||||||
final Card source = ability.getSourceCard();
|
final Card source = ability.getSourceCard();
|
||||||
final String type = this.getType();
|
final String type = this.getType();
|
||||||
@@ -309,7 +147,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
|||||||
if (type.equals("OriginalHost")) {
|
if (type.equals("OriginalHost")) {
|
||||||
typeList = Lists.newArrayList(ability.getOriginalHost());
|
typeList = Lists.newArrayList(ability.getOriginalHost());
|
||||||
} else {
|
} else {
|
||||||
typeList = CardLists.getValidCards(activator.getCardsIn(this.getZone()), type.split(";"), activator, source);
|
typeList = CardLists.getValidCards(activator.getCardsIn(this.zone), type.split(";"), activator, source);
|
||||||
}
|
}
|
||||||
if (amount != null) {
|
if (amount != null) {
|
||||||
for (Card c : typeList) {
|
for (Card c : typeList) {
|
||||||
@@ -354,7 +192,7 @@ public class CostRemoveCounter extends CostPartWithList {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPayment(SpellAbility ability, Card targetCard){
|
protected void doPayment(SpellAbility ability, Card targetCard){
|
||||||
targetCard.subtractCounter(this.getCounter(), cntRemoved);
|
targetCard.subtractCounter(this.counter, cntRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ package forge.game.cost;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostReturn.
|
* The Class CostReturn.
|
||||||
@@ -108,49 +106,6 @@ public class CostReturn extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
|
|
||||||
final List<Card> list = payer.getCardsIn(ZoneType.Battlefield);
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, list.size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
final Card card = ability.getSourceCard();
|
|
||||||
if (card.getController() == payer && card.isInPlay()) {
|
|
||||||
return payer.getController().confirmPayment(this, "Return " + card.getName() + " to hand?") ? PaymentDecision.card(card) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<Card> validCards = CardLists.getValidCards(ability.getActivatingPlayer().getCardsIn(ZoneType.Battlefield), this.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, validCards);
|
|
||||||
inp.setMessage("Return %d " + this.getType() + " " + this.getType() + " card(s) to hand");
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,24 +17,18 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
import forge.util.Lang;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostReveal.
|
* The Class CostReveal.
|
||||||
@@ -115,86 +109,6 @@ public class CostReveal extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
|
|
||||||
if (this.payCostFromSource())
|
|
||||||
return PaymentDecision.card(source);
|
|
||||||
|
|
||||||
if (this.getType().equals("Hand"))
|
|
||||||
return PaymentDecision.card(activator.getCardsIn(ZoneType.Hand));
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = null;
|
|
||||||
if (this.getType().equals("SameColor")) {
|
|
||||||
Integer num = this.convertAmount();
|
|
||||||
List<Card> handList = activator.getCardsIn(ZoneType.Hand);
|
|
||||||
final List<Card> handList2 = handList;
|
|
||||||
handList = CardLists.filter(handList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
for (Card card : handList2) {
|
|
||||||
if (!card.equals(c) && card.sharesColorWith(c)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (num == 0)
|
|
||||||
return PaymentDecision.number(0);
|
|
||||||
|
|
||||||
inp = new InputSelectCardsFromList(num, handList) {
|
|
||||||
private static final long serialVersionUID = 8338626212893374798L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCardSelected(Card c, MouseEvent triggerEvent) {
|
|
||||||
Card firstCard = Iterables.getFirst(this.selected, null);
|
|
||||||
if(firstCard != null && !CardPredicates.sharesColorWith(firstCard).apply(c))
|
|
||||||
return;
|
|
||||||
super.onCardSelected(c, triggerEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
inp.setMessage("Select " + Lang.nounWithAmount(num, "card" ) + " of same color to reveal.");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Integer num = this.convertAmount();
|
|
||||||
|
|
||||||
List<Card> handList = activator.getCardsIn(ZoneType.Hand);
|
|
||||||
handList = CardLists.getValidCards(handList, this.getType().split(";"), activator, ability.getSourceCard());
|
|
||||||
|
|
||||||
if (num == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
num = chooseXValue(source, ability, handList.size());
|
|
||||||
} else {
|
|
||||||
num = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( num == 0 )
|
|
||||||
return PaymentDecision.number(0);;
|
|
||||||
|
|
||||||
inp = new InputSelectCardsFromList(num, num, handList);
|
|
||||||
inp.setMessage("Select %d more " + getDescriptiveType() + " card(s) to reveal.");
|
|
||||||
}
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ package forge.game.cost;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostSacrifice.
|
* The Class CostSacrifice.
|
||||||
@@ -117,59 +115,6 @@ public class CostSacrifice extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
final String type = this.getType();
|
|
||||||
|
|
||||||
List<Card> list = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
|
||||||
list = CardLists.getValidCards(list, type.split(";"), activator, source);
|
|
||||||
if (activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) {
|
|
||||||
list = CardLists.getNotType(list, "Creature");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.payCostFromSource()) {
|
|
||||||
if (source.getController() == ability.getActivatingPlayer() && source.isInPlay()) {
|
|
||||||
return activator.getController().confirmPayment(this, "Sacrifice " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
|
||||||
} else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amount.equals("All"))
|
|
||||||
return PaymentDecision.card(list);
|
|
||||||
|
|
||||||
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
// Generalize this
|
|
||||||
if (ability.getSVar(amount).equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, list.size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (0 == c.intValue()) {
|
|
||||||
return PaymentDecision.number(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
|
||||||
inp.setMessage("Select a " + this.getDescriptiveType() + " to sacrifice (%d left)");
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if ( inp.hasCancelled() )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPayment(SpellAbility ability, Card targetCard) {
|
protected void doPayment(SpellAbility ability, Card targetCard) {
|
||||||
targetCard.getGame().getAction().sacrifice(targetCard, ability);
|
targetCard.getGame().getAction().sacrifice(targetCard, ability);
|
||||||
|
|||||||
@@ -84,23 +84,6 @@ public class CostTap extends CostPart {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
// if (!canPay(ability, source, ability.getActivatingPlayer(),
|
|
||||||
// payment.getCost()))
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
return PaymentDecision.number(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public <T> T accept(ICostVisitor<T> visitor) {
|
public <T> T accept(ICostVisitor<T> visitor) {
|
||||||
return visitor.visit(this);
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,12 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostTapType.
|
* The Class CostTapType.
|
||||||
@@ -161,107 +159,6 @@ public class CostTapType extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
|
|
||||||
String type = this.getType();
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
|
|
||||||
boolean sameType = false;
|
|
||||||
if (type.contains("sharesCreatureTypeWith")) {
|
|
||||||
sameType = true;
|
|
||||||
type = type.replace("sharesCreatureTypeWith", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean totalPower = false;
|
|
||||||
String totalP = "";
|
|
||||||
if (type.contains("+withTotalPowerGE")) {
|
|
||||||
totalPower = true;
|
|
||||||
totalP = type.split("withTotalPowerGE")[1];
|
|
||||||
type = type.replace("+withTotalPowerGE" + totalP, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
typeList = CardLists.getValidCards(typeList, type.split(";"), activator, ability.getSourceCard());
|
|
||||||
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
|
|
||||||
if (c == null && !amount.equals("Any")) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, typeList.size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sameType) {
|
|
||||||
final List<Card> List2 = typeList;
|
|
||||||
typeList = CardLists.filter(typeList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
for (Card card : List2) {
|
|
||||||
if (!card.equals(c) && card.sharesCreatureTypeWith(c)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (c == 0) return PaymentDecision.number(0);
|
|
||||||
List<Card> tapped = new ArrayList<Card>();
|
|
||||||
while (c > 0) {
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, typeList);
|
|
||||||
inp.setMessage("Select one of the cards to tap. Already chosen: " + tapped);
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
if (inp.hasCancelled())
|
|
||||||
return null;
|
|
||||||
final Card first = inp.getFirstSelected();
|
|
||||||
tapped.add(first);
|
|
||||||
typeList = CardLists.filter(typeList, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
return c.sharesCreatureTypeWith(first);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
typeList.remove(first);
|
|
||||||
c--;
|
|
||||||
}
|
|
||||||
return PaymentDecision.card(tapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalPower) {
|
|
||||||
int i = Integer.parseInt(totalP);
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(0, typeList.size(), typeList);
|
|
||||||
inp.setMessage("Select a card to tap.");
|
|
||||||
inp.setUnselectAllowed(true);
|
|
||||||
inp.setCancelAllowed(true);
|
|
||||||
inp.showAndWait();
|
|
||||||
|
|
||||||
if (inp.hasCancelled() || CardLists.getTotalPower(inp.getSelected()) < i) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, typeList);
|
|
||||||
inp.setMessage("Select a " + getDescriptiveType() + " to tap (%d left)");
|
|
||||||
inp.showAndWait();
|
|
||||||
if ( inp.hasCancelled() )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -86,24 +86,6 @@ public class CostUnattach extends CostPartWithList {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
|
|
||||||
Card cardToUnattach = findCardToUnattach(source, activator, ability);
|
|
||||||
if (cardToUnattach != null && activator.getController().confirmPayment(this, "Unattach " + cardToUnattach.getName() + "?")) {
|
|
||||||
return PaymentDecision.card(cardToUnattach);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Card findCardToUnattach(final Card source, Player activator, SpellAbility ability) {
|
public Card findCardToUnattach(final Card source, Player activator, SpellAbility ability) {
|
||||||
if (getType().equals("CARDNAME")) {
|
if (getType().equals("CARDNAME")) {
|
||||||
if (source.isEquipping()) {
|
if (source.isEquipping()) {
|
||||||
|
|||||||
@@ -75,18 +75,6 @@ public class CostUntap extends CostPart {
|
|||||||
return source.isTapped() && (!source.isSick() || source.hasKeyword("CARDNAME may activate abilities as though it has haste."));
|
return source.isTapped() && (!source.isSick() || source.hasKeyword("CARDNAME may activate abilities as though it has haste."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player activator) {
|
|
||||||
return PaymentDecision.number(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPart#payAI(forge.card.cost.PaymentDecision, forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPart#payAI(forge.card.cost.PaymentDecision, forge.game.player.AIPlayer, forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,14 +18,12 @@
|
|||||||
package forge.game.cost;
|
package forge.game.cost;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.input.InputSelectCardsFromList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class CostUntapType.
|
* The Class CostUntapType.
|
||||||
@@ -120,41 +118,6 @@ public class CostUntapType extends CostPartWithList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* forge.card.cost.CostPart#payHuman(forge.card.spellability.SpellAbility,
|
|
||||||
* forge.Card, forge.card.cost.Cost_Payment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final PaymentDecision payHuman(final SpellAbility ability, final Player payer) {
|
|
||||||
List<Card> typeList = CardLists.getValidCards(payer.getGame().getCardsIn(ZoneType.Battlefield), this.getType().split(";"),
|
|
||||||
payer, ability.getSourceCard());
|
|
||||||
typeList = CardLists.filter(typeList, Presets.TAPPED);
|
|
||||||
final Card source = ability.getSourceCard();
|
|
||||||
if (!canUntapSource) {
|
|
||||||
typeList.remove(source);
|
|
||||||
}
|
|
||||||
final String amount = this.getAmount();
|
|
||||||
Integer c = this.convertAmount();
|
|
||||||
if (c == null) {
|
|
||||||
final String sVar = ability.getSVar(amount);
|
|
||||||
// Generalize this
|
|
||||||
if (sVar.equals("XChoice")) {
|
|
||||||
c = chooseXValue(source, ability, typeList.size());
|
|
||||||
} else {
|
|
||||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, typeList);
|
|
||||||
inp.setMessage("Select a " + getDescriptiveType() + " to untap (%d left)");
|
|
||||||
inp.showAndWait();
|
|
||||||
if( inp.hasCancelled() || inp.getSelected().size() != c )
|
|
||||||
return null;
|
|
||||||
return PaymentDecision.card(inp.getSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
* @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card)
|
||||||
*/
|
*/
|
||||||
|
|||||||
1156
forge-gui/src/main/java/forge/gui/player/HumanCostDecision.java
Normal file
1156
forge-gui/src/main/java/forge/gui/player/HumanCostDecision.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -321,6 +321,8 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HumanCostDecision hcd = new HumanCostDecision(p, sourceAbility, source);
|
||||||
|
|
||||||
//the following costs do not need inputs
|
//the following costs do not need inputs
|
||||||
for (CostPart part : parts) {
|
for (CostPart part : parts) {
|
||||||
boolean mayRemovePart = true;
|
boolean mayRemovePart = true;
|
||||||
@@ -364,7 +366,7 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (part instanceof CostGainLife) {
|
else if (part instanceof CostGainLife) {
|
||||||
PaymentDecision pd = part.payHuman(sourceAbility, p);
|
PaymentDecision pd = part.accept(hcd);
|
||||||
|
|
||||||
if (pd == null)
|
if (pd == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -375,7 +377,7 @@ public class HumanPlay {
|
|||||||
if (!p.getController().confirmPayment(part, "Do you want to add " + ((CostAddMana) part).toString() + " to your mana pool?" + orString)) {
|
if (!p.getController().confirmPayment(part, "Do you want to add " + ((CostAddMana) part).toString() + " to your mana pool?" + orString)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PaymentDecision pd = part.payHuman(sourceAbility, p);
|
PaymentDecision pd = part.accept(hcd);
|
||||||
|
|
||||||
if (pd == null)
|
if (pd == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -452,7 +454,7 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (part instanceof CostRemoveCounter) {
|
else if (part instanceof CostRemoveCounter) {
|
||||||
CounterType counterType = ((CostRemoveCounter) part).getCounter();
|
CounterType counterType = ((CostRemoveCounter) part).counter;
|
||||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||||
|
|
||||||
if (!part.canPay(sourceAbility)) {
|
if (!part.canPay(sourceAbility)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user