Cost.combine(c1,c2) was modifying its argument c2. That would lead to bugs in propaganda effects. The method was replaced with Cost.add(c1) that adds c1 to this (and the current cost is obvously changed)

This commit is contained in:
Maxmtg
2013-04-15 07:16:10 +00:00
parent 98b1e3bb30
commit 1a721fc2b0
5 changed files with 20 additions and 29 deletions

View File

@@ -350,7 +350,6 @@ public final class AbilityFactory {
final String strLeftAbility = card.getState(CardCharacteristicName.LeftSplit).getIntrinsicAbility().get(0); final String strLeftAbility = card.getState(CardCharacteristicName.LeftSplit).getIntrinsicAbility().get(0);
Map<String, String> leftMap = getMapParams(strLeftAbility); Map<String, String> leftMap = getMapParams(strLeftAbility);
AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap); AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap);
Cost leftCost = parseAbilityCost(card, leftMap, leftType);
ApiType leftApi = leftType.getApiTypeOf(leftMap); ApiType leftApi = leftType.getApiTypeOf(leftMap);
leftMap.put("StackDecription", leftMap.get("SpellDescription")); leftMap.put("StackDecription", leftMap.get("SpellDescription"));
leftMap.put("SpellDescription", "Fuse (you may cast both halves of this card from your hand)."); leftMap.put("SpellDescription", "Fuse (you may cast both halves of this card from your hand).");
@@ -359,14 +358,14 @@ public final class AbilityFactory {
final String strRightAbility = card.getState(CardCharacteristicName.RightSplit).getIntrinsicAbility().get(0); final String strRightAbility = card.getState(CardCharacteristicName.RightSplit).getIntrinsicAbility().get(0);
Map<String, String> rightMap = getMapParams(strRightAbility); Map<String, String> rightMap = getMapParams(strRightAbility);
AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap); AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap);
Cost rightCost = parseAbilityCost(card, rightMap, rightType);
ApiType rightApi = leftType.getApiTypeOf(rightMap); ApiType rightApi = leftType.getApiTypeOf(rightMap);
rightMap.put("StackDecription", rightMap.get("SpellDescription")); rightMap.put("StackDecription", rightMap.get("SpellDescription"));
rightMap.put("SpellDescription", ""); rightMap.put("SpellDescription", "");
Cost totalCost = parseAbilityCost(card, leftMap, leftType);
Cost joinedCost = Cost.combine(rightCost, leftCost); totalCost.add(parseAbilityCost(card, rightMap, rightType));
final SpellAbility left = getAbility(leftType, leftApi, leftMap, joinedCost, card);
final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, card);
final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, card); final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, card);
left.appendSubAbility(right); left.appendSubAbility(right);
return left; return left;

View File

