From c0c5c6328490c7b85303a69eec8cc4972388ad72 Mon Sep 17 00:00:00 2001 From: Alex Vasile <48962821+Alex-Vasile@users.noreply.github.com> Date: Fri, 12 Aug 2022 21:33:02 -0400 Subject: [PATCH] Fixed "One mana of any color" abilities from allowing you to make {C}. Closes #9351. --- .../AnyColorLandsProduceManaAbilityTest.java | 45 +++++++++++++ .../mana/AnyColorLandsProduceManaAbility.java | 66 +++++++------------ .../main/java/mage/constants/ManaType.java | 61 ++++++++++++----- 3 files changed, 115 insertions(+), 57 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/abilities/mana/AnyColorLandsProduceManaAbilityTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/mana/AnyColorLandsProduceManaAbilityTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/mana/AnyColorLandsProduceManaAbilityTest.java new file mode 100644 index 00000000000..97828f4d391 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/mana/AnyColorLandsProduceManaAbilityTest.java @@ -0,0 +1,45 @@ +package org.mage.test.cards.abilities.mana; + +import mage.abilities.mana.ManaOptions; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions; + +/** + * These tests check that {@link mage.abilities.mana.AnyColorLandsProduceManaAbility AnyColorLandsProduceManaAbility} + * works properly abilities where Colorless isn't a valid option. + *

