* Fixed that casting spells without mana costs did not work correctly for spells with mono hybrid mana costs (e.g. Beseech the Queen by Omniscience) fixes #1404.

This commit is contained in:
LevelX2 2015-12-06 09:37:45 +01:00
parent 2619202931
commit 259d6744ae
3 changed files with 133 additions and 23 deletions

View file

@ -41,4 +41,27 @@ public class OmniscienceTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Knight of the White Orchid", 0); assertPermanentCount(playerA, "Knight of the White Orchid", 0);
} }
/**
* If you cast a card with monocolored hybrid mana with Omniscience's
* alternate casting cost, you will be asked to pay 1 colorless mana per
* monocolored hybrid mana in its cost. For example, while casting Beseech
* the Queen, you are asked to pay {1}{1}{1}.
*/
@Test
public void testMonocoloredHybridMana() {
// You may cast nonland cards from your hand without paying their mana costs.
addCard(Zone.BATTLEFIELD, playerA, "Omniscience", 1);
// ({2B} can be paid with any two mana or with {B}. This card's converted mana cost is 6.)
// Search your library for a card with converted mana cost less than or equal to the number of lands you control, reveal it, and put it into your hand. Then shuffle your library.
addCard(Zone.HAND, playerA, "Beseech the Queen", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Beseech the Queen");
setStopAt(1, PhaseStep.END_TURN);
execute();
// Beseech the Queen is cast because it is free
assertGraveyardCount(playerA, "Beseech the Queen", 1);
}
} }

View file