@@ -649,11 +649,8 @@ public class Cost {
return sb.toString(); return sb.toString();
} }
public static Cost combine(Cost cost1, Cost cost2) { public Cost add(Cost cost1) {
if (cost1 == null) return cost2; CostPartMana costPart2 = this.getCostMana();
if (cost2 == null) return cost1;
CostPartMana costPart2 = cost2.getCostMana();
for (final CostPart part : cost1.getCostParts()) { for (final CostPart part : cost1.getCostParts()) {
if (part instanceof CostPartMana && costPart2 != null) { if (part instanceof CostPartMana && costPart2 != null) {
ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana());
@@ -662,13 +659,13 @@ public class Cost {
String r2 = costPart2.getRestiction(); String r2 = costPart2.getRestiction();
String r1 = ((CostPartMana) part).getRestiction(); String r1 = ((CostPartMana) part).getRestiction();
String r = r1 == null ? r2 : ( r2 == null ? r1 : r1+"."+r2); String r = r1 == null ? r2 : ( r2 == null ? r1 : r1+"."+r2);
cost2.getCostParts().remove(costPart2); getCostParts().remove(costPart2);
cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0)); getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0));
} else { } else {
cost2.getCostParts().add(part); getCostParts().add(part);
} }
} }
return cost2; return this;
} }
public static int chooseXValue(final Card card, final SpellAbility sa, final int maxValue) { public static int chooseXValue(final Card card, final SpellAbility sa, final int maxValue) {

View File

@@ -1249,10 +1249,6 @@ public final class GameActionUtil {
return alternatives; return alternatives;
} }
private static Cost combineCosts(SpellAbility sa, String additionalCost) {
return Cost.combine(sa.getPayCosts(), new Cost(sa.getSourceCard(), additionalCost, false));
}
/** /**
* <p> * <p>
* getSpliceAbilities. * getSpliceAbilities.
@@ -1290,7 +1286,7 @@ public final class GameActionUtil {
//create a new spell copy //create a new spell copy
final SpellAbility newSA = s.copy(); final SpellAbility newSA = s.copy();
newSA.setBasicSpell(false); newSA.setBasicSpell(false);
newSA.setPayCosts(combineCosts(newSA, keyword.substring(19))); newSA.setPayCosts(new Cost(c, keyword.substring(19), false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST); newSA.setManaCost(ManaCost.NO_COST);
newSA.setDescription(s.getDescription() + " (Splicing " + c + " onto it)"); newSA.setDescription(s.getDescription() + " (Splicing " + c + " onto it)");
newSA.addSplicedCards(c); newSA.addSplicedCards(c);
@@ -1347,13 +1343,13 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) { for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy(); final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false); newSA.setBasicSpell(false);
newSA.setPayCosts(GameActionUtil.combineCosts(newSA, keyword.substring(8))); newSA.setPayCosts(new Cost(source, keyword.substring(8), false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST); newSA.setManaCost(ManaCost.NO_COST);
newSA.setDescription(sa.getDescription() + " (with Buyback)"); newSA.setDescription(sa.getDescription() + " (with Buyback)");
ArrayList<String> newoacs = new ArrayList<String>(); ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts()); newoacs.addAll(sa.getOptionalAdditionalCosts());
newSA.setOptionalAdditionalCosts(newoacs); newSA.setOptionalAdditionalCosts(newoacs);
newSA.addOptionalAdditionalCosts("Buyback"); newSA.addOptionalAdditionalCosts(keyword);
if (newSA.canPlay()) { if (newSA.canPlay()) {
newAbilities.add(newAbilities.size(), newSA); newAbilities.add(newAbilities.size(), newSA);
} }
@@ -1364,10 +1360,10 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) { for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy(); final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false); newSA.setBasicSpell(false);
newSA.setPayCosts(GameActionUtil.combineCosts(newSA, keyword.substring(7)));
newSA.setManaCost(ManaCost.NO_COST);
final Cost cost = new Cost(source, keyword.substring(7), false); final Cost cost = new Cost(source, keyword.substring(7), false);
newSA.setDescription(sa.getDescription() + " (Kicker " + cost.toSimpleString() + ")"); newSA.setDescription(sa.getDescription() + " (Kicker " + cost.toSimpleString() + ")");
newSA.setPayCosts(cost.add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST);
ArrayList<String> newoacs = new ArrayList<String>(); ArrayList<String> newoacs = new ArrayList<String>();
newoacs.addAll(sa.getOptionalAdditionalCosts()); newoacs.addAll(sa.getOptionalAdditionalCosts());
newSA.setOptionalAdditionalCosts(newoacs); newSA.setOptionalAdditionalCosts(newoacs);
@@ -1384,7 +1380,7 @@ public final class GameActionUtil {
for (SpellAbility sa : abilities) { for (SpellAbility sa : abilities) {
final SpellAbility newSA = sa.copy(); final SpellAbility newSA = sa.copy();
newSA.setBasicSpell(false); newSA.setBasicSpell(false);
newSA.setPayCosts(GameActionUtil.combineCosts(newSA, costString1)); newSA.setPayCosts(new Cost(source, costString1, false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST); newSA.setManaCost(ManaCost.NO_COST);
final Cost cost1 = new Cost(source, costString1, false); final Cost cost1 = new Cost(source, costString1, false);
newSA.setDescription(sa.getDescription() + " (Additional cost " + cost1.toSimpleString() + ")"); newSA.setDescription(sa.getDescription() + " (Additional cost " + cost1.toSimpleString() + ")");
@@ -1397,7 +1393,7 @@ public final class GameActionUtil {
//second option //second option
final SpellAbility newSA2 = sa.copy(); final SpellAbility newSA2 = sa.copy();
newSA2.setBasicSpell(false); newSA2.setBasicSpell(false);
newSA2.setPayCosts(GameActionUtil.combineCosts(newSA2, costString2)); newSA.setPayCosts(new Cost(source, costString2, false).add(newSA.getPayCosts()));
newSA2.setManaCost(ManaCost.NO_COST); newSA2.setManaCost(ManaCost.NO_COST);
final Cost cost2 = new Cost(source, costString2, false); final Cost cost2 = new Cost(source, costString2, false);
newSA2.setDescription(sa.getDescription() + " (Additional cost " + cost2.toSimpleString() + ")"); newSA2.setDescription(sa.getDescription() + " (Additional cost " + cost2.toSimpleString() + ")");
@@ -1417,7 +1413,7 @@ public final class GameActionUtil {
newSA.setBasicSpell(false); newSA.setBasicSpell(false);
final String conspireCost = "tapXType<2/Creature.SharesColorWith/untapped creature you control" final String conspireCost = "tapXType<2/Creature.SharesColorWith/untapped creature you control"
+ " that shares a color with " + source.getName() + ">"; + " that shares a color with " + source.getName() + ">";
newSA.setPayCosts(GameActionUtil.combineCosts(newSA, conspireCost)); newSA.setPayCosts(new Cost(source, conspireCost, false).add(newSA.getPayCosts()));
newSA.setManaCost(ManaCost.NO_COST); newSA.setManaCost(ManaCost.NO_COST);
newSA.setDescription(sa.getDescription() + " (Conspire)"); newSA.setDescription(sa.getDescription() + " (Conspire)");
ArrayList<String> newoacs = new ArrayList<String>(); ArrayList<String> newoacs = new ArrayList<String>();

View File

@@ -34,7 +34,6 @@ import forge.CardPredicates.Presets;
import forge.CardUtil; import forge.CardUtil;
import forge.Color; import forge.Color;
import forge.Singletons; import forge.Singletons;
import forge.card.MagicColor;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.ApiType; import forge.card.ability.ApiType;
import forge.card.ability.effects.CharmEffect; import forge.card.ability.effects.CharmEffect;

View File

@@ -1129,7 +1129,7 @@ public class CombatUtil {
final ArrayList<StaticAbility> staticAbilities = card.getStaticAbilities(); final ArrayList<StaticAbility> staticAbilities = card.getStaticAbilities();
for (final StaticAbility stAb : staticAbilities) { for (final StaticAbility stAb : staticAbilities) {
Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, game.getCombat().getDefenderByAttacker(c)); Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, game.getCombat().getDefenderByAttacker(c));
attackCost = Cost.combine(attackCost, additionalCost); attackCost.add(additionalCost);
} }
} }