+ * The test for ensuring that it works with colorless mana is handled in {@link org.mage.test.cards.mana.ReflectingPoolTest}. + * + * @author Alex-Vasile + */ +public class AnyColorLandsProduceManaAbilityTest extends CardTestPlayerBase { + + // Any color (but not colorless since that's not a color) + private static final String fellwarStone = "Fellwar Stone"; + + /** + * Fellwar Stone should not be able to tap for {C}. + *

+ * {@link mage.cards.f.FellwarStone Fellwar Stone} + * {T}: Add one mana of any color that a land an opponent controls could produce. + */ + @Test + public void testColorlessNotAllowed() { + addCard(Zone.BATTLEFIELD, playerA, fellwarStone); + + addCard(Zone.BATTLEFIELD, playerB, "Mountain"); + addCard(Zone.BATTLEFIELD, playerB, "Desert"); + + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame); + Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); + assertManaOptions("{R}", manaOptions); + } +} diff --git a/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java b/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java index 76ab7371156..62c3136bb14 100644 --- a/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java +++ b/Mage/src/main/java/mage/abilities/mana/AnyColorLandsProduceManaAbility.java @@ -57,7 +57,7 @@ public class AnyColorLandsProduceManaAbility extends ActivatedManaAbilityImpl { } public static Set getManaTypesFromPermanent(Permanent permanent, Game game) { - Set allTypes = new HashSet<>(); + Set allTypes = new HashSet<>(6); if (permanent != null) { Abilities manaAbilities = permanent.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD); for (ActivatedManaAbilityImpl ability : manaAbilities) { @@ -73,7 +73,7 @@ class AnyColorLandsProduceManaEffect extends ManaEffect { private final FilterPermanent filter; private final boolean onlyColors; // false if mana types can be produced (also Colorless mana), if true only colors can be produced (no Colorless mana). - private boolean inManaTypeCalculation = false; + private transient boolean inManaTypeCalculation = false; AnyColorLandsProduceManaEffect(TargetController targetController, boolean onlyColors, FilterPermanent filter) { super(); @@ -97,57 +97,36 @@ class AnyColorLandsProduceManaEffect extends ManaEffect { @Override public List getNetMana(Game game, Ability source) { - List netManas = new ArrayList<>(); - if (game != null) { - netManas = ManaType.getManaListFromManaTypes(getManaTypes(game, source), onlyColors); - } - return netManas; + return game == null ? new ArrayList<>() : ManaType.getManaListFromManaTypes(getManaTypes(game, source), onlyColors); } @Override public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); if (game == null) { - return mana; + return null; } - Choice choice = ManaType.getChoiceOfManaTypes(getManaTypes(game, source), onlyColors); - if (!choice.getChoices().isEmpty()) { + + Set types = getManaTypes(game, source); + if (types.isEmpty()) { + return null; + } + + Choice choice = ManaType.getChoiceOfManaTypes(types, onlyColors); + if (choice.getChoices().size() == 1) { + choice.setChoice(choice.getChoices().iterator().next()); + } else { Player player = game.getPlayer(source.getControllerId()); - if (choice.getChoices().size() == 1) { - choice.setChoice(choice.getChoices().iterator().next()); - } else { - if (player == null || !player.choose(outcome, choice, game)) { - return null; - } - } - if (choice.getChoice() != null) { - switch (choice.getChoice()) { - case "Black": - mana.setBlack(1); - break; - case "Blue": - mana.setBlue(1); - break; - case "Red": - mana.setRed(1); - break; - case "Green": - mana.setGreen(1); - break; - case "White": - mana.setWhite(1); - break; - case "Colorless": - mana.setColorless(1); - break; - } + if (player == null || !player.choose(outcome, choice, game)) { + return null; } } - return mana; + + ManaType chosenType = ManaType.findByName(choice.getChoice()); + return chosenType == null ? null : new Mana(chosenType); } private Set getManaTypes(Game game, Ability source) { - Set types = new HashSet<>(); + Set types = new HashSet<>(6); if (game == null || game.getPhase() == null) { return types; } @@ -162,6 +141,11 @@ class AnyColorLandsProduceManaEffect extends ManaEffect { } } inManaTypeCalculation = false; + + if (onlyColors) { + types.remove(ManaType.COLORLESS); + } + return types; } diff --git a/Mage/src/main/java/mage/constants/ManaType.java b/Mage/src/main/java/mage/constants/ManaType.java index 728be6324e4..c71e389b33e 100644 --- a/Mage/src/main/java/mage/constants/ManaType.java +++ b/Mage/src/main/java/mage/constants/ManaType.java @@ -53,7 +53,7 @@ public enum ManaType { if (types.contains(ManaType.WHITE)) { choice.getChoices().add("White"); } - if (types.contains(ManaType.COLORLESS)) { + if (types.contains(ManaType.COLORLESS) && !onlyColors) { choice.getChoices().add("Colorless"); } return choice; @@ -95,21 +95,22 @@ public enum ManaType { manaTypes.add(ManaType.GREEN); manaTypes.add(ManaType.WHITE); manaTypes.add(ManaType.RED); - } - if (mana.getBlack() > 0) { - manaTypes.add(ManaType.BLACK); - } - if (mana.getBlue() > 0) { - manaTypes.add(ManaType.BLUE); - } - if (mana.getGreen() > 0) { - manaTypes.add(ManaType.GREEN); - } - if (mana.getWhite() > 0) { - manaTypes.add(ManaType.WHITE); - } - if (mana.getRed() > 0) { - manaTypes.add(ManaType.RED); + } else { + if (mana.getBlack() > 0) { + manaTypes.add(ManaType.BLACK); + } + if (mana.getBlue() > 0) { + manaTypes.add(ManaType.BLUE); + } + if (mana.getGreen() > 0) { + manaTypes.add(ManaType.GREEN); + } + if (mana.getWhite() > 0) { + manaTypes.add(ManaType.WHITE); + } + if (mana.getRed() > 0) { + manaTypes.add(ManaType.RED); + } } if (mana.getColorless() > 0) { manaTypes.add(ManaType.COLORLESS); @@ -117,6 +118,34 @@ public enum ManaType { return manaTypes; } + /** + * Utility function to find the ManaType associated with a name without needing to have the if-statements + * cluttering up the code. + *

+ * Used for things like mapping back to a ManaType after the user chose from several of them. + * + * @param name The name of the mana to find + * @return The ManaType representing that mana (or null) + */ + public static ManaType findByName(String name) { + switch (name) { + case "Black": + return ManaType.BLACK; + case "Blue": + return ManaType.BLUE; + case "Red": + return ManaType.RED; + case "Green": + return ManaType.GREEN; + case "White": + return ManaType.WHITE; + case "Colorless": + return ManaType.COLORLESS; + default: + return null; + } + } + public static Set getManaTypesFromManaList(List manaList) { Set manaTypes = new HashSet<>(); for (Mana mana : manaList) {