diff --git a/.gitattributes b/.gitattributes index 48719d5b232..80a8b678601 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13790,7 +13790,6 @@ src/main/java/forge/card/cost/CostTapType.java -text src/main/java/forge/card/cost/CostUnattach.java -text src/main/java/forge/card/cost/CostUntap.java -text src/main/java/forge/card/cost/CostUntapType.java -text -src/main/java/forge/card/cost/CostUtil.java -text src/main/java/forge/card/cost/InputPayCostBase.java -text src/main/java/forge/card/cost/PaymentDecision.java -text src/main/java/forge/card/cost/package-info.java svneol=native#text/plain diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 140576872c0..e90250ddfa4 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -9177,6 +9177,9 @@ public class Card extends GameEntity implements Comparable { return; } } + if ( sa.getSourceCard().hasKeyword("Fuse") ) // it's ok that such card won't change its side + return; + throw new RuntimeException("Not found which part to choose for ability " + sa + " from card " + this); } diff --git a/src/main/java/forge/card/ability/AbilityFactory.java b/src/main/java/forge/card/ability/AbilityFactory.java index 1ba18db3f88..f6a2f88dead 100644 --- a/src/main/java/forge/card/ability/AbilityFactory.java +++ b/src/main/java/forge/card/ability/AbilityFactory.java @@ -41,6 +41,44 @@ import forge.util.FileSection; */ public final class AbilityFactory { + public enum AbilityRecordType { + Ability("AB"), + Spell("SP"), + SubAbility("DB"); + + private final String prefix; + private AbilityRecordType(String prefix) { + this.prefix = prefix; + } + public String getPrefix() { + return prefix; + } + + public SpellAbility buildSpellAbility(ApiType api, Card hostCard, Cost abCost, Target abTgt, Map mapParams ) { + switch(this) { + case Ability: return new AbilityApiBased(api, hostCard, abCost, abTgt, mapParams); + case Spell: return new SpellApiBased(api, hostCard, abCost, abTgt, mapParams); + case SubAbility: return new AbilitySub(api, hostCard, abTgt, mapParams); + } + return null; // exception here would be fine! + } + + public ApiType getApiTypeOf(Map abParams) { + return ApiType.smartValueOf(abParams.get(this.getPrefix())); + } + + public static AbilityRecordType getRecordType(Map abParams) { + if (abParams.containsKey(AbilityRecordType.Ability.getPrefix())) { + return AbilityRecordType.Ability; + } else if (abParams.containsKey(AbilityRecordType.Spell.getPrefix())) { + return AbilityRecordType.Spell; + } else if (abParams.containsKey(AbilityRecordType.SubAbility.getPrefix())) { + return AbilityRecordType.SubAbility; + } else { + return null; + } + } + } /** *

