mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
moved a gui reference out from costs
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -15013,6 +15013,7 @@ forge-gui/src/main/java/forge/game/cost/Cost.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/game/cost/CostAddMana.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostChooseCreatureType.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostDamage.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostDecisionMakerBase.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostDiscard.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostDraw.java -text
|
||||
forge-gui/src/main/java/forge/game/cost/CostExile.java -text
|
||||
|
||||
@@ -18,6 +18,7 @@ import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.cost.CostAddMana;
|
||||
import forge.game.cost.CostChooseCreatureType;
|
||||
import forge.game.cost.CostDamage;
|
||||
import forge.game.cost.CostDecisionMakerBase;
|
||||
import forge.game.cost.CostDiscard;
|
||||
import forge.game.cost.CostDraw;
|
||||
import forge.game.cost.CostExile;
|
||||
@@ -47,19 +48,18 @@ import forge.game.player.PlayerControllerAi;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public class AiCostDecision extends CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
|
||||
private final Player ai;
|
||||
private final SpellAbility ability;
|
||||
private final Card source;
|
||||
|
||||
public AiCostDecision(Player ai0, SpellAbility sa, Card source0) {
|
||||
ai = ai0;
|
||||
public AiCostDecision(Player ai0, SpellAbility sa) {
|
||||
super(ai0);
|
||||
ability = sa;
|
||||
source = source0;
|
||||
source = ability.getSourceCard();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostAddMana cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -74,7 +74,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseCreatureType cost) {
|
||||
String choice = ai.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>());
|
||||
String choice = player.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>());
|
||||
return PaymentDecision.type(choice);
|
||||
}
|
||||
|
||||
@@ -82,12 +82,12 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public PaymentDecision visit(CostDiscard cost) {
|
||||
final String type = cost.getType();
|
||||
|
||||
final List<Card> hand = ai.getCardsIn(ZoneType.Hand);
|
||||
final List<Card> hand = player.getCardsIn(ZoneType.Hand);
|
||||
if (type.equals("LastDrawn")) {
|
||||
if (!hand.contains(ai.getLastDrawnCard())) {
|
||||
if (!hand.contains(player.getLastDrawnCard())) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(ai.getLastDrawnCard());
|
||||
return PaymentDecision.card(player.getLastDrawnCard());
|
||||
}
|
||||
else if (cost.payCostFromSource()) {
|
||||
if (!hand.contains(source)) {
|
||||
@@ -116,7 +116,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return PaymentDecision.card(CardLists.getRandomSubList(hand, c));
|
||||
}
|
||||
else {
|
||||
final AiController aic = ((PlayerControllerAi)ai.getController()).getAi();
|
||||
final AiController aic = ((PlayerControllerAi)player.getController()).getAi();
|
||||
return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (cost.getType().equals("All")) {
|
||||
return PaymentDecision.card(ai.getCardsIn(cost.getFrom()));
|
||||
return PaymentDecision.card(player.getCardsIn(cost.getFrom()));
|
||||
}
|
||||
else if (cost.getType().contains("FromTopGrave")) {
|
||||
return null;
|
||||
@@ -173,14 +173,14 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (cost.getFrom().equals(ZoneType.Library)) {
|
||||
return PaymentDecision.card(ai.getCardsIn(ZoneType.Library, c));
|
||||
return PaymentDecision.card(player.getCardsIn(ZoneType.Library, c));
|
||||
}
|
||||
else if (cost.sameZone) {
|
||||
// TODO Determine exile from same zone for AI
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
List<Card> chosen = ComputerUtil.chooseExileFrom(ai, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
List<Card> chosen = ComputerUtil.chooseExileFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
return null == chosen ? null : PaymentDecision.card(chosen);
|
||||
}
|
||||
}
|
||||
@@ -195,9 +195,9 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
List<Card> typeList = ai.getGame().getCardsIn(ZoneType.Exile);
|
||||
List<Card> typeList = player.getGame().getCardsIn(ZoneType.Exile);
|
||||
|
||||
typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), ai, source);
|
||||
typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), player, source);
|
||||
|
||||
if (typeList.size() < c) {
|
||||
return null;
|
||||
@@ -237,7 +237,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
final List<Card> typeList = CardLists.getValidCards(ai.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ai, source);
|
||||
final List<Card> typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, source);
|
||||
|
||||
|
||||
if (typeList.size() < c) {
|
||||
@@ -258,7 +258,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public PaymentDecision visit(CostGainLife cost) {
|
||||
final List<Player> oppsThatCanGainLife = new ArrayList<Player>();
|
||||
|
||||
for (final Player opp : cost.getPotentialTargets(ai, source)) {
|
||||
for (final Player opp : cost.getPotentialTargets(player, source)) {
|
||||
if (opp.canGainLife()) {
|
||||
oppsThatCanGainLife.add(opp);
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
List<Card> topLib = ai.getCardsIn(ZoneType.Library, c);
|
||||
List<Card> topLib = player.getCardsIn(ZoneType.Library, c);
|
||||
return topLib.size() < c ? null : PaymentDecision.card(topLib);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
}
|
||||
if (!ai.canPayLife(c)) {
|
||||
if (!player.canPayLife(c)) {
|
||||
return null;
|
||||
}
|
||||
// activator.payLife(c, null);
|
||||
@@ -317,14 +317,14 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
@Override
|
||||
public PaymentDecision visit(CostPutCardToLib cost) {
|
||||
Integer c = cost.convertAmount();
|
||||
final Game game = ai.getGame();
|
||||
final Game game = player.getGame();
|
||||
List<Card> chosen = new ArrayList<Card>();
|
||||
List<Card> list;
|
||||
|
||||
if (cost.isSameZone()) {
|
||||
list = new ArrayList<Card>(game.getCardsIn(cost.getFrom()));
|
||||
} else {
|
||||
list = new ArrayList<Card>(ai.getCardsIn(cost.getFrom()));
|
||||
list = new ArrayList<Card>(player.getCardsIn(cost.getFrom()));
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
@@ -337,7 +337,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
list = CardLists.getValidCards(list, cost.getType().split(";"), ai, source);
|
||||
list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
if (cost.isSameZone()) {
|
||||
// Jotun Grunt
|
||||
@@ -352,7 +352,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
chosen = chosen.subList(0, c);
|
||||
} else {
|
||||
chosen = ComputerUtil.choosePutToLibraryFrom(ai, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
chosen = ComputerUtil.choosePutToLibraryFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
}
|
||||
return chosen.isEmpty() ? null : PaymentDecision.card(chosen);
|
||||
}
|
||||
@@ -365,7 +365,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
}
|
||||
|
||||
final List<Card> typeList = CardLists.getValidCards(ai.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ai, source);
|
||||
final List<Card> typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, source);
|
||||
|
||||
Card card = null;
|
||||
if (cost.getType().equals("Creature.YouCtrl")) {
|
||||
@@ -390,7 +390,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
if (sVar.equals("XChoice")) {
|
||||
List<Card> typeList =
|
||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
|
||||
CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), ability.getActivatingPlayer(), ability.getSourceCard());
|
||||
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
|
||||
c = typeList.size();
|
||||
source.setSVar("ChosenX", "Number$" + Integer.toString(c));
|
||||
@@ -402,7 +402,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Card> totap = ComputerUtil.chooseTapType(ai, cost.getType(), source, !cost.canTapSource, c);
|
||||
List<Card> totap = ComputerUtil.chooseTapType(player, cost.getType(), source, !cost.canTapSource, c);
|
||||
|
||||
|
||||
if (totap == null) {
|
||||
@@ -437,7 +437,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
List<Card> list = ComputerUtil.chooseSacrificeType(ai, cost.getType(), source, ability.getTargetCard(), c);
|
||||
List<Card> list = ComputerUtil.chooseSacrificeType(player, cost.getType(), source, ability.getTargetCard(), c);
|
||||
return PaymentDecision.card(list);
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
List<Card> res = ComputerUtil.chooseReturnType(ai, cost.getType(), source, ability.getTargetCard(), c);
|
||||
List<Card> res = ComputerUtil.chooseReturnType(player, cost.getType(), source, ability.getTargetCard(), c);
|
||||
return res.isEmpty() ? null : PaymentDecision.card(res);
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public PaymentDecision visit(CostReveal cost) {
|
||||
|
||||
final String type = cost.getType();
|
||||
List<Card> hand = new ArrayList<Card>(ai.getCardsIn(ZoneType.Hand));
|
||||
List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
if (!hand.contains(source)) {
|
||||
@@ -469,13 +469,13 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (cost.getType().equals("Hand"))
|
||||
return PaymentDecision.card(ai.getCardsIn(ZoneType.Hand));
|
||||
return PaymentDecision.card(player.getCardsIn(ZoneType.Hand));
|
||||
|
||||
if (cost.getType().equals("SameColor")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
hand = CardLists.getValidCards(hand, type.split(";"), ai, source);
|
||||
hand = CardLists.getValidCards(hand, type.split(";"), player, source);
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(cost.getAmount());
|
||||
@@ -486,7 +486,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
final AiController aic = ((PlayerControllerAi)ai.getController()).getAi();
|
||||
final AiController aic = ((PlayerControllerAi)player.getController()).getAi();
|
||||
return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
final int c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
final String type = cost.getType();
|
||||
|
||||
List<Card> typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), ai, source);
|
||||
List<Card> typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, source);
|
||||
List<Card> hperms = CardLists.filter(typeList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card crd) {
|
||||
@@ -536,7 +536,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
if (type.equals("OriginalHost")) {
|
||||
typeList = Lists.newArrayList(ability.getOriginalHost());
|
||||
} else {
|
||||
typeList = CardLists.getValidCards(ai.getCardsIn(cost.zone), type.split(";"), ai, source);
|
||||
typeList = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
|
||||
}
|
||||
for (Card card : typeList) {
|
||||
if (card.getCounters(cost.counter) >= c) {
|
||||
@@ -563,8 +563,8 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
if (sVar.equals("XChoice")) {
|
||||
List<Card> typeList = ai.getGame().getCardsIn(ZoneType.Battlefield);
|
||||
typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), ai, ability.getSourceCard());
|
||||
List<Card> typeList = player.getGame().getCardsIn(ZoneType.Battlefield);
|
||||
typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), player, ability.getSourceCard());
|
||||
if (!cost.canUntapSource) {
|
||||
typeList.remove(source);
|
||||
}
|
||||
@@ -576,7 +576,7 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Card> list = ComputerUtil.chooseUntapType(ai, cost.getType(), source, cost.canUntapSource, c);
|
||||
List<Card> list = ComputerUtil.chooseUntapType(player, cost.getType(), source, cost.canUntapSource, c);
|
||||
|
||||
if (list == null) {
|
||||
System.out.println("Couldn't find a valid card to untap for: " + source.getName());
|
||||
@@ -593,12 +593,17 @@ public class AiCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostUnattach cost) {
|
||||
Card cardToUnattach = cost.findCardToUnattach(source, (Player) ai, ability);
|
||||
Card cardToUnattach = cost.findCardToUnattach(source, (Player) player, ability);
|
||||
if (cardToUnattach == null) {
|
||||
// We really shouldn't be able to get here if there's nothing to unattach
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(cardToUnattach);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean paysRightAfterDecision() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ComputerUtil {
|
||||
}
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
if (pay.payComputerCosts(new AiCostDecision(ai, sa))) {
|
||||
game.getStack().addAndUnfreeze(sa);
|
||||
if (sa.getSplicedCards() != null && !sa.getSplicedCards().isEmpty()) {
|
||||
game.getAction().reveal(sa.getSplicedCards(), ai, true, "Computer reveals spliced cards from ");
|
||||
@@ -240,7 +240,7 @@ public class ComputerUtil {
|
||||
game.getStack().add(sa);
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
if (pay.payComputerCosts(ai, game)) {
|
||||
if (pay.payComputerCosts(new AiCostDecision(ai, sa))) {
|
||||
game.getStack().add(sa);
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
final CostPayment pay = new CostPayment(newSA.getPayCosts(), newSA);
|
||||
pay.payComputerCosts(ai, game);
|
||||
pay.payComputerCosts(new AiCostDecision(ai, sa));
|
||||
|
||||
game.getStack().add(newSA);
|
||||
}
|
||||
@@ -314,7 +314,7 @@ public class ComputerUtil {
|
||||
ComputerUtilMana.payManaCost(ai, sa);
|
||||
} else {
|
||||
final CostPayment pay = new CostPayment(cost, sa);
|
||||
pay.payComputerCosts(ai, game);
|
||||
pay.payComputerCosts(new AiCostDecision(ai, sa));
|
||||
}
|
||||
|
||||
AbilityUtils.resolve(sa);
|
||||
|
||||
@@ -209,7 +209,7 @@ public class ComputerUtilMana {
|
||||
else {
|
||||
if (saPayment.getPayCosts() != null) {
|
||||
final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment);
|
||||
if (!pay.payComputerCosts(ai, ai.getGame())) {
|
||||
if (!pay.payComputerCosts(new AiCostDecision(ai, sa))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
AiCostDecision aiDecisions = new AiCostDecision(ai, sa, source);
|
||||
AiCostDecision aiDecisions = new AiCostDecision(ai, sa);
|
||||
for (final CostPart part : abCost.getCostParts()) {
|
||||
if (part instanceof CostDiscard) {
|
||||
PaymentDecision decision = part.accept(aiDecisions);
|
||||
|
||||
@@ -154,7 +154,10 @@ public class Cost {
|
||||
parsedMana = new CostPartMana(new ManaCost(new ManaCostParser(manaParts.toString())), xCantBe0 ? "XCantBe0" : null);
|
||||
}
|
||||
if (parsedMana != null) {
|
||||
this.costParts.add(0, parsedMana);
|
||||
if(parsedMana.shouldPayLast()) // back from the brink pays mana after 'exile' part is paid
|
||||
this.costParts.add(parsedMana);
|
||||
else
|
||||
this.costParts.add(0, parsedMana);
|
||||
}
|
||||
|
||||
// inspect parts to set Sac, {T} and {Q} flags
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package forge.game.cost;
|
||||
|
||||
import forge.game.player.Player;
|
||||
|
||||
public abstract class CostDecisionMakerBase implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
protected final Player player;
|
||||
public CostDecisionMakerBase(Player player0) {
|
||||
player = player0;
|
||||
}
|
||||
public Player getPlayer() { return player; }
|
||||
public abstract boolean paysRightAfterDecision();
|
||||
}
|
||||
@@ -29,8 +29,12 @@ public class CostPartMana extends CostPart {
|
||||
// "Leftover"
|
||||
private final ManaCost cost;
|
||||
private boolean xCantBe0 = false;
|
||||
private boolean isRememberedCreatureCost = false;
|
||||
private final String restriction;
|
||||
|
||||
public boolean shouldPayLast() {
|
||||
return isRememberedCreatureCost;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new cost mana.
|
||||
*
|
||||
@@ -43,7 +47,8 @@ public class CostPartMana extends CostPart {
|
||||
public CostPartMana(final ManaCost cost, String restriction) {
|
||||
this.cost = cost;
|
||||
this.xCantBe0 = "XCantBe0".equals(restriction);
|
||||
this.restriction = xCantBe0 ? null : restriction;
|
||||
this.isRememberedCreatureCost = "Remembered".equalsIgnoreCase(restriction);
|
||||
this.restriction = xCantBe0 || isRememberedCreatureCost ? null : restriction;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,15 +19,12 @@ package forge.game.cost;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import forge.ai.AiCostDecision;
|
||||
import forge.game.Game;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.gui.player.HumanCostDecision;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -134,20 +131,12 @@ public class CostPayment {
|
||||
this.ability.getActivatingPlayer().getManaPool().refundManaPaid(this.ability);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* payCost.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public boolean payCost(final Player payer) {
|
||||
HumanCostDecision hcd = new HumanCostDecision(payer, ability, ability.getSourceCard());
|
||||
public boolean payCost(final CostDecisionMakerBase decisionMaker) {
|
||||
|
||||
for (final CostPart part : this.cost.getCostParts()) {
|
||||
PaymentDecision pd = part.accept(hcd);
|
||||
PaymentDecision pd = part.accept(decisionMaker);
|
||||
|
||||
if ( null == pd || !part.payAsDecided(payer, pd, ability))
|
||||
if ( null == pd || !part.payAsDecided(decisionMaker.getPlayer(), pd, ability))
|
||||
return false;
|
||||
|
||||
// abilities care what was used to pay for them
|
||||
@@ -166,35 +155,26 @@ public class CostPayment {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* payComputerCosts.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
public final boolean payComputerCosts(final Player ai, final Game game) {
|
||||
// canPayAdditionalCosts now Player Agnostic
|
||||
|
||||
public final boolean payComputerCosts(final CostDecisionMakerBase decisionMaker) {
|
||||
// Just in case it wasn't set, but honestly it shouldn't have gotten
|
||||
// here without being set
|
||||
this.ability.setActivatingPlayer(ai);
|
||||
|
||||
final Card source = this.ability.getSourceCard();
|
||||
final List<CostPart> parts = this.cost.getCostParts();
|
||||
this.ability.setActivatingPlayer(decisionMaker.getPlayer());
|
||||
|
||||
Map<Class<? extends CostPart>, PaymentDecision> decisions = new HashMap<Class<? extends CostPart>, PaymentDecision>();
|
||||
AiCostDecision aiDecisions = new AiCostDecision(ai, ability, source);
|
||||
|
||||
|
||||
// Set all of the decisions before attempting to pay anything
|
||||
for (final CostPart part : parts) {
|
||||
PaymentDecision decision = part.accept(aiDecisions);
|
||||
if ( null == decision ) return false;
|
||||
for (final CostPart part : this.cost.getCostParts()) {
|
||||
PaymentDecision decision = part.accept(decisionMaker);
|
||||
if (null == decision) return false;
|
||||
|
||||
if (decisionMaker.paysRightAfterDecision() && !part.payAsDecided(decisionMaker.getPlayer(), decision, ability))
|
||||
return false;
|
||||
|
||||
decisions.put(part.getClass(), decision);
|
||||
}
|
||||
|
||||
for (final CostPart part : parts) {
|
||||
if (!part.payAsDecided(ai, decisions.get(part.getClass()), this.ability)) {
|
||||
for (final CostPart part : this.cost.getCostParts()) {
|
||||
if (!part.payAsDecided(decisionMaker.getPlayer(), decisions.get(part.getClass()), this.ability)) {
|
||||
return false;
|
||||
}
|
||||
// abilities care what was used to pay for them
|
||||
|
||||
@@ -33,6 +33,7 @@ import forge.game.cost.CostPayment;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.gui.player.HumanCostDecision;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -74,7 +75,7 @@ public class HumanPlaySpellAbility {
|
||||
boolean prerequisitesMet = this.announceValuesLikeX()
|
||||
&& this.announceType()
|
||||
&& (!mayChooseTargets || setupTargets()) // if you can choose targets, then do choose them.
|
||||
&& (isFree || this.payment.payCost(human));
|
||||
&& (isFree || this.payment.payCost(new HumanCostDecision(human, ability, ability.getSourceCard())));
|
||||
|
||||
if (!prerequisitesMet) {
|
||||
if (!ability.isTrigger()) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.cost.CostAddMana;
|
||||
import forge.game.cost.CostChooseCreatureType;
|
||||
import forge.game.cost.CostDamage;
|
||||
import forge.game.cost.CostDecisionMakerBase;
|
||||
import forge.game.cost.CostDiscard;
|
||||
import forge.game.cost.CostDraw;
|
||||
import forge.game.cost.CostExile;
|
||||
@@ -47,7 +48,6 @@ import forge.game.cost.CostTapType;
|
||||
import forge.game.cost.CostUnattach;
|
||||
import forge.game.cost.CostUntap;
|
||||
import forge.game.cost.CostUntapType;
|
||||
import forge.game.cost.ICostVisitor;
|
||||
import forge.game.cost.PaymentDecision;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -59,14 +59,13 @@ import forge.gui.input.InputSelectManyBase;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.Lang;
|
||||
|
||||
public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
|
||||
private final Player payer;
|
||||
private final SpellAbility ability;
|
||||
private final Card source;
|
||||
|
||||
public HumanCostDecision(Player p, SpellAbility sa, Card source) {
|
||||
payer = p;
|
||||
super(p);
|
||||
ability = sa;
|
||||
this.source = source;
|
||||
}
|
||||
@@ -77,7 +76,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return AbilityFactory.calculateAmount(card, "ChosenX", null);
|
||||
}*/
|
||||
|
||||
int chosenX = payer.getController().chooseNumber(ability, source.toString() + " - Choose a Value for X", 0, maxValue);
|
||||
int chosenX = player.getController().chooseNumber(ability, source.toString() + " - Choose a Value for X", 0, maxValue);
|
||||
ability.setSVar("ChosenX", Integer.toString(chosenX));
|
||||
source.setSVar("ChosenX", Integer.toString(chosenX));
|
||||
return chosenX;
|
||||
@@ -94,7 +93,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostChooseCreatureType cost) {
|
||||
String choice = payer.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>(), true);
|
||||
String choice = player.getController().chooseSomeType("Creature", ability, new ArrayList<String>(CardType.getCreatureTypes()), new ArrayList<String>(), true);
|
||||
if( null == choice )
|
||||
return null;
|
||||
return PaymentDecision.type(choice);
|
||||
@@ -102,7 +101,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostDiscard cost) {
|
||||
List<Card> handList = new ArrayList<Card>(payer.getCardsIn(ZoneType.Hand));
|
||||
List<Card> handList = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));
|
||||
String discardType = cost.getType();
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
@@ -115,7 +114,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (discardType.equals("LastDrawn")) {
|
||||
final Card lastDrawn = payer.getLastDrawnCard();
|
||||
final Card lastDrawn = player.getLastDrawnCard();
|
||||
return handList.contains(lastDrawn) ? PaymentDecision.card(lastDrawn) : null;
|
||||
}
|
||||
|
||||
@@ -137,7 +136,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
if (discardType.contains("+WithSameName")) {
|
||||
String type = discardType.replace("+WithSameName", "");
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), payer, source);
|
||||
handList = CardLists.getValidCards(handList, type.split(";"), player, source);
|
||||
final List<Card> landList2 = handList;
|
||||
handList = CardLists.filter(handList, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -171,7 +170,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
String type = new String(discardType);
|
||||
final String[] validType = type.split(";");
|
||||
handList = CardLists.getValidCards(handList, validType, payer, source);
|
||||
handList = CardLists.getValidCards(handList, validType, player, source);
|
||||
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
@@ -198,7 +197,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
@Override
|
||||
public PaymentDecision visit(CostDamage cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final int life = payer.getLife();
|
||||
final int life = player.getLife();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
@@ -212,7 +211,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
if (payer.canPayLife(c) && payer.getController().confirmPayment(cost, "Pay " + c + " Life?")) {
|
||||
if (player.canPayLife(c) && player.getController().confirmPayment(cost, "Pay " + c + " Life?")) {
|
||||
return PaymentDecision.number(c);
|
||||
}
|
||||
return null;
|
||||
@@ -227,7 +226,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
|
||||
if (!payer.getController().confirmPayment(cost, "Draw " + c + " Card" + (c == 1 ? "" : "s"))) {
|
||||
if (!player.getController().confirmPayment(cost, "Draw " + c + " Card" + (c == 1 ? "" : "s"))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -237,7 +236,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
@Override
|
||||
public PaymentDecision visit(CostExile cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final Game game = payer.getGame();
|
||||
final Game game = player.getGame();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
String type = cost.getType();
|
||||
@@ -258,18 +257,18 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
list = new ArrayList<Card>(game.getCardsIn(cost.from));
|
||||
}
|
||||
else {
|
||||
list = new ArrayList<Card>(payer.getCardsIn(cost.from));
|
||||
list = new ArrayList<Card>(player.getCardsIn(cost.from));
|
||||
}
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
return source.getZone() == payer.getZone(cost.from) && payer.getController().confirmPayment(cost, "Exile " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
||||
return source.getZone() == player.getZone(cost.from) && player.getController().confirmPayment(cost, "Exile " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
||||
|
||||
}
|
||||
|
||||
if (type.equals("All")) {
|
||||
return PaymentDecision.card(list);
|
||||
}
|
||||
list = CardLists.getValidCards(list, type.split(";"), payer, source);
|
||||
list = CardLists.getValidCards(list, type.split(";"), player, source);
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
// Generalize this
|
||||
@@ -290,7 +289,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (cost.from == ZoneType.Stack) { return exileFromStack(cost, ability, c); }
|
||||
if (cost.from == ZoneType.Library) { return exileFromTop(cost, ability, payer, c); }
|
||||
if (cost.from == ZoneType.Library) { return exileFromTop(cost, ability, player, c); }
|
||||
if (fromTopGrave) { return exileFromTopGraveType(ability, c, list); }
|
||||
if (!cost.sameZone) { return exileFromMiscZone(cost, ability, c, list); }
|
||||
|
||||
@@ -383,12 +382,12 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return PaymentDecision.card(exiled);
|
||||
}
|
||||
|
||||
private PaymentDecision exileFromTop(final CostExile cost, final SpellAbility sa, final Player payer, final int nNeeded) {
|
||||
private PaymentDecision exileFromTop(final CostExile cost, final SpellAbility sa, final Player player, 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);
|
||||
final List<Card> list = player.getCardsIn(ZoneType.Library, nNeeded);
|
||||
|
||||
if (list.size() > nNeeded || !payer.getController().confirmPayment(cost, "Exile " + Lang.nounWithAmount(nNeeded, "card") + " from the top of your library?")) {
|
||||
if (list.size() > nNeeded || !player.getController().confirmPayment(cost, "Exile " + Lang.nounWithAmount(nNeeded, "card") + " from the top of your library?")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -463,8 +462,8 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
if (c == null) {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
final List<Card> list = payer.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> validCards = CardLists.getValidCards(list, cost.getType().split(";"), payer, source);
|
||||
final List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
List<Card> validCards = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, validCards);
|
||||
final String desc = cost.getTypeDescription() == null ? cost.getType() : cost.getTypeDescription();
|
||||
@@ -480,7 +479,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public PaymentDecision visit(CostGainLife cost) {
|
||||
final String amount = cost.getAmount();
|
||||
|
||||
final int life = payer.getLife();
|
||||
final int life = player.getLife();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
@@ -494,7 +493,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
final List<Player> oppsThatCanGainLife = new ArrayList<Player>();
|
||||
for (final Player opp : cost.getPotentialTargets(payer, source)) {
|
||||
for (final Player opp : cost.getPotentialTargets(player, source)) {
|
||||
if (opp.canGainLife()) {
|
||||
oppsThatCanGainLife.add(opp);
|
||||
}
|
||||
@@ -528,16 +527,16 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!payer.getController().confirmPayment(cost, "Mill " + c + " card" + (c == 1 ? "" : "s") + " from your library?")) {
|
||||
if (!player.getController().confirmPayment(cost, "Mill " + c + " card" + (c == 1 ? "" : "s") + " from your library?")) {
|
||||
return null;
|
||||
}
|
||||
return PaymentDecision.card(payer.getCardsIn(ZoneType.Library, c));
|
||||
return PaymentDecision.card(player.getCardsIn(ZoneType.Library, c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostPayLife cost) {
|
||||
final String amount = cost.getAmount();
|
||||
final int life = payer.getLife();
|
||||
final int life = player.getLife();
|
||||
|
||||
Integer c = cost.convertAmount();
|
||||
if (c == null) {
|
||||
@@ -555,7 +554,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
if (payer.canPayLife(c) && payer.getController().confirmPayment(cost, "Pay " + c + " Life?")) {
|
||||
if (player.canPayLife(c) && player.getController().confirmPayment(cost, "Pay " + c + " Life?")) {
|
||||
return PaymentDecision.number(c);
|
||||
}
|
||||
return null;
|
||||
@@ -572,7 +571,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
List<Card> list = cost.sameZone ? payer.getGame().getCardsIn(cost.getFrom()) : payer.getCardsIn(cost.getFrom());
|
||||
List<Card> list = cost.sameZone ? player.getGame().getCardsIn(cost.getFrom()) : player.getCardsIn(cost.getFrom());
|
||||
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
@@ -584,7 +583,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
}
|
||||
|
||||
list = CardLists.getValidCards(list, cost.getType().split(";"), payer, source);
|
||||
list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);
|
||||
|
||||
if (cost.from == ZoneType.Hand) {
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(c, c, list);
|
||||
@@ -595,7 +594,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
if (cost.sameZone){
|
||||
List<Player> players = payer.getGame().getPlayers();
|
||||
List<Player> players = player.getGame().getPlayers();
|
||||
List<Player> payableZone = new ArrayList<Player>();
|
||||
for (Player p : players) {
|
||||
List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
|
||||
@@ -664,7 +663,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
|
||||
// Cards to use this branch: Scarscale Ritual, Wandering Mage - each adds only one counter
|
||||
List<Card> typeList = CardLists.getValidCards(payer.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), payer, ability.getSourceCard());
|
||||
List<Card> typeList = CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), player, ability.getSourceCard());
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, typeList);
|
||||
inp.setMessage("Put " + Lang.nounWithAmount(c, cost.getCounter().getName() + " counter") + " on " +cost.getDescriptiveType());
|
||||
@@ -682,7 +681,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
|
||||
final List<Card> list = payer.getCardsIn(ZoneType.Battlefield);
|
||||
final List<Card> list = player.getCardsIn(ZoneType.Battlefield);
|
||||
if (c == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
// Generalize this
|
||||
@@ -694,8 +693,8 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
}
|
||||
if (cost.payCostFromSource()) {
|
||||
final Card card = ability.getSourceCard();
|
||||
if (card.getController() == payer && card.isInPlay()) {
|
||||
return payer.getController().confirmPayment(cost, "Return " + card.getName() + " to hand?") ? PaymentDecision.card(card) : null;
|
||||
if (card.getController() == player && card.isInPlay()) {
|
||||
return player.getController().confirmPayment(cost, "Return " + card.getName() + " to hand?") ? PaymentDecision.card(card) : null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -721,12 +720,12 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return PaymentDecision.card(source);
|
||||
|
||||
if (cost.getType().equals("Hand"))
|
||||
return PaymentDecision.card(payer.getCardsIn(ZoneType.Hand));
|
||||
return PaymentDecision.card(player.getCardsIn(ZoneType.Hand));
|
||||
|
||||
InputSelectCardsFromList inp = null;
|
||||
if (cost.getType().equals("SameColor")) {
|
||||
Integer num = cost.convertAmount();
|
||||
List<Card> handList = payer.getCardsIn(ZoneType.Hand);
|
||||
List<Card> handList = player.getCardsIn(ZoneType.Hand);
|
||||
final List<Card> handList2 = handList;
|
||||
handList = CardLists.filter(handList, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -758,8 +757,8 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
} else {
|
||||
Integer num = cost.convertAmount();
|
||||
|
||||
List<Card> handList = payer.getCardsIn(ZoneType.Hand);
|
||||
handList = CardLists.getValidCards(handList, cost.getType().split(";"), payer, ability.getSourceCard());
|
||||
List<Card> handList = player.getCardsIn(ZoneType.Hand);
|
||||
handList = CardLists.getValidCards(handList, cost.getType().split(";"), player, ability.getSourceCard());
|
||||
|
||||
if (num == null) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
@@ -792,8 +791,8 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
List<Card> list = new ArrayList<Card>(payer.getCardsIn(ZoneType.Battlefield));
|
||||
list = CardLists.getValidCards(list, type.split(";"), payer, source);
|
||||
List<Card> list = new ArrayList<Card>(player.getCardsIn(ZoneType.Battlefield));
|
||||
list = CardLists.getValidCards(list, type.split(";"), player, source);
|
||||
|
||||
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@@ -930,7 +929,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
return res;
|
||||
}
|
||||
|
||||
List<Card> validCards = CardLists.getValidCards(payer.getCardsIn(cost.zone), type.split(";"), payer, source);
|
||||
List<Card> validCards = CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
|
||||
if (cost.zone.equals(ZoneType.Battlefield)) {
|
||||
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(cntRemoved, cost.counter, validCards);
|
||||
inp.setMessage("Remove %d " + cost.counter.getName() + " counters from " + cost.getDescriptiveType());
|
||||
@@ -969,15 +968,15 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
final String amount = cost.getAmount();
|
||||
final String type = cost.getType();
|
||||
|
||||
List<Card> list = new ArrayList<Card>(payer.getCardsIn(ZoneType.Battlefield));
|
||||
list = CardLists.getValidCards(list, type.split(";"), payer, source);
|
||||
if (payer.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) {
|
||||
List<Card> list = new ArrayList<Card>(player.getCardsIn(ZoneType.Battlefield));
|
||||
list = CardLists.getValidCards(list, type.split(";"), player, source);
|
||||
if (player.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) {
|
||||
list = CardLists.getNotType(list, "Creature");
|
||||
}
|
||||
|
||||
if (cost.payCostFromSource()) {
|
||||
if (source.getController() == ability.getActivatingPlayer() && source.isInPlay()) {
|
||||
return payer.getController().confirmPayment(cost, "Sacrifice " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
||||
return player.getController().confirmPayment(cost, "Sacrifice " + source.getName() + "?") ? PaymentDecision.card(source) : null;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
@@ -1020,7 +1019,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostTapType cost) {
|
||||
List<Card> typeList = new ArrayList<Card>(payer.getCardsIn(ZoneType.Battlefield));
|
||||
List<Card> typeList = new ArrayList<Card>(player.getCardsIn(ZoneType.Battlefield));
|
||||
String type = cost.getType();
|
||||
final String amount = cost.getAmount();
|
||||
Integer c = cost.convertAmount();
|
||||
@@ -1039,7 +1038,7 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
type = type.replace("+withTotalPowerGE" + totalP, "");
|
||||
}
|
||||
|
||||
typeList = CardLists.getValidCards(typeList, type.split(";"), payer, ability.getSourceCard());
|
||||
typeList = CardLists.getValidCards(typeList, type.split(";"), player, ability.getSourceCard());
|
||||
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
|
||||
if (c == null && !amount.equals("Any")) {
|
||||
final String sVar = ability.getSVar(amount);
|
||||
@@ -1113,8 +1112,8 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
|
||||
@Override
|
||||
public PaymentDecision visit(CostUntapType cost) {
|
||||
List<Card> typeList = CardLists.getValidCards(payer.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"),
|
||||
payer, ability.getSourceCard());
|
||||
List<Card> typeList = CardLists.getValidCards(player.getGame().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"),
|
||||
player, ability.getSourceCard());
|
||||
typeList = CardLists.filter(typeList, Presets.TAPPED);
|
||||
if (!cost.canUntapSource) {
|
||||
typeList.remove(source);
|
||||
@@ -1147,10 +1146,15 @@ public class HumanCostDecision implements ICostVisitor<PaymentDecision> {
|
||||
public PaymentDecision visit(CostUnattach cost) {
|
||||
final Card source = ability.getSourceCard();
|
||||
|
||||
Card cardToUnattach = cost.findCardToUnattach(source, payer, ability);
|
||||
if (cardToUnattach != null && payer.getController().confirmPayment(cost, "Unattach " + cardToUnattach.getName() + "?")) {
|
||||
Card cardToUnattach = cost.findCardToUnattach(source, player, ability);
|
||||
if (cardToUnattach != null && player.getController().confirmPayment(cost, "Unattach " + cardToUnattach.getName() + "?")) {
|
||||
return PaymentDecision.card(cardToUnattach);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean paysRightAfterDecision() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user