From 1a721fc2b050882f313faebe80aba65bb7d571f0 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Mon, 15 Apr 2013 07:16:10 +0000 Subject: [PATCH] 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) --- .../forge/card/ability/AbilityFactory.java | 11 +++++----- src/main/java/forge/card/cost/Cost.java | 15 ++++++-------- src/main/java/forge/game/GameActionUtil.java | 20 ++++++++----------- src/main/java/forge/game/ai/ComputerUtil.java | 1 - .../java/forge/game/phase/CombatUtil.java | 2 +- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/main/java/forge/card/ability/AbilityFactory.java b/src/main/java/forge/card/ability/AbilityFactory.java index a8d1cd12b37..e6caf1fa411 100644 --- a/src/main/java/forge/card/ability/AbilityFactory.java +++ b/src/main/java/forge/card/ability/AbilityFactory.java @@ -350,7 +350,6 @@ public final class AbilityFactory { final String strLeftAbility = card.getState(CardCharacteristicName.LeftSplit).getIntrinsicAbility().get(0); Map leftMap = getMapParams(strLeftAbility); AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap); - Cost leftCost = parseAbilityCost(card, leftMap, leftType); ApiType leftApi = leftType.getApiTypeOf(leftMap); leftMap.put("StackDecription", leftMap.get("SpellDescription")); 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); Map rightMap = getMapParams(strRightAbility); AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap); - Cost rightCost = parseAbilityCost(card, rightMap, rightType); ApiType rightApi = leftType.getApiTypeOf(rightMap); rightMap.put("StackDecription", rightMap.get("SpellDescription")); rightMap.put("SpellDescription", ""); - - - Cost joinedCost = Cost.combine(rightCost, leftCost); - final SpellAbility left = getAbility(leftType, leftApi, leftMap, joinedCost, card); + + Cost totalCost = parseAbilityCost(card, leftMap, leftType); + totalCost.add(parseAbilityCost(card, rightMap, rightType)); + + final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, card); final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, card); left.appendSubAbility(right); return left; diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index ce714af4a57..07bacf24860 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -649,11 +649,8 @@ public class Cost { return sb.toString(); } - public static Cost combine(Cost cost1, Cost cost2) { - if (cost1 == null) return cost2; - if (cost2 == null) return cost1; - - CostPartMana costPart2 = cost2.getCostMana(); + public Cost add(Cost cost1) { + CostPartMana costPart2 = this.getCostMana(); for (final CostPart part : cost1.getCostParts()) { if (part instanceof CostPartMana && costPart2 != null) { ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); @@ -662,13 +659,13 @@ public class Cost { String r2 = costPart2.getRestiction(); String r1 = ((CostPartMana) part).getRestiction(); String r = r1 == null ? r2 : ( r2 == null ? r1 : r1+"."+r2); - cost2.getCostParts().remove(costPart2); - cost2.getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0)); + getCostParts().remove(costPart2); + getCostParts().add(0, new CostPartMana(oldManaCost.toManaCost(), r, !xCanBe0)); } 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) { diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index b84be2dd354..9c7f6c18c5e 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -1249,10 +1249,6 @@ public final class GameActionUtil { return alternatives; } - private static Cost combineCosts(SpellAbility sa, String additionalCost) { - return Cost.combine(sa.getPayCosts(), new Cost(sa.getSourceCard(), additionalCost, false)); - } - /** *

* getSpliceAbilities. @@ -1290,7 +1286,7 @@ public final class GameActionUtil { //create a new spell copy final SpellAbility newSA = s.copy(); 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.setDescription(s.getDescription() + " (Splicing " + c + " onto it)"); newSA.addSplicedCards(c); @@ -1347,13 +1343,13 @@ public final class GameActionUtil { for (SpellAbility sa : abilities) { final SpellAbility newSA = sa.copy(); 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.setDescription(sa.getDescription() + " (with Buyback)"); ArrayList newoacs = new ArrayList(); newoacs.addAll(sa.getOptionalAdditionalCosts()); newSA.setOptionalAdditionalCosts(newoacs); - newSA.addOptionalAdditionalCosts("Buyback"); + newSA.addOptionalAdditionalCosts(keyword); if (newSA.canPlay()) { newAbilities.add(newAbilities.size(), newSA); } @@ -1364,10 +1360,10 @@ public final class GameActionUtil { for (SpellAbility sa : abilities) { final SpellAbility newSA = sa.copy(); 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); newSA.setDescription(sa.getDescription() + " (Kicker " + cost.toSimpleString() + ")"); + newSA.setPayCosts(cost.add(newSA.getPayCosts())); + newSA.setManaCost(ManaCost.NO_COST); ArrayList newoacs = new ArrayList(); newoacs.addAll(sa.getOptionalAdditionalCosts()); newSA.setOptionalAdditionalCosts(newoacs); @@ -1384,7 +1380,7 @@ public final class GameActionUtil { for (SpellAbility sa : abilities) { final SpellAbility newSA = sa.copy(); newSA.setBasicSpell(false); - newSA.setPayCosts(GameActionUtil.combineCosts(newSA, costString1)); + newSA.setPayCosts(new Cost(source, costString1, false).add(newSA.getPayCosts())); newSA.setManaCost(ManaCost.NO_COST); final Cost cost1 = new Cost(source, costString1, false); newSA.setDescription(sa.getDescription() + " (Additional cost " + cost1.toSimpleString() + ")"); @@ -1397,7 +1393,7 @@ public final class GameActionUtil { //second option final SpellAbility newSA2 = sa.copy(); newSA2.setBasicSpell(false); - newSA2.setPayCosts(GameActionUtil.combineCosts(newSA2, costString2)); + newSA.setPayCosts(new Cost(source, costString2, false).add(newSA.getPayCosts())); newSA2.setManaCost(ManaCost.NO_COST); final Cost cost2 = new Cost(source, costString2, false); newSA2.setDescription(sa.getDescription() + " (Additional cost " + cost2.toSimpleString() + ")"); @@ -1417,7 +1413,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(GameActionUtil.combineCosts(newSA, conspireCost)); + newSA.setPayCosts(new Cost(source, conspireCost, false).add(newSA.getPayCosts())); newSA.setManaCost(ManaCost.NO_COST); newSA.setDescription(sa.getDescription() + " (Conspire)"); ArrayList newoacs = new ArrayList(); diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 307c2147208..da18884b74c 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -34,7 +34,6 @@ import forge.CardPredicates.Presets; import forge.CardUtil; import forge.Color; import forge.Singletons; -import forge.card.MagicColor; import forge.card.ability.AbilityUtils; import forge.card.ability.ApiType; import forge.card.ability.effects.CharmEffect; diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index 331b7964358..a9bc82bc7b0 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -1129,7 +1129,7 @@ public class CombatUtil { final ArrayList staticAbilities = card.getStaticAbilities(); for (final StaticAbility stAb : staticAbilities) { Cost additionalCost = stAb.getCostAbility("CantAttackUnless", c, game.getCombat().getDefenderByAttacker(c)); - attackCost = Cost.combine(attackCost, additionalCost); + attackCost.add(additionalCost); } }