removed manaCost from SpellAbility, use payCost instead.

removed Card arguement from Cost ctor
This commit is contained in:
Maxmtg
2013-04-15 08:31:37 +00:00
parent 1a721fc2b0
commit 4143c472ff
25 changed files with 127 additions and 201 deletions

View File

@@ -2110,7 +2110,7 @@ public class Card extends GameEntity implements Comparable<Card> {
} else if (keyword.startsWith("Morph")) {
sbLong.append("Morph");
if (keyword.contains(":")) {
final Cost mCost = new Cost(this, keywords.get(i).substring(6), true);
final Cost mCost = new Cost(keywords.get(i).substring(6), true);
if (!mCost.isOnlyManaCost()) {
sbLong.append(" -");
}
@@ -2147,12 +2147,12 @@ public class Card extends GameEntity implements Comparable<Card> {
} else if (keyword.startsWith("AlternateAdditionalCost")) {
final String costString1 = keyword.split(":")[1];
final String costString2 = keyword.split(":")[2];
final Cost cost1 = new Cost(this, costString1, false);
final Cost cost2 = new Cost(this, costString2, false);
final Cost cost1 = new Cost(costString1, false);
final Cost cost2 = new Cost(costString2, false);
sbLong.append("As an additional cost to cast " + this.getName() + ", " + cost1.toSimpleString()
+ " or pay " + cost2.toSimpleString() + ".\r\n");
} else if (keyword.startsWith("Kicker")) {
final Cost cost = new Cost(this, keywords.get(i).substring(7), false);
final Cost cost = new Cost(keywords.get(i).substring(7), false);
sbLong.append("Kicker " + cost.toSimpleString() + "\r\n");
} else if (keyword.endsWith(".") && !keywords.get(i).startsWith("Haunt")) {
sbLong.append(keywords.get(i).toString()).append("\r\n");
@@ -2404,7 +2404,7 @@ public class Card extends GameEntity implements Comparable<Card> {
if (keyword.startsWith("Flashback")) {
sb.append("Flashback");
if (keyword.contains(" ")) {
final Cost fbCost = new Cost(this, keyword.substring(10), true);
final Cost fbCost = new Cost(keyword.substring(10), true);
if (!fbCost.isOnlyManaCost()) {
sb.append(" -");
}
@@ -2415,19 +2415,19 @@ public class Card extends GameEntity implements Comparable<Card> {
}
sb.append("\r\n");
} else if (keyword.startsWith("Splice")) {
final Cost cost = new Cost(this, keyword.substring(19), false);
final Cost cost = new Cost(keyword.substring(19), false);
sb.append("Splice onto Arcane " + cost.toSimpleString() + "\r\n");
} else if (keyword.startsWith("Buyback")) {
final Cost cost = new Cost(this, keyword.substring(8), false);
final Cost cost = new Cost(keyword.substring(8), false);
sb.append("Buyback " + cost.toSimpleString() + "\r\n");
} else if (keyword.startsWith("Kicker")) {
final Cost cost = new Cost(this, keyword.substring(7), false);
final Cost cost = new Cost(keyword.substring(7), false);
sb.append("Kicker " + cost.toSimpleString() + "\r\n");
} else if (keyword.startsWith("AlternateAdditionalCost")) {
final String costString1 = keyword.split(":")[1];
final String costString2 = keyword.split(":")[2];
final Cost cost1 = new Cost(this, costString1, false);
final Cost cost2 = new Cost(this, costString2, false);
final Cost cost1 = new Cost(costString1, false);
final Cost cost2 = new Cost(costString2, false);
sb.append("As an additional cost to cast " + this.getName() + ", " + cost1.toSimpleString()
+ " or pay " + cost2.toSimpleString() + ".\r\n");
} else if (keyword.startsWith("Storm")) {

View File

@@ -116,7 +116,7 @@ public final class AbilityFactory {
if (!mapParams.containsKey("Cost")) {
throw new RuntimeException("AbilityFactory : getAbility -- no Cost in " + hostCard.getName());
}
abCost = new Cost(hostCard, mapParams.get("Cost"), type == AbilityRecordType.Ability);
abCost = new Cost(mapParams.get("Cost"), type == AbilityRecordType.Ability);
}
return abCost;
}

View File

@@ -1107,7 +1107,7 @@ public class AbilityUtils {
unlessCost = Integer.toString(calculateAmount(source, sa.getParam("UnlessCost").replace(" ", ""), sa));
}
final Cost cost = new Cost(source, unlessCost, true);
final Cost cost = new Cost(unlessCost, true);
final Ability ability = new AbilityStatic(source, cost, sa.getTarget()) {
@Override
public void resolve() { /* nothing to do here */ }

View File

@@ -181,7 +181,7 @@ public class CardFactory {
}
copySA.setCopied(true);
//remove all costs
copySA.setPayCosts(new Cost(c, "", sa.isAbility()));
copySA.setPayCosts(new Cost("", sa.isAbility()));
if (sa.getTarget() != null) {
Target target = new Target(sa.getTarget());
target.setSourceCard(c);

View File

@@ -152,7 +152,7 @@ public class CardFactoryCreatures {
}
private static void getCard_MasterOfTheWildHunt(final Card card) {
final Cost abCost = new Cost(card, "T", true);
final Cost abCost = new Cost("T", true);
final Target abTgt = new Target(card, "Target a creature to Hunt", "Creature".split(","));
class MasterOfTheWildHuntAbility extends AbilityActivated {
public MasterOfTheWildHuntAbility(final Card ca, final Cost co, final Target t) {
@@ -568,7 +568,7 @@ public class CardFactoryCreatures {
class LevelUpAbility extends AbilityActivated {
public LevelUpAbility(final Card ca, final String s) {
super(ca, new Cost(ca, manacost, true), null);
super(ca, new Cost(manacost, true), null);
}
@Override

View File

@@ -255,8 +255,7 @@ public class CardFactorySorceries {
* library.
*/
final Cost abCost = new Cost(card, "U U", false);
return new Spell(card, abCost, null) {
return new Spell(card, new Cost("U U", false), null) {
private static final long serialVersionUID = -8497142072380944393L;
@Override

View File

@@ -100,7 +100,7 @@ public class CardFactoryUtil {
*/
public static AbilityActivated abilityUnearth(final Card sourceCard, final String manaCost) {
final Cost cost = new Cost(sourceCard, manaCost, true);
final Cost cost = new Cost(manaCost, true);
class AbilityUnearth extends AbilityActivated {
public AbilityUnearth(final Card ca, final Cost co, final Target t) {
super(ca, co, t);
@@ -162,7 +162,7 @@ public class CardFactoryUtil {
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility abilityMorphDown(final Card sourceCard) {
final Spell morphDown = new Spell(sourceCard) {
final Spell morphDown = new Spell(sourceCard, new Cost(ManaCost.THREE, false), null) {
private static final long serialVersionUID = -1438810964807867610L;
@Override
@@ -184,7 +184,6 @@ public class CardFactoryUtil {
}
};
morphDown.setManaCost(ManaCost.THREE);
morphDown.setDescription("(You may cast this face down as a 2/2 creature for 3.)");
morphDown.setStackDescription("Morph - Creature 2/2");
morphDown.setCastFaceDown(true);
@@ -313,7 +312,7 @@ public class CardFactoryUtil {
*/
public static SpellAbility abilityTransmute(final Card sourceCard, String transmuteCost) {
transmuteCost += " Discard<1/CARDNAME>";
final Cost abCost = new Cost(sourceCard, transmuteCost, true);
final Cost abCost = new Cost(transmuteCost, true);
class AbilityTransmute extends AbilityActivated {
public AbilityTransmute(final Card ca, final Cost co, final Target t) {
super(ca, co, t);
@@ -406,7 +405,7 @@ public class CardFactoryUtil {
*/
public static SpellAbility abilitySuspend(final Card sourceCard, final String suspendCost, final String timeCounters) {
// be careful with Suspend ability, it will not hit the stack
Cost cost = new Cost(sourceCard, suspendCost, true);
Cost cost = new Cost(suspendCost, true);
final SpellAbility suspend = new AbilityStatic(sourceCard, cost, null) {
@Override
public boolean canPlay() {
@@ -2598,7 +2597,7 @@ public class CardFactoryUtil {
final SpellAbility sa1 = card.getFirstSpellAbility();
if (sa1 != null && sa1.isSpell()) {
final String altCost = card.getSVar("FullCost");
final Cost abCost = new Cost(card, altCost, sa1.isAbility());
final Cost abCost = new Cost(altCost, sa1.isAbility());
sa1.setPayCosts(abCost);
}
}
@@ -3104,7 +3103,7 @@ public class CardFactoryUtil {
final SpellAbility altCostSA = sa.copy();
final Cost abCost = new Cost(card, altCost, altCostSA.isAbility());
final Cost abCost = new Cost(altCost, altCostSA.isAbility());
altCostSA.setPayCosts(abCost);
final StringBuilder sb = new StringBuilder();
@@ -3136,7 +3135,11 @@ public class CardFactoryUtil {
* @return
*/
private static SpellAbility makeEvokeSpell(final Card card, final String evokeKeyword) {
final SpellAbility evokedSpell = new Spell(card) {
final String[] k = evokeKeyword.split(":");
final String evokedCost = k[1];
ManaCost manaCost = new ManaCost(new ManaCostParser(evokedCost));
final SpellAbility evokedSpell = new Spell(card, new Cost(manaCost, false), null) {
private static final long serialVersionUID = -1598664196463358630L;
@Override
@@ -3154,12 +3157,6 @@ public class CardFactoryUtil {
}
};
card.removeIntrinsicKeyword(evokeKeyword);
final String[] k = evokeKeyword.split(":");
final String evokedCost = k[1];
evokedSpell.setManaCost(new ManaCost(new ManaCostParser(evokedCost)));
final StringBuilder desc = new StringBuilder();
desc.append("Evoke ").append(evokedCost);
desc.append(" (You may cast this spell for its evoke cost. ");
@@ -3349,7 +3346,7 @@ public class CardFactoryUtil {
Map<String, String> sVars = card.getSVars();
final String[] k = parse.split(":");
final Cost cost = new Cost(card, k[1], true);
final Cost cost = new Cost(k[1], true);
card.addSpellAbility(CardFactoryUtil.abilityMorphDown(card));

View File

@@ -43,6 +43,16 @@ public class Cost {
private boolean isAbility = true;
private final ArrayList<CostPart> costParts = new ArrayList<CostPart>();
private boolean tapCost = false;
public final boolean hasTapCost() {
return this.tapCost;
}
public final boolean hasNoManaCost() {
return this.getTotalMana().isZero();
}
/**
* Gets the cost parts.
*
@@ -52,23 +62,6 @@ public class Cost {
return this.costParts;
}
private boolean tapCost = false;
public final boolean hasTapCost() {
return this.tapCost;
}
/**
* <p>
* hasNoManaCost.
* </p>
*
* @return a boolean.
*/
public final boolean hasNoManaCost() {
return this.getTotalMana().isZero();
}
/**
* <p>
* isOnlyManaCost.
@@ -104,12 +97,12 @@ public class Cost {
return ManaCost.ZERO;
}
private final String name;
private Cost() {}
// Parsing Strings
public Cost(final Card card, ManaCost cost, final boolean bAbility) {
this(card, cost.toString(), bAbility);
public Cost(ManaCost cost, final boolean bAbility) {
this(cost.toString(), bAbility);
}
/**
@@ -123,10 +116,9 @@ public class Cost {
* @param bAbility
* a boolean.
*/
public Cost(final Card card, String parse, final boolean bAbility) {
public Cost(String parse, final boolean bAbility) {
this.isAbility = bAbility;
// when adding new costs for cost string, place them here
this.name = card != null ? card.getName() : "";
boolean xCantBe0 = false;
boolean untapCost = false;
@@ -379,6 +371,17 @@ public class Cost {
this.costParts.add(new CostPartMana(changedCost.toManaCost(), null, false));
}
}
public final Cost copyWithNoMana() {
Cost toRet = new Cost();
for(CostPart cp : this.costParts) {
if ( cp instanceof CostPartMana )
toRet.costParts.add(new CostPartMana(ManaCost.ZERO, null, false));
else
toRet.costParts.add(cp);
}
return toRet;
}
public final CostPartMana getCostMana() {
for (final CostPart part : this.costParts) {
@@ -502,7 +505,7 @@ public class Cost {
boolean first = true;
if (bFlag) {
cost.append("As an additional cost to cast ").append(this.name).append(", ");
cost.append("As an additional cost to cast selected card, ");
} else {
// usually no additional mana cost for spells
// only three Alliances cards have additional mana costs, but they

View File

@@ -21,6 +21,7 @@ import com.esotericsoftware.minlog.Log;
import forge.Card;
import forge.Singletons;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
/**
@@ -44,10 +45,11 @@ public abstract class Ability extends SpellAbility {
* a {@link java.lang.String} object.
*/
public Ability(final Card sourceCard, final ManaCost manaCost) {
super(sourceCard);
this.setManaCost(manaCost);
this(sourceCard, new Cost(manaCost, true));
}
public Ability(final Card sourceCard, final Cost cost) {
super(sourceCard, cost);
}
/**
* <p>
* Constructor for Ability.
@@ -76,7 +78,7 @@ public abstract class Ability extends SpellAbility {
return this.getSourceCard().isInPlay() && !this.getSourceCard().isFaceDown();
}
public static final Ability PLAY_LAND_SURROGATE = new Ability(null, null){
public static final Ability PLAY_LAND_SURROGATE = new Ability(null, (Cost)null){
@Override
public void resolve() {
// TODO Auto-generated method stub

View File

@@ -50,7 +50,7 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
* a {@link java.lang.String} object.
*/
public AbilityActivated(final Card card, final String manacost) {
this(card, new Cost(card, manacost, true), null);
this(card, new Cost(manacost, true), null);
}
/**
@@ -66,9 +66,7 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
* a {@link forge.card.spellability.Target} object.
*/
public AbilityActivated(final Card sourceCard, final Cost abCost, final Target tgt) {
super(sourceCard);
this.setManaCost(abCost.getTotalMana());
this.setPayCosts(abCost);
super(sourceCard, abCost);
if ((tgt != null) && tgt.doesTarget()) {
this.setTarget(tgt);
}

View File

@@ -45,9 +45,7 @@ public abstract class AbilityStatic extends Ability {
}
public AbilityStatic(final Card sourceCard, final Cost abCost, final Target tgt) {
super(sourceCard, abCost.getTotalMana());
this.setManaCost(abCost.getTotalMana());
this.setPayCosts(abCost);
super(sourceCard, abCost);
if ((tgt != null) && tgt.doesTarget()) {
this.setTarget(tgt);
}

View File

@@ -59,7 +59,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
public Spell(final Card sourceCard) {
super(sourceCard);
this.setManaCost(sourceCard.getManaCost());
this.setPayCosts(new Cost(sourceCard.getManaCost(), false));
this.setStackDescription(sourceCard.getSpellText());
this.getRestrictions().setZone(ZoneType.Hand);
}
@@ -109,7 +109,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
return false;
}
// for uncastables like lotus bloom, check if manaCost is blank
if (isBasicSpell() && getManaCost().isNoCost()) {
if (isBasicSpell() && (getPayCosts() == null || getPayCosts().getTotalMana().isNoCost())) {
return false;
}

View File

@@ -31,7 +31,6 @@ import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.ability.ApiType;
import forge.card.cost.Cost;
import forge.card.cost.CostPart;
import forge.card.cost.CostPartMana;
import forge.card.mana.Mana;
import forge.card.mana.ManaCost;
@@ -54,7 +53,6 @@ public abstract class SpellAbility implements ISpellAbility {
// choices for constructor isPermanent argument
private String description = "";
private String stackDescription = "";
private ManaCost manaCost = null;
private ManaCost multiKickerManaCost = null;
private ManaCost replicateManaCost = null;
private Player activatingPlayer = null;
@@ -173,8 +171,13 @@ public abstract class SpellAbility implements ISpellAbility {
* @param iSourceCard
* a {@link forge.Card} object.
*/
public SpellAbility(final Card iSourceCard) {
public SpellAbility(final Card iSourceCard, Cost toPay) {
this.sourceCard = iSourceCard;
this.payCosts = toPay;
}
public SpellAbility(final Card iSourceCard ) {
this(iSourceCard, null);
}
// Spell, and Ability, and other Ability objects override this method
@@ -221,29 +224,6 @@ public abstract class SpellAbility implements ISpellAbility {
return false;
}
/**
* <p>
* Getter for the field <code>manaCost</code>.
* </p>
*
* @return a {@link java.lang.String} object.
*/
public ManaCost getManaCost() {
return this.manaCost;
}
/**
* <p>
* Setter for the field <code>manaCost</code>.
* </p>
*
* @param cost
* a {@link java.lang.String} object.
*/
public void setManaCost(final ManaCost cost) {
this.manaCost = cost;
}
/**
* <p>
* Getter for the field <code>multiKickerManaCost</code>.
@@ -1136,17 +1116,8 @@ public abstract class SpellAbility implements ISpellAbility {
}
public SpellAbility copyWithNoManaCost() {
final SpellAbility newSA = this;
final Cost cost = new Cost(this.getSourceCard(), "", false);
if (newSA.getPayCosts() != null) {
for (final CostPart part : newSA.getPayCosts().getCostParts()) {
if (!(part instanceof CostPartMana)) {
cost.getCostParts().add(part);
}
}
}
newSA.setPayCosts(cost);
newSA.setManaCost(ManaCost.NO_COST);
final SpellAbility newSA = this.copy();
newSA.setPayCosts(newSA.getPayCosts().copyWithNoMana());
newSA.setDescription(newSA.getDescription() + " (without paying its mana cost)");
return newSA;
}

View File

@@ -67,7 +67,7 @@ public class SpellPermanent extends Spell {
*/
public SpellPermanent(final Card sourceCard) {
// Add Costs for all SpellPermanents
this(sourceCard, new Cost(sourceCard, sourceCard.getManaCost(), false), null);
this(sourceCard, new Cost(sourceCard.getManaCost(), false), null);
} // Spell_Permanent()
/**
@@ -97,7 +97,7 @@ public class SpellPermanent extends Spell {
this.setDescription(this.getStackDescription());
if (this.getManaCost().countX() > 0) {
if (this.getPayCosts().getTotalMana().countX() > 0) {
if (!this.getSourceCard().getSVar("X").equals("")) {
this.setSVar("X", this.getSourceCard().getSVar("X"));
}

View File

@@ -84,7 +84,7 @@ public class StaticAbilityCantAttackBlock {
costString = Integer.toString(CardFactoryUtil.xCount(hostCard, hostCard.getSVar("Y")));
}
final Cost cost = new Cost(hostCard, costString, true);
final Cost cost = new Cost(costString, true);
return cost;
}
@@ -118,7 +118,7 @@ public class StaticAbilityCantAttackBlock {
costString = Integer.toString(CardFactoryUtil.xCount(hostCard, hostCard.getSVar("Y")));
}
final Cost cost = new Cost(hostCard, costString, true);
final Cost cost = new Cost(costString, true);
return cost;
}

View File

@@ -35,6 +35,7 @@ import forge.CardPredicates;
import forge.CardUtil;
import forge.Command;
import forge.CounterType;
import forge.FThreads;
import forge.GameEntity;
import forge.card.CardType;
import forge.card.TriggerReplacementBase;
@@ -335,8 +336,11 @@ public class GameAction {
* @return a {@link forge.Card} object.
*/
public final Card moveTo(final Zone zoneTo, Card c) {
// FThreads.assertExecutedByEdt(false); // This code must never be executed from EDT,
// use FThreads.invokeInNewThread to run code in a pooled thread
// if a split card is moved, convert it back to its full form before moving (unless moving to stack)
if (c.isSplitCard() && zoneTo != game.getStackZone()) {
if (c.isSplitCard() && !zoneTo.is(ZoneType.Stack)) {
c.setState(CardCharacteristicName.Original);
}
@@ -481,7 +485,7 @@ public class GameAction {
private void handleRecoverAbility(final Card recoverable) {
final String recoverCost = recoverable.getKeyword().get(recoverable.getKeywordPosition("Recover")).split(":")[1];
final Cost cost = new Cost(recoverable, recoverCost, true);
final Cost cost = new Cost(recoverCost, true);
final SpellAbility abRecover = new AbilityActivated(recoverable, cost, null) {
private static final long serialVersionUID = 8858061639236920054L;
@@ -758,7 +762,7 @@ public class GameAction {
}
final SpellAbility madness = card.getFirstSpellAbility().copy();
madness.setPayCosts(new Cost(card, card.getMadnessCost(), false));
madness.setPayCosts(new Cost(card.getMadnessCost(), false));
final StringBuilder sb = new StringBuilder();
sb.append(card.getName()).append(" - Cast via Madness");

View File

@@ -564,8 +564,8 @@ public final class GameActionUtil {
throw new RuntimeException("GameActionUtil.payCostDuringAbilityResolve - The remaining payment type is not Mana.");
InputPayment toSet = current == null
? new InputPayManaExecuteCommands(p, source + "\r\n", ability.getManaCost())
: new InputPayManaExecuteCommands(p, source + "\r\n" + "Current Card: " + current + "\r\n" , ability.getManaCost());
? new InputPayManaExecuteCommands(p, source + "\r\n", cost.getCostMana().getManaToPay())
: new InputPayManaExecuteCommands(p, source + "\r\n" + "Current Card: " + current + "\r\n" , cost.getCostMana().getManaToPay());
FThreads.setInputAndWait(toSet);
return toSet.isPaid();
}
@@ -1159,7 +1159,7 @@ public final class GameActionUtil {
// there is a flashback cost (and not the cards cost)
if (!keyword.equals("Flashback")) {
final Cost fbCost = new Cost(source, keyword.substring(10), false);
final Cost fbCost = new Cost(keyword.substring(10), false);
flashback.setPayCosts(fbCost);
}
alternatives.add(flashback);
@@ -1170,17 +1170,8 @@ public final class GameActionUtil {
sar.setVariables(sa.getRestrictions());
sar.setZone(null);
newSA.setRestrictions(sar);
final Cost cost = new Cost(source, "", false);
if (newSA.getPayCosts() != null) {
for (final CostPart part : newSA.getPayCosts().getCostParts()) {
if (!(part instanceof CostPartMana)) {
cost.getCostParts().add(part);
}
}
}
newSA.setBasicSpell(false);
newSA.setPayCosts(cost);
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(newSA.getPayCosts().copyWithNoMana());
newSA.setDescription(sa.getDescription() + " (without paying its mana cost)");
alternatives.add(newSA);
}
@@ -1191,17 +1182,8 @@ public final class GameActionUtil {
sar.setZone(null);
sar.setOpponentOnly(true);
newSA.setRestrictions(sar);
final Cost cost = new Cost(source, "", false);
if (newSA.getPayCosts() != null) {
for (final CostPart part : newSA.getPayCosts().getCostParts()) {
if (!(part instanceof CostPartMana)) {
cost.getCostParts().add(part);
}
}
}
newSA.setBasicSpell(false);
newSA.setPayCosts(cost);
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(newSA.getPayCosts().copyWithNoMana());
newSA.setDescription(sa.getDescription() + " (without paying its mana cost)");
alternatives.add(newSA);
}
@@ -1211,38 +1193,17 @@ public final class GameActionUtil {
sar.setVariables(sa.getRestrictions());
sar.setInstantSpeed(true);
newSA.setRestrictions(sar);
final Cost cost = new Cost(source, "", false);
if (newSA.getPayCosts() != null) {
for (final CostPart part : newSA.getPayCosts().getCostParts()) {
if (!(part instanceof CostPartMana)) {
cost.getCostParts().add(part);
}
}
}
newSA.setBasicSpell(false);
newSA.setPayCosts(cost);
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(newSA.getPayCosts().copyWithNoMana());
newSA.setDescription(sa.getDescription() + " (without paying its mana cost and as though it has flash)");
alternatives.add(newSA);
}
if (sa.isSpell() && keyword.startsWith("Alternative Cost")) {
final SpellAbility newSA = sa.copy();
final Cost cost = new Cost(source, keyword.substring(17), false);
if (newSA.getPayCosts() != null) {
for (final CostPart part : newSA.getPayCosts().getCostParts()) {
if (!(part instanceof CostPartMana)) {
cost.getCostParts().add(part);
}
}
}
newSA.setBasicSpell(false);
final Cost cost = new Cost(keyword.substring(17), false).add(newSA.getPayCosts().copyWithNoMana());
newSA.setPayCosts(cost);
newSA.setManaCost(ManaCost.NO_COST);
String costString = cost.toSimpleString();
if (costString.equals("")) {
costString = "0";
}
newSA.setDescription(sa.getDescription() + " (by paying " + costString + " instead of its mana cost)");
newSA.setDescription(sa.getDescription() + " (by paying " + cost.toSimpleString() + " instead of its mana cost)");
alternatives.add(newSA);
}
}
@@ -1286,8 +1247,7 @@ public final class GameActionUtil {
//create a new spell copy
final SpellAbility newSA = s.copy();
newSA.setBasicSpell(false);
newSA.setPayCosts(new Cost(c, keyword.substring(19), false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(new Cost(keyword.substring(19), false).add(newSA.getPayCosts()));
newSA.setDescription(s.getDescription() + " (Splicing " + c + " onto it)");
newSA.addSplicedCards(c);
@@ -1343,8 +1303,7 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false);
newSA.setPayCosts(new Cost(source, keyword.substring(8), false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(new Cost(keyword.substring(8), false).add(newSA.getPayCosts()));
newSA.setDescription(sa.getDescription() + " (with Buyback)");
ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts());
@@ -1360,10 +1319,9 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false);
final Cost cost = new Cost(source, keyword.substring(7), false);
final Cost cost = new Cost(keyword.substring(7), false);
newSA.setDescription(sa.getDescription() + " (Kicker " + cost.toSimpleString() + ")");
newSA.setPayCosts(cost.add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts());
newSA.setOptionalAdditionalCosts(newoacs);
@@ -1380,9 +1338,8 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false);
newSA.setPayCosts(new Cost(source, costString1, false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
final Cost cost1 = new Cost(source, costString1, false);
newSA.setPayCosts(new Cost(costString1, false).add(newSA.getPayCosts()));
final Cost cost1 = new Cost(costString1, false);
newSA.setDescription(sa.getDescription() + " (Additional cost " + cost1.toSimpleString() + ")");
ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts());
@@ -1393,9 +1350,8 @@ public final class GameActionUtil {
//second option
final SpellAbility newSA2 = sa.copy();
newSA2.setBasicSpell(false);
newSA.setPayCosts(new Cost(source, costString2, false).add(newSA.getPayCosts()));
newSA2.setManaCost(ManaCost.NO_COST);
final Cost cost2 = new Cost(source, costString2, false);
newSA.setPayCosts(new Cost(costString2, false).add(newSA.getPayCosts()));
final Cost cost2 = new Cost(costString2, false);
newSA2.setDescription(sa.getDescription() + " (Additional cost " + cost2.toSimpleString() + ")");
ArrayList<String> newoacs2 = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts());
@@ -1413,8 +1369,7 @@ public final class GameActionUtil {
newSA.setBasicSpell(false);
final String conspireCost = "tapXType<2/Creature.SharesColorWith/untapped creature you control"
+ " that shares a color with " + source.getName() + ">";
newSA.setPayCosts(new Cost(source, conspireCost, false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
newSA.setPayCosts(new Cost(conspireCost, false).add(newSA.getPayCosts()));
newSA.setDescription(sa.getDescription() + " (Conspire)");
ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts());

View File

@@ -484,8 +484,8 @@ public class AiController {
public int compare(final SpellAbility a, final SpellAbility b) {
// sort from highest cost to lowest
// we want the highest costs first
int a1 = a.getManaCost().getCMC();
int b1 = b.getManaCost().getCMC();
int a1 = a.getPayCosts() == null ? 0 : a.getPayCosts().getTotalMana().getCMC();
int b1 = b.getPayCosts() == null ? 0 : b.getPayCosts().getTotalMana().getCMC();
// cast 0 mana cost spells first (might be a Mox)
if (a1 == 0) {

View File

@@ -312,7 +312,7 @@ public class ComputerUtilCost {
* @return a boolean.
*/
public static boolean shouldPayCost(final Player ai, final Card hostCard, final String costString) {
final Cost cost = new Cost(hostCard, costString, false);
final Cost cost = new Cost(costString, false);
for (final CostPart part : cost.getCostParts()) {
if (part instanceof CostPayLife) {

View File

@@ -412,7 +412,7 @@ public class ComputerUtilMana {
* @return ManaCost
*/
private static ManaCostBeingPaid calculateManaCost(final SpellAbility sa, final boolean test, final int extraMana) {
final ManaCost mana = sa.getPayCosts() != null ? sa.getPayCosts().getTotalMana() : sa.getManaCost();
final ManaCost mana = sa.getPayCosts() != null ? sa.getPayCosts().getTotalMana() : ManaCost.NO_COST;
ManaCostBeingPaid cost = new ManaCostBeingPaid(mana);
cost.applySpellCostChange(sa);

View File

@@ -1123,13 +1123,14 @@ public class CombatUtil {
* a boolean.
*/
public static void checkPropagandaEffects(final GameState game, final Card c) {
Cost attackCost = new Cost(c, "0", true);
Cost attackCost = new Cost(ManaCost.ZERO, true);
// Sort abilities to apply them in proper order
for (Card card : game.getCardsIn(ZoneType.Battlefield)) {
final ArrayList<StaticAbility> staticAbilities = card.getStaticAbilities();
for (final StaticAbility stAb : staticAbilities) {
Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, game.getCombat().getDefenderByAttacker(c));
attackCost.add(additionalCost);
if ( null != additionalCost )
attackCost.add(additionalCost);
}
}

View File

@@ -28,6 +28,7 @@ import forge.CardLists;
import forge.CardPredicates.Presets;
import forge.Singletons;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
import forge.card.spellability.Ability;
import forge.card.spellability.AbilityStatic;
import forge.card.staticability.StaticAbility;
@@ -212,13 +213,14 @@ public class PhaseUtil {
for (Card blocker : filterList) {
final List<Card> attackers = new ArrayList<Card>(combat.getAttackersBlockedBy(blocker));
for (Card attacker : attackers) {
Cost blockCost = new Cost(blocker, "0", true);
Cost blockCost = new Cost(ManaCost.ZERO, true);
// Sort abilities to apply them in proper order
for (Card card : game.getCardsIn(ZoneType.Battlefield)) {
final ArrayList<StaticAbility> staticAbilities = card.getStaticAbilities();
for (final StaticAbility stAb : staticAbilities) {
Cost additionalCost = stAb.getCostAbility("CantBlockUnless", blocker, attacker);
blockCost = Cost.combine(blockCost, additionalCost);
Cost c1 = stAb.getCostAbility("CantBlockUnless", blocker, attacker);
if ( c1 != null )
blockCost.add(c1);
}
}

View File

@@ -38,6 +38,7 @@ import forge.card.spellability.AbilityManaPart;
import forge.card.spellability.AbilityStatic;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputPayManaExecuteCommands;
import forge.control.input.InputPayment;
import forge.control.input.InputSelectCards;
import forge.control.input.InputSelectCardsFromList;
import forge.game.GameActionUtil;
@@ -169,7 +170,7 @@ public class Upkeep extends Phase {
for (int i = 0; i < list.size(); i++) {
final Card c = list.get(i);
if (c.hasStartOfKeyword("(Echo unpaid)")) {
final Ability blankAbility = Upkeep.BlankAbility(c, c.getEchoCost());
final Ability blankAbility = Upkeep.getBlankAbility(c, c.getEchoCost());
blankAbility.setActivatingPlayer(c.getController());
final StringBuilder sb = new StringBuilder();
@@ -181,7 +182,7 @@ public class Upkeep extends Phase {
Player controller = c.getController();
if (controller.isHuman()) {
Cost cost = new Cost(c, c.getEchoCost().trim(), true);
Cost cost = new Cost(c.getEchoCost().trim(), true);
if ( !GameActionUtil.payCostDuringAbilityResolve(blankAbility, cost, null, game) )
game.getAction().sacrifice(c, null);;
@@ -275,7 +276,7 @@ public class Upkeep extends Phase {
FThreads.setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computer
Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
Ability aiPaid = Upkeep.getBlankAbility(c, upkeepCost.toString());
isUpkeepPaid = ComputerUtilCost.canPayCost(aiPaid, controller) && !c.hasKeyword("Indestructible");
if (isUpkeepPaid) {
ComputerUtil.playNoStack((AIPlayer)controller, aiPaid, game);
@@ -317,7 +318,7 @@ public class Upkeep extends Phase {
}
final String upkeepCost = cost;
final Ability blankAbility = Upkeep.BlankAbility(c, upkeepCost);
final Ability blankAbility = Upkeep.getBlankAbility(c, upkeepCost);
blankAbility.setActivatingPlayer(controller);
final Ability upkeepAbility = new Ability(c, ManaCost.ZERO) {
@@ -360,7 +361,7 @@ public class Upkeep extends Phase {
FThreads.setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computers
final Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
final Ability aiPaid = Upkeep.getBlankAbility(c, upkeepCost.toString());
if (ComputerUtilCost.canPayCost(aiPaid, controller) && ComputerUtilCombat.predictDamageTo(controller, upkeepDamage, c, false) > 0) {
ComputerUtil.playNoStack((AIPlayer)controller, aiPaid, game);
isUpkeepPaid = true;
@@ -395,13 +396,10 @@ public class Upkeep extends Phase {
* a {@link java.lang.String} object.
* @return a {@link forge.card.spellability.Ability} object.
*/
private static Ability BlankAbility(final Card c, final String costString) {
Cost cost = new Cost(c, costString, true);
return new AbilityStatic(c, cost, null) {
public static Ability getBlankAbility(final Card c, final String costString) {
return new AbilityStatic(c, new Cost(costString, true), null) {
@Override
public void resolve() {
}
public void resolve() {}
};
}
@@ -601,7 +599,7 @@ public class Upkeep extends Phase {
@Override
public void resolve() {
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(cp, "Pay Demonic Hordes upkeep cost", cost.getManaCost() /*, true */);
InputPayment inp = new InputPayManaExecuteCommands(cp, "Pay Demonic Hordes upkeep cost", cost.getPayCosts().getTotalMana() /*, true */);
FThreads.setInputAndWait(inp);
if ( !inp.isPaid() )
unpaidHordesAb.resolve();

View File

@@ -133,7 +133,7 @@ public class HumanPlayer extends Player {
if (newAbility) {
CostPayment payment = null;
if (sa.getPayCosts() == null) {
payment = new CostPayment(new Cost(sa.getSourceCard(), "0", sa.isAbility()), sa);
payment = new CostPayment(new Cost("0", sa.isAbility()), sa);
} else {
payment = new CostPayment(sa.getPayCosts(), sa);
}
@@ -141,11 +141,10 @@ public class HumanPlayer extends Player {
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(sa, payment);
req.fillRequirements(false, false, false);
} else {
ManaCostBeingPaid manaCost = new ManaCostBeingPaid(sa.getManaCost());
ManaCostBeingPaid manaCost = new ManaCostBeingPaid(sa.getPayCosts().getCostMana().getManaToPay());
if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) {
manaCost = new ManaCostBeingPaid("0");
} else {
manaCost = new ManaCostBeingPaid(sa.getManaCost());
manaCost.applySpellCostChange(sa);
}
@@ -191,11 +190,10 @@ public class HumanPlayer extends Player {
req.fillRequirements(useOldTargets, false, true);
} else {
ManaCostBeingPaid manaCost = new ManaCostBeingPaid(sa.getManaCost());
ManaCostBeingPaid manaCost = new ManaCostBeingPaid(sa.getPayCosts().getTotalMana());
if (sa.getSourceCard().isCopiedSpell() && sa.isSpell()) {
manaCost = new ManaCostBeingPaid("0");
} else {
manaCost = new ManaCostBeingPaid(sa.getManaCost());
manaCost.applySpellCostChange(sa);
}

View File

@@ -3036,7 +3036,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
}
final SpellAbility playForMiracleCost = card.getFirstSpellAbility().copy();
playForMiracleCost.setPayCosts(new Cost(card, card.getMiracleCost(), false));
playForMiracleCost.setPayCosts(new Cost(card.getMiracleCost(), false));
playForMiracleCost.setStackDescription(card.getName() + " - Cast via Miracle");
// TODO Convert this to a Trigger