diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 37a1a96a89e..ab9d96e0a33 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -29,6 +29,7 @@ import forge.game.ability.effects.AttachEffect; import forge.game.card.*; import forge.game.event.*; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaConversionService; import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; @@ -785,7 +786,7 @@ public class GameAction { game.getReplacementHandler().cleanUpTemporaryReplacements(); for (final Player p : game.getPlayers()) { - p.getManaPool().restoreColorReplacements(); + new ManaConversionService(p.getManaPool()).restoreColorReplacements(); p.clearStaticAbilities(); } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index f3b9d374e66..c980a16b4de 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -18,6 +18,7 @@ import forge.game.ability.AbilityFactory.AbilityRecordType; import forge.game.card.*; import forge.game.cost.Cost; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaConversionService; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerCollection; @@ -1663,7 +1664,7 @@ public class AbilityUtils { } } // AdjustColorReplacement has two different matrices handling final mana conversion under the covers - p.getManaPool().adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); + new ManaConversionService(p.getManaPool()).adjustColorReplacement(ManaAtom.fromName(c), convertByte, additive); } } } diff --git a/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java b/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java new file mode 100644 index 00000000000..0a047f766d7 --- /dev/null +++ b/forge-game/src/main/java/forge/game/mana/IManaConversionMatrix.java @@ -0,0 +1,11 @@ +package forge.game.mana; + +import forge.card.mana.ManaAtom; + +public interface IManaConversionMatrix { + // Conversion matrix ORs byte values to make mana more payable + // Restrictive matrix ANDs byte values to make mana less payable + byte[] colorConversionMatrix = new byte[ManaAtom.MANATYPES.length]; + byte[] colorRestrictionMatrix = new byte[ManaAtom.MANATYPES.length]; + +} diff --git a/forge-game/src/main/java/forge/game/mana/ManaConversionService.java b/forge-game/src/main/java/forge/game/mana/ManaConversionService.java new file mode 100644 index 00000000000..513d47cd5db --- /dev/null +++ b/forge-game/src/main/java/forge/game/mana/ManaConversionService.java @@ -0,0 +1,36 @@ +package forge.game.mana; + +import forge.card.mana.ManaAtom; + +public class ManaConversionService { + static byte[] identityMatrix = { ManaAtom.WHITE, ManaAtom.BLUE, ManaAtom.BLACK, ManaAtom.RED, ManaAtom.GREEN, ManaAtom.COLORLESS }; + + IManaConversionMatrix matrix; + + public ManaConversionService(IManaConversionMatrix mtrx) { + matrix = mtrx; + } + + public void adjustColorReplacement(byte originalColor, byte replacementColor, boolean additive) { + // Fix the index without hardcodes + int rowIdx = ManaAtom.getIndexOfFirstManaType(originalColor); + rowIdx = rowIdx < 0 ? identityMatrix.length - 1 : rowIdx; + if (additive) { + matrix.colorConversionMatrix[rowIdx] |= replacementColor; + } + else { + matrix.colorRestrictionMatrix[rowIdx] &= replacementColor; + } + } + + public void restoreColorReplacements() { + // By default each color can only be paid by itself ( {G} -> {G}, {C} -> {C} + for (int i = 0; i < matrix.colorConversionMatrix.length; i++) { + matrix.colorConversionMatrix[i] = identityMatrix[i]; + } + // By default all mana types are unrestricted + for (int i = 0; i < matrix.colorRestrictionMatrix.length; i++) { + matrix.colorRestrictionMatrix[i] = ManaAtom.ALL_MANA_TYPES; + } + } +} 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 d76c2145973..0b0c4f3924c 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -20,7 +20,6 @@ package forge.game.mana; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; - import forge.GameCommand; import forge.card.MagicColor; import forge.card.mana.ManaAtom; @@ -36,14 +35,9 @@ import forge.game.player.Player; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; - import org.apache.commons.lang3.StringUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** *
@@ -53,13 +47,13 @@ import java.util.List;
* @author Forge
* @version $Id$
*/
-public class ManaPool implements Iterable
@@ -81,6 +76,7 @@ public class HumanPlaySpellAbility {
final Card c = ability.getHostCard();
final CardPlayOption option = c.mayPlay(ability.getMayPlay());
+ ManaConversionService service = new ManaConversionService(manapool);
boolean manaTypeConversion = false;
boolean manaColorConversion = false;
@@ -169,11 +165,12 @@ public class HumanPlaySpellAbility {
ability.getHostCard().unanimateBestow();
}
}
+
if (manaTypeConversion || manaColorConversion || keywordColor) {
- manapool.restoreColorReplacements();
+ service.restoreColorReplacements();
}
if (playerManaConversion) {
- manapool.restoreColorReplacements();
+ service.restoreColorReplacements();
human.decNumManaConversion();
}
return false;
@@ -196,7 +193,7 @@ public class HumanPlaySpellAbility {
clearTargets(ability);
}
if (manaTypeConversion || manaColorConversion || keywordColor) {
- manapool.restoreColorReplacements();
+ service.restoreColorReplacements();
}
}
return true;