diff --git a/forge-core/src/main/java/forge/card/mana/ManaAtom.java b/forge-core/src/main/java/forge/card/mana/ManaAtom.java index f2b814a17d3..3a645e0aea4 100644 --- a/forge-core/src/main/java/forge/card/mana/ManaAtom.java +++ b/forge-core/src/main/java/forge/card/mana/ManaAtom.java @@ -4,7 +4,7 @@ import forge.card.MagicColor; /** A bitmask to represent any mana symbol as an integer. */ public abstract class ManaAtom { - public static final int COLORLESS = 1 << 7; + public static final int COLORLESS = 1 << 6; /** The Constant WHITE. */ public static final int WHITE = MagicColor.WHITE; diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index 133338701ac..43ad3c78951 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -697,7 +697,7 @@ public class Cost { for (final CostPart part : cost1.getCostParts()) { if (part instanceof CostPartMana && costPart2 != null) { ManaCostBeingPaid oldManaCost = new ManaCostBeingPaid(((CostPartMana) part).getMana()); - oldManaCost.combineManaCost(costPart2.getMana()); + oldManaCost.addManaCost(costPart2.getMana()); String r2 = costPart2.getRestiction(); String r1 = ((CostPartMana) part).getRestiction(); String r = r1 == null ? r2 : ( r2 == null ? r1 : r1 + "." + r2); diff --git a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java index c8c5d6f9550..c683a28fc9b 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java @@ -18,10 +18,12 @@ package forge.game.mana; import java.util.ArrayList; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -279,7 +281,7 @@ public class ManaCostBeingPaid { } }; - return tryPayMana(colorMask, Iterables.filter(unpaidShards.keySet(), predCanBePaid)); + return tryPayMana(colorMask, Iterables.filter(unpaidShards.keySet(), predCanBePaid), pool.getPosibleColorUses(colorMask)); } /** @@ -303,27 +305,31 @@ public class ManaCostBeingPaid { } }; - return tryPayMana(mana.getColorCode(), Iterables.filter(unpaidShards.keySet(), predCanBePaid)); + byte inColor = mana.getColorCode(); + byte outColor = pool.getPosibleColorUses(inColor); + return tryPayMana(inColor, Iterables.filter(unpaidShards.keySet(), predCanBePaid), outColor); } - private boolean tryPayMana(final byte colorMask, Iterable payableShards) { - ManaCostShard choice = null; + private boolean tryPayMana(final byte colorMask, Iterable payableShards, byte possibleUses) { + Set choice = EnumSet.noneOf(ManaCostShard.class); + int priority = Integer.MIN_VALUE; for (ManaCostShard toPay : payableShards) { // if m is a better to pay than choice - if (choice == null) { - choice = toPay; - continue; - } - if (isFirstChoiceBetter(toPay, choice, colorMask)) { - choice = toPay; + int toPayPriority = getPayPriority(toPay, possibleUses); + if (toPayPriority > priority) { + priority = toPayPriority; + choice.clear(); } + if ( toPayPriority == priority ) + choice.add(toPay); } // for - if (choice == null) { + if (choice.isEmpty()) { return false; } - decreaseShard(choice, 1); - if (choice.isOr2Colorless() && choice.getColorMask() != colorMask) { + ManaCostShard chosenShard = Iterables.getFirst(choice, null); + decreaseShard(chosenShard, 1); + if (chosenShard.isOr2Colorless() && ( 0 != (chosenShard.getColorMask() & possibleUses) )) { this.increaseColorlessMana(1); } @@ -331,9 +337,6 @@ public class ManaCostBeingPaid { return true; } - private boolean isFirstChoiceBetter(ManaCostShard s1, ManaCostShard s2, byte colorMask) { - return getPayPriority(s1, colorMask) > getPayPriority(s2, colorMask); - } private int getPayPriority(ManaCostShard bill, byte paymentColor) { if (bill == ManaCostShard.COLORLESS) { @@ -342,7 +345,7 @@ public class ManaCostBeingPaid { if (bill.isMonoColor()) { if (bill.isOr2Colorless()) { - return bill.getColorMask() == paymentColor ? 9 : 4; + return (bill.getColorMask() & paymentColor & MagicColor.ALL_COLORS) != 0? 9 : 4; } if (!bill.isPhyrexian()) { return 10; @@ -362,7 +365,7 @@ public class ManaCostBeingPaid { } - public final void combineManaCost(final ManaCost extra) { + public final void addManaCost(final ManaCost extra) { for (ManaCostShard shard : extra) { if (shard == ManaCostShard.X) { cntX++; @@ -374,7 +377,7 @@ public class ManaCostBeingPaid { increaseColorlessMana(extra.getGenericCost()); } - public final void determineManaCostDifference(final ManaCost subThisManaCost) { + public final void subtractManaCost(final ManaCost subThisManaCost) { for (ManaCostShard shard : subThisManaCost) { if (shard == ManaCostShard.X) { cntX--; @@ -607,7 +610,7 @@ public class ManaCostBeingPaid { return; } - determineManaCostDifference(toSac.getManaCost()); + subtractManaCost(toSac.getManaCost()); sa.setSacrificedAsOffering(toSac); toSac.setUsedToPay(true); //stop it from interfering with mana input diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java index b8969317308..08748cb1ce2 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -427,9 +427,13 @@ public class ManaPool { colorConversionMatrix[i] = identityMatrix[i]; } - public boolean canPayForShardWithColor(ManaCostShard shard, byte color) { + public byte getPosibleColorUses(byte color) { int rowIdx = MagicColor.getIndexOfFirstColor(color); - byte line = colorConversionMatrix[rowIdx < 0 ? identityMatrix.length - 1 : rowIdx]; + return colorConversionMatrix[rowIdx < 0 ? identityMatrix.length - 1 : rowIdx]; + } + + public boolean canPayForShardWithColor(ManaCostShard shard, byte color) { + byte line = getPosibleColorUses(color); for(int i = 0; i < MagicColor.NUMBER_OR_COLORS; i++) { byte outColor = MagicColor.WUBRG[i]; diff --git a/forge-gui/src/main/java/forge/gui/input/InputPayMana.java b/forge-gui/src/main/java/forge/gui/input/InputPayMana.java index 2ae6f7d0040..f3a710bee3c 100644 --- a/forge-gui/src/main/java/forge/gui/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/gui/input/InputPayMana.java @@ -11,6 +11,7 @@ import forge.FThreads; import forge.ai.ComputerUtilMana; import forge.card.ColorSet; import forge.card.MagicColor; +import forge.card.mana.ManaAtom; import forge.card.mana.ManaCostShard; import forge.game.Game; import forge.game.ability.ApiType; @@ -110,8 +111,8 @@ public abstract class InputPayMana extends InputSyncronizedBase { if (manaCost.isAnyPartPayableWith(color, player.getManaPool())) { colorCanUse |= color; } if (manaCost.needsColor(color, player.getManaPool())) { colorNeeded |= color; } } - if (manaCost.isAnyPartPayableWith(MagicColor.COLORLESS, player.getManaPool())) - colorCanUse |= MagicColor.COLORLESS; + if (manaCost.isAnyPartPayableWith((byte) ManaAtom.COLORLESS, player.getManaPool())) + colorCanUse |= ManaAtom.COLORLESS; if ( 0 == colorCanUse ) // no mana cost or something return; @@ -266,6 +267,8 @@ public abstract class InputPayMana extends InputSyncronizedBase { if (0 != (neededColor & MagicColor.fromName(color))) { return true; } + if( (neededColor & ManaAtom.COLORLESS) != 0) + return true; } } return false; diff --git a/forge-gui/src/main/java/forge/gui/player/HumanPlay.java b/forge-gui/src/main/java/forge/gui/player/HumanPlay.java index b0e19b32148..d6e3d2bc4ec 100644 --- a/forge-gui/src/main/java/forge/gui/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/gui/player/HumanPlay.java @@ -726,7 +726,7 @@ public class HumanPlay { if ( timesMultikicked > 0 && ability.isAnnouncing("Multikicker")) { ManaCost mkCost = ability.getMultiKickerManaCost(); for(int i = 0; i < timesMultikicked; i++) - toPay.combineManaCost(mkCost); + toPay.addManaCost(mkCost); } InputPayMana inpPayment;