Fixed "One mana of any color" abilities from allowing you to make {C}. Closes #9351.

This commit is contained in:
Alex Vasile 2022-08-12 21:33:02 -04:00
parent 6b5a4de999
commit c0c5c63284
3 changed files with 115 additions and 57 deletions

View file

@ -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.
* <p>
* 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}.
* <p>
* {@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);
}
}

View file

@ -57,7 +57,7 @@ public class AnyColorLandsProduceManaAbility extends ActivatedManaAbilityImpl {
}
public static Set<ManaType> getManaTypesFromPermanent(Permanent permanent, Game game) {
Set<ManaType> allTypes = new HashSet<>();
Set<ManaType> allTypes = new HashSet<>(6);
if (permanent != null) {
Abilities<ActivatedManaAbilityImpl> 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<Mana> getNetMana(Game game, Ability source) {
List<Mana> 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<ManaType> 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<ManaType> getManaTypes(Game game, Ability source) {
Set types = new HashSet<>();
Set<ManaType> 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;
}

View file

@ -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.
* <p>
* 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<ManaType> getManaTypesFromManaList(List<Mana> manaList) {
Set<ManaType> manaTypes = new HashSet<>();
for (Mana mana : manaList) {