* getAbility. @@ -53,12 +91,7 @@ public final class AbilityFactory { * @return a {@link forge.card.spellability.SpellAbility} object. */ public static final SpellAbility getAbility(final String abString, final Card hostCard) { - - SpellAbility spellAbility = null; - - boolean isAb = false; - boolean isSp = false; - boolean isDb = false; + Map mapParams; try { @@ -69,35 +102,29 @@ public final class AbilityFactory { } // parse universal parameters - - ApiType api = null; - if (mapParams.containsKey("AB")) { - isAb = true; - api = ApiType.smartValueOf(mapParams.get("AB")); - } else if (mapParams.containsKey("SP")) { - isSp = true; - api = ApiType.smartValueOf(mapParams.get("SP")); - } else if (mapParams.containsKey("DB")) { - isDb = true; - api = ApiType.smartValueOf(mapParams.get("DB")); - } else { + AbilityRecordType type = AbilityRecordType.getRecordType(mapParams); + if( null == type ) throw new RuntimeException("AbilityFactory : getAbility -- no API in " + hostCard.getName()); - } + + return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(hostCard, mapParams, type), hostCard); + } + public static Cost parseAbilityCost(final Card hostCard, Map mapParams, AbilityRecordType type) { Cost abCost = null; - if (!isDb) { + if (type != AbilityRecordType.SubAbility) { if (!mapParams.containsKey("Cost")) { throw new RuntimeException("AbilityFactory : getAbility -- no Cost in " + hostCard.getName()); } - abCost = new Cost(hostCard, mapParams.get("Cost"), isAb); - + abCost = new Cost(hostCard, mapParams.get("Cost"), type == AbilityRecordType.Ability); } + return abCost; + } + public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map mapParams, Cost abCost, Card hostCard) { + + Target abTgt = mapParams.containsKey("ValidTgts") ? readTarget(hostCard, mapParams) : null; - // *********************************** - // Match API keywords. These are listed in alphabetical order. - if (api == ApiType.CopySpellAbility) { if (abTgt != null) { @@ -119,20 +146,13 @@ public final class AbilityFactory { else if (api == ApiType.PermanentCreature || api == ApiType.PermanentNoncreature) { // If API is a permanent type, and creating AF Spell // Clear out the auto created SpellPemanent spell - if (isSp) { + if (type == AbilityRecordType.Spell) { hostCard.clearFirstSpell(); } } - if (isAb) { - spellAbility = new AbilityApiBased(api, hostCard, abCost, abTgt, mapParams); - } else if (isSp) { - spellAbility = new SpellApiBased(api, hostCard, abCost, abTgt, mapParams); - } else if (isDb) { - spellAbility = new AbilitySub(api, hostCard, abTgt, mapParams); - } - + SpellAbility spellAbility = type.buildSpellAbility(api, hostCard, abCost, abTgt, mapParams); if (spellAbility == null) { @@ -163,7 +183,7 @@ public final class AbilityFactory { } else if (mapParams.containsKey("SpellDescription")) { final StringBuilder sb = new StringBuilder(); - if (!isDb) { // SubAbilities don't have Costs or Cost + if (type != AbilityRecordType.SubAbility) { // SubAbilities don't have Costs or Cost // descriptors if (mapParams.containsKey("PrecostDesc")) { sb.append(mapParams.get("PrecostDesc")).append(" "); diff --git a/src/main/java/forge/card/ability/ai/PumpAi.java b/src/main/java/forge/card/ability/ai/PumpAi.java index 6de1ef7ed85..77e9e5e113c 100644 --- a/src/main/java/forge/card/ability/ai/PumpAi.java +++ b/src/main/java/forge/card/ability/ai/PumpAi.java @@ -13,7 +13,8 @@ import forge.Singletons; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityAi; import forge.card.cost.Cost; -import forge.card.cost.CostUtil; +import forge.card.cost.CostPart; +import forge.card.cost.CostTapType; import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.Target; @@ -29,6 +30,19 @@ import forge.game.zone.ZoneType; public class PumpAi extends PumpAiBase { + private static boolean hasTapCost(final Cost cost, final Card source) { + if (cost == null) { + return true; + } + for (final CostPart part : cost.getCostParts()) { + if (part instanceof CostTapType) { + return true; + } + } + return false; + } + + /* (non-Javadoc) * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility) */ @@ -56,7 +70,7 @@ public class PumpAi extends PumpAiBase { return false; } - if (Singletons.getModel().getGame().getStack().isEmpty() && CostUtil.hasTapCost(cost, sa.getSourceCard())) { + if (Singletons.getModel().getGame().getStack().isEmpty() && hasTapCost(cost, sa.getSourceCard())) { if (ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && ph.isPlayerTurn(ai)) { return false; } diff --git a/src/main/java/forge/card/cardfactory/CardFactory.java b/src/main/java/forge/card/cardfactory/CardFactory.java index 2912b7fdb3d..31681eda675 100644 --- a/src/main/java/forge/card/cardfactory/CardFactory.java +++ b/src/main/java/forge/card/cardfactory/CardFactory.java @@ -292,6 +292,7 @@ public class CardFactory { if ( state == CardCharacteristicName.LeftSplit || state == CardCharacteristicName.RightSplit ) { card.getState(CardCharacteristicName.Original).getSpellAbility().addAll(card.getCharacteristics().getSpellAbility()); + card.getState(CardCharacteristicName.Original).getIntrinsicKeyword().addAll(card.getIntrinsicKeyword()); // Copy 'Fuse' to original side } } diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index bd69df415ba..cf9009a5ad6 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -2371,7 +2371,29 @@ public class CardFactoryUtil { } card.addSpellAbility(sa); } + } + public static final SpellAbility buildFusedAbility(final Card card) { + if(!card.isSplitCard()) + throw new IllegalStateException("Fuse ability may be built only on split cards"); + + final String strLeftAbility = card.getState(CardCharacteristicName.LeftSplit).getIntrinsicAbility().get(0); + Map leftMap = AbilityFactory.getMapParams(strLeftAbility); + AbilityFactory.AbilityRecordType leftType = AbilityFactory.AbilityRecordType.getRecordType(leftMap); + Cost leftCost = AbilityFactory.parseAbilityCost(card, leftMap, leftType); + ApiType leftApi = leftType.getApiTypeOf(leftMap); + + final String strRightAbility = card.getState(CardCharacteristicName.RightSplit).getIntrinsicAbility().get(0); + Map rightMap = AbilityFactory.getMapParams(strRightAbility); + AbilityFactory.AbilityRecordType rightType = AbilityFactory.AbilityRecordType.getRecordType(leftMap); + Cost rightCost = AbilityFactory.parseAbilityCost(card, rightMap, rightType); + ApiType rightApi = leftType.getApiTypeOf(rightMap); + + Cost joinedCost = Cost.combine(rightCost, leftCost); + final SpellAbility left = AbilityFactory.getAbility(leftType, leftApi, leftMap, joinedCost, card); + final AbilitySub right = (AbilitySub) AbilityFactory.getAbility(AbilityFactory.AbilityRecordType.SubAbility, rightApi, rightMap, null, card); + left.appendSubAbility(right); + return left; } /** @@ -2417,6 +2439,10 @@ public class CardFactoryUtil { sa.setReplicateManaCost(new ManaCost(new ManaCostParser(k[1]))); } } + + if(CardFactoryUtil.hasKeyword(card, "Fuse") != -1) { + card.getState(CardCharacteristicName.Original).getSpellAbility().add(buildFusedAbility(card)); + } final int evokePos = CardFactoryUtil.hasKeyword(card, "Evoke"); if (evokePos != -1) { @@ -3197,12 +3223,7 @@ public class CardFactoryUtil { private static final Map emptyMap = new TreeMap(); public static void setupETBReplacementAbility(SpellAbility sa) { - SpellAbility tailend = sa; - while (tailend.getSubAbility() != null) { - tailend = tailend.getSubAbility(); - } - - tailend.setSubAbility(new AbilitySub(ApiType.InternalEtbReplacement, sa.getSourceCard(), null, emptyMap)); + sa.appendSubAbility(new AbilitySub(ApiType.InternalEtbReplacement, sa.getSourceCard(), null, emptyMap)); // ETBReplacementMove(sa.getSourceCard(), null)); } diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index d3d0cb34bf0..f30897344e5 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -28,6 +28,7 @@ import forge.card.mana.ManaCostBeingPaid; import forge.card.mana.ManaCostParser; import forge.card.spellability.SpellAbility; import forge.game.zone.ZoneType; +import forge.gui.GuiChoose; import forge.util.TextUtil; /** @@ -647,4 +648,42 @@ 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(); + for (final CostPart part : cost1.getCostParts()) { + if (part instanceof CostPartMana && costPart2 != null) { + ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); + boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0(); + oldManaCost.combineManaCost(costPart2.getMana()); + 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)); + } else { + cost2.getCostParts().add(part); + } + } + return cost2; + } + + public static int chooseXValue(final Card card, final SpellAbility sa, final int maxValue) { + /*final String chosen = sa.getSVar("ChosenX"); + if (chosen.length() > 0) { + return AbilityFactory.calculateAmount(card, "ChosenX", null); + }*/ + + final Integer[] choiceArray = new Integer[maxValue + 1]; + for (int i = 0; i < choiceArray.length; i++) { + choiceArray[i] = i; + } + final Integer chosenX = GuiChoose.one(card.toString() + " - Choose a Value for X", choiceArray); + sa.setSVar("ChosenX", Integer.toString(chosenX)); + card.setSVar("ChosenX", Integer.toString(chosenX)); + return chosenX; + } } diff --git a/src/main/java/forge/card/cost/CostDamage.java b/src/main/java/forge/card/cost/CostDamage.java index 1a82c960d12..a7b0af5c712 100644 --- a/src/main/java/forge/card/cost/CostDamage.java +++ b/src/main/java/forge/card/cost/CostDamage.java @@ -88,7 +88,7 @@ public class CostDamage extends CostPart { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, life); + c = Cost.chooseXValue(source, ability, life); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostDiscard.java b/src/main/java/forge/card/cost/CostDiscard.java index 4c800273418..0aa34866f64 100644 --- a/src/main/java/forge/card/cost/CostDiscard.java +++ b/src/main/java/forge/card/cost/CostDiscard.java @@ -184,7 +184,7 @@ public class CostDiscard extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, handList.size()); + c = Cost.chooseXValue(source, ability, handList.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } @@ -220,7 +220,7 @@ public class CostDiscard extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, handList.size()); + c = Cost.chooseXValue(source, ability, handList.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostExile.java b/src/main/java/forge/card/cost/CostExile.java index 8ceb591ce54..84fb929a69e 100644 --- a/src/main/java/forge/card/cost/CostExile.java +++ b/src/main/java/forge/card/cost/CostExile.java @@ -541,7 +541,7 @@ public class CostExile extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, list.size()); + c = Cost.chooseXValue(source, ability, list.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostGainLife.java b/src/main/java/forge/card/cost/CostGainLife.java index dbbd9958ac8..dd2c1addfd0 100644 --- a/src/main/java/forge/card/cost/CostGainLife.java +++ b/src/main/java/forge/card/cost/CostGainLife.java @@ -128,7 +128,7 @@ public class CostGainLife extends CostPart { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, life); + c = Cost.chooseXValue(source, ability, life); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostMill.java b/src/main/java/forge/card/cost/CostMill.java index 40eefd99084..f654cf8ca5f 100644 --- a/src/main/java/forge/card/cost/CostMill.java +++ b/src/main/java/forge/card/cost/CostMill.java @@ -99,7 +99,7 @@ public class CostMill extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, this.getList().size()); + c = Cost.chooseXValue(source, ability, this.getList().size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostPayLife.java b/src/main/java/forge/card/cost/CostPayLife.java index 5afe507d3f0..181193bc0d4 100644 --- a/src/main/java/forge/card/cost/CostPayLife.java +++ b/src/main/java/forge/card/cost/CostPayLife.java @@ -120,7 +120,7 @@ public class CostPayLife extends CostPart { limit = AbilityUtils.calculateAmount(source, sVar.split("LimitMax.")[1], ability); } int maxLifePayment = limit < life ? limit : life; - c = CostUtil.chooseXValue(source, ability, maxLifePayment); + c = Cost.chooseXValue(source, ability, maxLifePayment); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostRemoveCounter.java b/src/main/java/forge/card/cost/CostRemoveCounter.java index 9cd17c09a55..649a90a363b 100644 --- a/src/main/java/forge/card/cost/CostRemoveCounter.java +++ b/src/main/java/forge/card/cost/CostRemoveCounter.java @@ -136,7 +136,7 @@ public class CostRemoveCounter extends CostPartWithList { if (amount.equals("All")) cntRemoved = maxCounters; else if ( c == null && "XChoice".equals(sVarAmount)) { - cntRemoved = CostUtil.chooseXValue(source, ability, maxCounters); + cntRemoved = Cost.chooseXValue(source, ability, maxCounters); } if (maxCounters < cntRemoved) diff --git a/src/main/java/forge/card/cost/CostReturn.java b/src/main/java/forge/card/cost/CostReturn.java index 701072a7e52..367f5d9e117 100644 --- a/src/main/java/forge/card/cost/CostReturn.java +++ b/src/main/java/forge/card/cost/CostReturn.java @@ -131,7 +131,7 @@ public class CostReturn extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, list.size()); + c = Cost.chooseXValue(source, ability, list.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostReveal.java b/src/main/java/forge/card/cost/CostReveal.java index 47c64509965..b42c0a77370 100644 --- a/src/main/java/forge/card/cost/CostReveal.java +++ b/src/main/java/forge/card/cost/CostReveal.java @@ -157,7 +157,7 @@ public class CostReveal extends CostPartWithList { if (num == null) { final String sVar = ability.getSVar(amount); if (sVar.equals("XChoice")) { - num = CostUtil.chooseXValue(source, ability, handList.size()); + num = Cost.chooseXValue(source, ability, handList.size()); } else { num = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostSacrifice.java b/src/main/java/forge/card/cost/CostSacrifice.java index 42375798133..dccbdb2f0e3 100644 --- a/src/main/java/forge/card/cost/CostSacrifice.java +++ b/src/main/java/forge/card/cost/CostSacrifice.java @@ -153,7 +153,7 @@ public class CostSacrifice extends CostPartWithList { if (c == null) { // Generalize this if (ability.getSVar(amount).equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, list.size()); + c = Cost.chooseXValue(source, ability, list.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostTapType.java b/src/main/java/forge/card/cost/CostTapType.java index ac4c6b9c2ac..188a04c5f5e 100644 --- a/src/main/java/forge/card/cost/CostTapType.java +++ b/src/main/java/forge/card/cost/CostTapType.java @@ -189,7 +189,7 @@ public class CostTapType extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, typeList.size()); + c = Cost.chooseXValue(source, ability, typeList.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostUntapType.java b/src/main/java/forge/card/cost/CostUntapType.java index 004d5cc5362..dbaca47dd9f 100644 --- a/src/main/java/forge/card/cost/CostUntapType.java +++ b/src/main/java/forge/card/cost/CostUntapType.java @@ -146,7 +146,7 @@ public class CostUntapType extends CostPartWithList { final String sVar = ability.getSVar(amount); // Generalize this if (sVar.equals("XChoice")) { - c = CostUtil.chooseXValue(source, ability, typeList.size()); + c = Cost.chooseXValue(source, ability, typeList.size()); } else { c = AbilityUtils.calculateAmount(source, amount, ability); } diff --git a/src/main/java/forge/card/cost/CostUtil.java b/src/main/java/forge/card/cost/CostUtil.java deleted file mode 100644 index e0e6c29aece..00000000000 --- a/src/main/java/forge/card/cost/CostUtil.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.card.cost; - -import forge.Card; -import forge.card.mana.ManaCostBeingPaid; -import forge.card.spellability.SpellAbility; -import forge.gui.GuiChoose; - -/** - * The Class CostUtil. - */ -public class CostUtil { - /** - * Checks for discard hand cost. - * - * @param cost - * the cost - * @return true, if successful - */ - public static boolean hasDiscardHandCost(final Cost cost) { - if (cost == null) { - return false; - } - for (final CostPart part : cost.getCostParts()) { - if (part instanceof CostDiscard) { - final CostDiscard disc = (CostDiscard) part; - if (disc.getType().equals("Hand")) { - return true; - } - } - } - return false; - } - - /** - * hasTapCost. - * - * @param cost - * the cost - * @param source - * the source - * @return true, if successful - */ - public static boolean hasTapCost(final Cost cost, final Card source) { - if (cost == null) { - return true; - } - for (final CostPart part : cost.getCostParts()) { - if (part instanceof CostTapType) { - return true; - } - } - return false; - } - - /** - * Choose x value. - * - * @param card - * the card - * @param sa - * the SpellAbility - * @param maxValue - * the max value - * @return the int - */ - public static int chooseXValue(final Card card, final SpellAbility sa, final int maxValue) { - /*final String chosen = sa.getSVar("ChosenX"); - if (chosen.length() > 0) { - return AbilityFactory.calculateAmount(card, "ChosenX", null); - }*/ - - final Integer[] choiceArray = new Integer[maxValue + 1]; - for (int i = 0; i < choiceArray.length; i++) { - choiceArray[i] = i; - } - final Integer chosenX = GuiChoose.one(card.toString() + " - Choose a Value for X", choiceArray); - sa.setSVar("ChosenX", Integer.toString(chosenX)); - card.setSVar("ChosenX", Integer.toString(chosenX)); - - return chosenX; - } - - - public static Cost combineCosts(Cost cost1, Cost cost2) { - if (cost1 == null) return cost2; - if (cost2 == null) return cost1; - - CostPartMana costPart2 = cost2.getCostMana(); - for (final CostPart part : cost1.getCostParts()) { - if (part instanceof CostPartMana && costPart2 != null) { - ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); - boolean xCanBe0 = ((CostPartMana) part).canXbe0() && costPart2.canXbe0(); - oldManaCost.combineManaCost(costPart2.getMana()); - 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)); - } else { - cost2.getCostParts().add(part); - } - } - return cost2; - } -} diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 998810f105b..0af4b99585e 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -959,6 +959,15 @@ public abstract class SpellAbility implements ISpellAbility { return sb.toString(); } + public void appendSubAbility(final AbilitySub toAdd) { + SpellAbility tailend = this; + while (tailend.getSubAbility() != null) { + tailend = tailend.getSubAbility(); + } + tailend.setSubAbility(toAdd); + } + + /** *

* Setter for the field subAbility. diff --git a/src/main/java/forge/game/GameActionUtil.java b/src/main/java/forge/game/GameActionUtil.java index ad61307bfc5..62cd5e7341a 100644 --- a/src/main/java/forge/game/GameActionUtil.java +++ b/src/main/java/forge/game/GameActionUtil.java @@ -53,7 +53,6 @@ import forge.card.cost.CostReturn; import forge.card.cost.CostReveal; import forge.card.cost.CostSacrifice; import forge.card.cost.CostTapType; -import forge.card.cost.CostUtil; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.AbilityManaPart; @@ -1250,10 +1249,8 @@ public final class GameActionUtil { return alternatives; } - public static Cost combineCosts(SpellAbility sa, String additionalCost) { - final Cost newCost = new Cost(sa.getSourceCard(), additionalCost, false); - Cost oldCost = sa.getPayCosts(); - return CostUtil.combineCosts(oldCost, newCost); + private static Cost combineCosts(SpellAbility sa, String additionalCost) { + return Cost.combine(sa.getPayCosts(), new Cost(sa.getSourceCard(), additionalCost, false)); } /** diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index a6ee39f3a1c..6c07062b224 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -36,8 +36,9 @@ import forge.card.ability.ApiType; import forge.card.ability.effects.CharmEffect; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; +import forge.card.cost.CostDiscard; +import forge.card.cost.CostPart; import forge.card.cost.CostPayment; -import forge.card.cost.CostUtil; import forge.card.spellability.AbilityStatic; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; @@ -124,6 +125,21 @@ public class ComputerUtil { return false; } + + private static boolean hasDiscardHandCost(final Cost cost) { + if (cost == null) { + return false; + } + for (final CostPart part : cost.getCostParts()) { + if (part instanceof CostDiscard) { + final CostDiscard disc = (CostDiscard) part; + if (disc.getType().equals("Hand")) { + return true; + } + } + } + return false; + } /** *

* counterSpellRestriction. @@ -149,7 +165,7 @@ public class ComputerUtil { // String totalMana = source.getSVar("PayX"); // + cost.getCMC() // Consider the costs here for relative "scoring" - if (CostUtil.hasDiscardHandCost(cost)) { + if (hasDiscardHandCost(cost)) { // Null Brooch aid restrict -= (ai.getCardsIn(ZoneType.Hand).size() * 20); } diff --git a/src/main/java/forge/game/phase/CombatUtil.java b/src/main/java/forge/game/phase/CombatUtil.java index 2cbdb922aab..c2a773503d2 100644 --- a/src/main/java/forge/game/phase/CombatUtil.java +++ b/src/main/java/forge/game/phase/CombatUtil.java @@ -39,7 +39,6 @@ import forge.card.CardType; import forge.card.ability.ApiType; import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; -import forge.card.cost.CostUtil; import forge.card.mana.ManaCost; import forge.card.spellability.Ability; import forge.card.spellability.AbilityStatic; @@ -1131,7 +1130,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 = CostUtil.combineCosts(attackCost, additionalCost); + attackCost = Cost.combine(attackCost, additionalCost); } } if (attackCost.toSimpleString().equals("")) {