@ -5,6 +5,7 @@ import java.util.LinkedHashMap;
import java.util.UUID; import java.util.UUID;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.mana.BasicManaAbility; import mage.abilities.mana.BasicManaAbility;
@ -14,6 +15,7 @@ import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility; import mage.abilities.mana.WhiteManaAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.util.CardUtil;
import mage.util.ManaUtil; import mage.util.ManaUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -125,6 +127,49 @@ public class ManaUtilTest extends CardTestPlayerBase {
} }
/**
* Mana.enough is used to check if a spell can be cast with an given amount
* of avalable mana
*/
@Test
public void testManaIncrease() {
// cost - reduction - rest
testManaReduction("{G}{G}", "{G}", "{G}");
testManaReduction("{1}{G}{G}", "{G}", "{1}{G}");
testManaReduction("{B}{B}", "{B}", "{B}");
testManaReduction("{1}{B}{B}", "{B}", "{1}{B}");
testManaReduction("{W}{W}", "{W}", "{W}");
testManaReduction("{1}{W}{W}", "{W}", "{1}{W}");
testManaReduction("{U}{U}", "{U}", "{U}");
testManaReduction("{1}{U}{U}", "{U}", "{1}{U}");
testManaReduction("{R}{R}", "{R}", "{R}");
testManaReduction("{1}{R}{R}", "{R}", "{1}{R}");
testManaReduction("{R}{G}{B}{U}{W}", "{R}{G}{B}{U}{W}", "{0}");
// Hybrid Mana
testManaReduction("{2/B}{2/B}{2/B}", "{B}{B}", "{2/B}");
testManaReduction("{2/B}{2/B}{2/B}", "{B}{B}{B}", "{0}");
testManaReduction("{2/W}{2/W}{2/W}", "{W}{W}", "{2/W}");
testManaReduction("{2/W}{2/W}{2/W}", "{W}{W}{W}", "{0}");
testManaReduction("{G/B}{G/B}{G/B}", "{B}{G}{B}", "{0}");
}
/**
* Checks if a given mana reduction left the expected amount of mana costs
*
* @param manaCostsToPay
* @param availablyAny
* @param available
* @param expected
*/
private void testManaReduction(String manaCostsToPay, String manaToReduce, String restMana) {
SpellAbility spellAbility = new SpellAbility(new ManaCostsImpl(manaCostsToPay), "Test");
CardUtil.adjustCost(spellAbility, new ManaCostsImpl(manaToReduce), true);
Assert.assertTrue("The mana cost to pay " + manaCostsToPay + " reduced by " + manaToReduce + " should left " + restMana + " but the rest was " + spellAbility.getManaCostsToPay().getText(), spellAbility.getManaCostsToPay().getText().equals(restMana));
}
/** /**
* Common way to test ManaUtil.tryToAutoPay * Common way to test ManaUtil.tryToAutoPay
* *

View file

@ -45,6 +45,7 @@ import mage.abilities.costs.mana.HybridManaCost;
import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.MonoHybridManaCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.keyword.ChangelingAbility;
import mage.cards.Card; import mage.cards.Card;
@ -292,14 +293,21 @@ public class CardUtil {
Mana reduceMana = new Mana(); Mana reduceMana = new Mana();
for (ManaCost manaCost : manaCostsToReduce) { for (ManaCost manaCost : manaCostsToReduce) {
reduceMana.add(manaCost.getMana()); if (manaCost instanceof MonoHybridManaCost) {
reduceMana.add(Mana.ColorlessMana(2));
} else {
reduceMana.add(manaCost.getMana());
}
} }
ManaCosts<ManaCost> manaCostToCheckForColorless = new ManaCostsImpl<>();
// subtract colored mana // subtract colored mana
for (ManaCost newManaCost : previousCost) { for (ManaCost newManaCost : previousCost) {
Mana mana = newManaCost.getMana(); Mana mana = newManaCost.getMana();
if (mana.getColorless() > 0) { if (!(newManaCost instanceof MonoHybridManaCost) && mana.getColorless() > 0) {
manaCostToCheckForColorless.add(newManaCost);
continue; continue;
} }
boolean hybridMana = newManaCost instanceof HybridManaCost;
if (mana.getBlack() > 0 && reduceMana.getBlack() > 0) { if (mana.getBlack() > 0 && reduceMana.getBlack() > 0) {
if (reduceMana.getBlack() > mana.getBlack()) { if (reduceMana.getBlack() > mana.getBlack()) {
reduceMana.setBlack(reduceMana.getBlack() - mana.getBlack()); reduceMana.setBlack(reduceMana.getBlack() - mana.getBlack());
@ -308,6 +316,9 @@ public class CardUtil {
mana.setBlack(mana.getBlack() - reduceMana.getBlack()); mana.setBlack(mana.getBlack() - reduceMana.getBlack());
reduceMana.setBlack(0); reduceMana.setBlack(0);
} }
if (hybridMana) {
continue;
}
} }
if (mana.getRed() > 0 && reduceMana.getRed() > 0) { if (mana.getRed() > 0 && reduceMana.getRed() > 0) {
if (reduceMana.getRed() > mana.getRed()) { if (reduceMana.getRed() > mana.getRed()) {
@ -317,6 +328,9 @@ public class CardUtil {
mana.setRed(mana.getRed() - reduceMana.getRed()); mana.setRed(mana.getRed() - reduceMana.getRed());
reduceMana.setRed(0); reduceMana.setRed(0);
} }
if (hybridMana) {
continue;
}
} }
if (mana.getBlue() > 0 && reduceMana.getBlue() > 0) { if (mana.getBlue() > 0 && reduceMana.getBlue() > 0) {
if (reduceMana.getBlue() > mana.getBlue()) { if (reduceMana.getBlue() > mana.getBlue()) {
@ -326,6 +340,9 @@ public class CardUtil {
mana.setBlue(mana.getBlue() - reduceMana.getBlue()); mana.setBlue(mana.getBlue() - reduceMana.getBlue());
reduceMana.setBlue(0); reduceMana.setBlue(0);
} }
if (hybridMana) {
continue;
}
} }
if (mana.getGreen() > 0 && reduceMana.getGreen() > 0) { if (mana.getGreen() > 0 && reduceMana.getGreen() > 0) {
if (reduceMana.getGreen() > mana.getGreen()) { if (reduceMana.getGreen() > mana.getGreen()) {
@ -335,6 +352,9 @@ public class CardUtil {
mana.setGreen(mana.getGreen() - reduceMana.getGreen()); mana.setGreen(mana.getGreen() - reduceMana.getGreen());
reduceMana.setGreen(0); reduceMana.setGreen(0);
} }
if (hybridMana) {
continue;
}
} }
if (mana.getWhite() > 0 && reduceMana.getWhite() > 0) { if (mana.getWhite() > 0 && reduceMana.getWhite() > 0) {
if (reduceMana.getWhite() > mana.getWhite()) { if (reduceMana.getWhite() > mana.getWhite()) {
@ -344,15 +364,22 @@ public class CardUtil {
mana.setWhite(mana.getWhite() - reduceMana.getWhite()); mana.setWhite(mana.getWhite() - reduceMana.getWhite());
reduceMana.setWhite(0); reduceMana.setWhite(0);
} }
} if (hybridMana) {
if (newManaCost instanceof HybridManaCost) { continue;
if (mana.count() > 1) {
adjustedCost.add(newManaCost);
} }
} else if (mana.count() > 0) {
adjustedCost.add(newManaCost);
} }
if (mana.count() > 0) {
if (newManaCost instanceof MonoHybridManaCost) {
if (mana.count() == 2) {
reduceMana.setColorless(reduceMana.getColorless() - 2);
continue;
}
}
manaCostToCheckForColorless.add(newManaCost);
}
} }
// subtract colorless mana, use all mana that is left // subtract colorless mana, use all mana that is left
int reduceAmount; int reduceAmount;
if (convertToGeneric) { if (convertToGeneric) {
@ -360,23 +387,38 @@ public class CardUtil {
} else { } else {
reduceAmount = reduceMana.getColorless(); reduceAmount = reduceMana.getColorless();
} }
for (ManaCost newManaCost : previousCost) { if (reduceAmount > 0) {
Mana mana = newManaCost.getMana(); for (ManaCost newManaCost : manaCostToCheckForColorless) {
if (mana.getColorless() == 0) { Mana mana = newManaCost.getMana();
continue; if (mana.getColorless() == 0 || reduceAmount == 0) {
} adjustedCost.add(newManaCost);
if (mana.getColorless() > 0 && reduceAmount > 0) { continue;
if (reduceAmount > mana.getColorless()) { }
reduceAmount -= mana.getColorless(); if (newManaCost instanceof MonoHybridManaCost) {
mana.setColorless(0); if (reduceAmount > 1) {
} else { reduceAmount -= 2;
mana.setColorless(mana.getColorless() - reduceAmount); mana.clear();
reduceAmount = 0; }
continue;
}
if (mana.getColorless() > 0) {
if (reduceAmount > mana.getColorless()) {
reduceAmount -= mana.getColorless();
mana.setColorless(0);
} else {
mana.setColorless(mana.getColorless() - reduceAmount);
reduceAmount = 0;
}
}
if (mana.count() > 0) {
adjustedCost.add(0, new GenericManaCost(mana.count()));
} }
} }
if (mana.count() > 0) { } else {
adjustedCost.add(0, new GenericManaCost(mana.count())); adjustedCost.addAll(manaCostToCheckForColorless);
} }
if (adjustedCost.isEmpty()) {
adjustedCost.add(new GenericManaCost(0)); // neede to check if cost was reduced to 0
} }
adjustedCost.setSourceFilter(previousCost.getSourceFilter()); // keep mana source restrictions adjustedCost.setSourceFilter(previousCost.getSourceFilter()); // keep mana source restrictions
spellAbility.getManaCostsToPay().clear(); spellAbility.getManaCostsToPay().clear();