forked from External/mage
* Monohybrid mana cost improves:
* fixed wrong manually pay by mana pool (it pays generic cost instead colored part of monohybrid); * fixed not working cost reduction effects (now monohybrid cost will be reduced correctly with some limitation, see #6130);
This commit is contained in:
parent
13ad86cb21
commit
b5acf64772
9 changed files with 589 additions and 78 deletions
|
|
@ -7,13 +7,16 @@ import mage.abilities.SpellAbility;
|
|||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.mana.*;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.ColoredManaSymbol;
|
||||
import mage.constants.EmptyNames;
|
||||
import mage.constants.ManaType;
|
||||
import mage.filter.Filter;
|
||||
import mage.game.CardState;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.token.Token;
|
||||
import mage.util.functions.CopyTokenFunction;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
|
@ -90,34 +93,118 @@ public final class CardUtil {
|
|||
}
|
||||
|
||||
private static ManaCosts<ManaCost> adjustCost(ManaCosts<ManaCost> manaCosts, int reduceCount) {
|
||||
int restToReduce = reduceCount;
|
||||
ManaCosts<ManaCost> adjustedCost = new ManaCostsImpl<>();
|
||||
boolean updated = false;
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
if (manaCost instanceof SnowManaCost) {
|
||||
adjustedCost.add(manaCost);
|
||||
continue;
|
||||
|
||||
// nothing to change
|
||||
if (reduceCount == 0) {
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
Mana mana = manaCost.getOptions().get(0);
|
||||
int colorless = mana != null ? mana.getGeneric() : 0;
|
||||
if (restToReduce != 0 && colorless > 0) {
|
||||
if ((colorless - restToReduce) > 0) {
|
||||
int newColorless = colorless - restToReduce;
|
||||
adjustedCost.add(new GenericManaCost(newColorless));
|
||||
restToReduce = 0;
|
||||
} else {
|
||||
restToReduce -= colorless;
|
||||
return adjustedCost;
|
||||
}
|
||||
|
||||
// remove or save cost
|
||||
if (reduceCount > 0) {
|
||||
int restToReduce = reduceCount;
|
||||
|
||||
// first run - priority single option costs (generic)
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
if (manaCost instanceof SnowManaCost) {
|
||||
adjustedCost.add(manaCost);
|
||||
continue;
|
||||
}
|
||||
updated = true;
|
||||
} else {
|
||||
adjustedCost.add(manaCost);
|
||||
|
||||
if (manaCost.getOptions().size() == 0) {
|
||||
adjustedCost.add(manaCost);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore monohybrid and other multi-option mana (for potential support)
|
||||
if (manaCost.getOptions().size() > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generic mana reduce
|
||||
Mana mana = manaCost.getOptions().get(0);
|
||||
int colorless = mana != null ? mana.getGeneric() : 0;
|
||||
if (restToReduce != 0 && colorless > 0) {
|
||||
if ((colorless - restToReduce) > 0) {
|
||||
// partly reduce
|
||||
int newColorless = colorless - restToReduce;
|
||||
adjustedCost.add(new GenericManaCost(newColorless));
|
||||
restToReduce = 0;
|
||||
} else {
|
||||
// full reduce - ignore cost
|
||||
restToReduce -= colorless;
|
||||
}
|
||||
} else {
|
||||
// nothing to reduce
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
|
||||
// second run - priority for multi option costs (monohybrid)
|
||||
//
|
||||
// from Reaper King:
|
||||
// If an effect reduces the cost to cast a spell by an amount of generic mana, it applies to a monocolored hybrid
|
||||
// spell only if you’ve chosen a method of paying for it that includes generic mana.
|
||||
// (2008-05-01)
|
||||
// TODO: xmage don't use announce for hybrid mana (instead it uses auto-pay), so that's workaround uses first hybrid to reduce (see https://github.com/magefree/mage/issues/6130 )
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
if (manaCost.getOptions().size() <= 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (manaCost instanceof MonoHybridManaCost) {
|
||||
// current implemention supports only 1 hybrid cost per object
|
||||
MonoHybridManaCost mono = (MonoHybridManaCost) manaCost;
|
||||
int colorless = mono.getOptions().get(1).getGeneric();
|
||||
if (restToReduce != 0 && colorless > 0) {
|
||||
if ((colorless - restToReduce) > 0) {
|
||||
// partly reduce
|
||||
int newColorless = colorless - restToReduce;
|
||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), newColorless));
|
||||
restToReduce = 0;
|
||||
} else {
|
||||
// full reduce
|
||||
adjustedCost.add(new MonoHybridManaCost(mono.getManaColor(), 0));
|
||||
restToReduce -= colorless;
|
||||
}
|
||||
} else {
|
||||
// nothing to reduce
|
||||
adjustedCost.add(mono.copy());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// unsupported multi-option mana types for reduce (like HybridManaCost)
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
|
||||
// for increasing spell cost effects
|
||||
if (!updated && reduceCount < 0) {
|
||||
adjustedCost.add(new GenericManaCost(-reduceCount));
|
||||
// increase cost (add to first generic or add new)
|
||||
if (reduceCount < 0) {
|
||||
Assert.assertEquals("must be empty", 0, adjustedCost.size());
|
||||
boolean added = false;
|
||||
for (ManaCost manaCost : manaCosts) {
|
||||
if (reduceCount != 0 && manaCost instanceof GenericManaCost) {
|
||||
// add increase cost to existing generic
|
||||
GenericManaCost gen = (GenericManaCost) manaCost;
|
||||
adjustedCost.add(new GenericManaCost(gen.getOptions().get(0).getGeneric() + -reduceCount));
|
||||
reduceCount = 0;
|
||||
added = true;
|
||||
} else {
|
||||
// non-generic mana
|
||||
adjustedCost.add(manaCost.copy());
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
// add increase cost as new
|
||||
adjustedCost.add(new GenericManaCost(-reduceCount));
|
||||
}
|
||||
}
|
||||
|
||||
// cost modifying effects requiring snow mana unnecessarily (fixes #6000)
|
||||
Filter filter = manaCosts.stream()
|
||||
.filter(manaCost -> !(manaCost instanceof SnowManaCost))
|
||||
.map(ManaCost::getSourceFilter)
|
||||
|
|
@ -642,4 +729,23 @@ public final class CardUtil {
|
|||
res.addAll(mana2);
|
||||
return res;
|
||||
}
|
||||
|
||||
public static ColoredManaSymbol manaTypeToColoredManaSymbol(ManaType manaType) {
|
||||
switch (manaType) {
|
||||
case BLACK:
|
||||
return ColoredManaSymbol.B;
|
||||
case BLUE:
|
||||
return ColoredManaSymbol.U;
|
||||
case GREEN:
|
||||
return ColoredManaSymbol.G;
|
||||
case RED:
|
||||
return ColoredManaSymbol.R;
|
||||
case WHITE:
|
||||
return ColoredManaSymbol.W;
|
||||
case GENERIC:
|
||||
case COLORLESS:
|
||||
default:
|
||||
throw new IllegalArgumentException("Wrong mana type " + manaType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue