Merge branch 'emblazoned_golem' into 'master'

Add Emblazoned Golem

See merge request core-developers/forge!4467
This commit is contained in:
Michael Kamensky
2021-04-12 04:17:33 +00:00
6 changed files with 88 additions and 19 deletions

View File

@@ -341,7 +341,7 @@ public class ComputerUtilMana {
continue;
}
if (canPayShardWithSpellAbility(toPay, ai, paymentChoice, sa, checkCosts)) {
if (canPayShardWithSpellAbility(toPay, ai, paymentChoice, sa, checkCosts, cost.getXManaCostPaidByColor())) {
return paymentChoice;
}
}
@@ -547,7 +547,7 @@ public class ComputerUtilMana {
}
// get a mana of this type from floating, bail if none available
final Mana mana = getMana(ai, part, sa, cost.getSourceRestriction(), (byte) -1);
final Mana mana = getMana(ai, part, sa, cost.getSourceRestriction(), (byte) -1, cost.getXManaCostPaidByColor());
if (mana != null) {
if (ai.getManaPool().tryPayCostWithMana(sa, cost, mana, false)) {
manaSpentToPay.add(0, mana);
@@ -936,7 +936,7 @@ public class ComputerUtilMana {
}
// get a mana of this type from floating, bail if none available
final Mana mana = getMana(ai, part, sa, cost.getSourceRestriction(), hasConverge ? cost.getColorsPaid() : -1);
final Mana mana = getMana(ai, part, sa, cost.getSourceRestriction(), hasConverge ? cost.getColorsPaid() : -1, cost.getXManaCostPaidByColor());
if (mana != null) {
if (ai.getManaPool().tryPayCostWithMana(sa, cost, mana, test)) {
manaSpentToPay.add(0, mana);
@@ -965,8 +965,10 @@ public class ComputerUtilMana {
* a {@link forge.game.spellability.SpellAbility} object.
* @return a {@link forge.game.mana.Mana} object.
*/
private static Mana getMana(final Player ai, final ManaCostShard shard, final SpellAbility saBeingPaidFor, String restriction, final byte colorsPaid) {
final List<Pair<Mana, Integer>> weightedOptions = selectManaToPayFor(ai.getManaPool(), shard, saBeingPaidFor, restriction, colorsPaid);
private static Mana getMana(final Player ai, final ManaCostShard shard, final SpellAbility saBeingPaidFor,
String restriction, final byte colorsPaid, Map<String, Integer> xManaCostPaidByColor) {
final List<Pair<Mana, Integer>> weightedOptions = selectManaToPayFor(ai.getManaPool(), shard,
saBeingPaidFor, restriction, colorsPaid, xManaCostPaidByColor);
// Exclude border case
if (weightedOptions.isEmpty()) {
@@ -1015,9 +1017,13 @@ public class ComputerUtilMana {
}
private static List<Pair<Mana, Integer>> selectManaToPayFor(final ManaPool manapool, final ManaCostShard shard,
final SpellAbility saBeingPaidFor, String restriction, final byte colorsPaid) {
final SpellAbility saBeingPaidFor, String restriction, final byte colorsPaid, Map<String, Integer> xManaCostPaidByColor) {
final List<Pair<Mana, Integer>> weightedOptions = new ArrayList<>();
for (final Mana thisMana : manapool) {
if (shard == ManaCostShard.COLORED_X && !ManaCostBeingPaid.canColoredXShardBePaidByColor(MagicColor.toShortString(thisMana.getColor()), xManaCostPaidByColor)) {
continue;
}
if (!manapool.canPayForShardWithColor(shard, thisMana.getColor())) {
continue;
}
@@ -1093,7 +1099,7 @@ public class ComputerUtilMana {
}
}
private static boolean canPayShardWithSpellAbility(ManaCostShard toPay, Player ai, SpellAbility ma, SpellAbility sa, boolean checkCosts) {
private static boolean canPayShardWithSpellAbility(ManaCostShard toPay, Player ai, SpellAbility ma, SpellAbility sa, boolean checkCosts, Map<String, Integer> xManaCostPaidByColor) {
final Card sourceCard = ma.getHostCard();
if (isManaSourceReserved(ai, sourceCard, sa)) {
@@ -1131,6 +1137,10 @@ public class ComputerUtilMana {
if (m.isComboMana()) {
for (String s : m.getComboColors().split(" ")) {
if (toPay == ManaCostShard.COLORED_X && !ManaCostBeingPaid.canColoredXShardBePaidByColor(s, xManaCostPaidByColor)) {
continue;
}
if ("Any".equals(s) || ai.getManaPool().canPayForShardWithColor(toPay, ManaAtom.fromName(s)))
return true;
}
@@ -1141,6 +1151,9 @@ public class ComputerUtilMana {
Set<String> reflected = CardUtil.getReflectableManaColors(ma);
for (byte c : MagicColor.WUBRG) {
if (toPay == ManaCostShard.COLORED_X && !ManaCostBeingPaid.canColoredXShardBePaidByColor(MagicColor.toShortString(c), xManaCostPaidByColor)) {
continue;
}
if (ai.getManaPool().canPayForShardWithColor(toPay, c) && reflected.contains(MagicColor.toLongString(c))) {
m.setExpressChoice(MagicColor.toShortString(c));
return true;
@@ -1148,6 +1161,16 @@ public class ComputerUtilMana {
}
return false;
}
if (toPay == ManaCostShard.COLORED_X) {
for (String s : m.mana().split(" ")) {
if (ManaCostBeingPaid.canColoredXShardBePaidByColor(s, xManaCostPaidByColor)) {
return true;
}
}
return false;
}
return true;
}
@@ -1434,17 +1457,26 @@ public class ComputerUtilMana {
// Tack xMana Payments into mana here if X is a set value
if (cost.getXcounter() > 0 || extraMana > 0) {
int manaToAdd = 0;
int xCounter = cost.getXcounter();
if (test && extraMana > 0) {
final int multiplicator = Math.max(cost.getXcounter(), 1);
final int multiplicator = Math.max(xCounter, 1);
manaToAdd = extraMana * multiplicator;
} else {
manaToAdd = AbilityUtils.calculateAmount(card, "X", sa) * cost.getXcounter();
manaToAdd = AbilityUtils.calculateAmount(card, "X", sa) * xCounter;
}
cost.increaseShard(ManaCostShard.parseNonGeneric(sa.getParamOrDefault("XColor", "1")), manaToAdd);
String xColor = sa.getParamOrDefault("XColor", "1");
if (card.hasKeyword("Spend only colored mana on X. No more than one mana of each color may be spent this way.")) {
xColor = "WUBRGX";
}
if (xCounter > 0) {
cost.setXManaCostPaid(manaToAdd / xCounter, xColor);
} else {
cost.increaseShard(ManaCostShard.parseNonGeneric(xColor), manaToAdd);
}
if (!test) {
sa.setXManaCostPaid(manaToAdd / cost.getXcounter());
sa.setXManaCostPaid(manaToAdd / xCounter);
}
}

View File

@@ -64,7 +64,10 @@ public enum ManaCostShard {
PR(ManaAtom.RED | ManaAtom.OR_2_LIFE, "P/R", "PR"),
PG(ManaAtom.GREEN | ManaAtom.OR_2_LIFE, "P/G", "PG"),
X(ManaAtom.IS_X, "X");
X(ManaAtom.IS_X, "X"),
// Colored only X, each color can be used to pay for this only once (for Emblazoned Golem)
COLORED_X(ManaAtom.WHITE | ManaAtom.BLUE | ManaAtom.BLACK | ManaAtom.RED | ManaAtom.GREEN | ManaAtom.IS_X, "1");
private final int shard;
@@ -297,7 +300,7 @@ public enum ManaCostShard {
}
public boolean isColor(byte colorCode) {
return (colorCode & this.shard) > 0;
return (colorCode & this.shard) > 0;
}
public boolean canBePaidWithManaOfColor(byte colorCode) {

View File

@@ -240,7 +240,7 @@ public class ManaCostBeingPaid {
public final boolean isNeeded(final Mana paid, final ManaPool pool) {
for (ManaCostShard shard : unpaidShards.keySet()) {
if (canBePaidWith(shard, paid, pool)) {
if (canBePaidWith(shard, paid, pool, xManaCostPaidByColor)) {
return true;
}
}
@@ -260,7 +260,7 @@ public class ManaCostBeingPaid {
shard = ManaCostShard.GENERIC;
}
else {
shard = ManaCostShard.valueOf(ManaAtom.fromName(xColor));
shard = ManaCostShard.parseNonGeneric(xColor);
}
increaseShard(shard, xCost, true);
}
@@ -441,6 +441,10 @@ public class ManaCostBeingPaid {
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
@Override
public boolean apply(ManaCostShard ms) {
// Check Colored X and see if the color is already used
if (ms == ManaCostShard.COLORED_X && !canColoredXShardBePaidByColor(MagicColor.toShortString(colorMask), xManaCostPaidByColor)) {
return false;
}
return pool.canPayForShardWithColor(ms, colorMask);
}
};
@@ -465,7 +469,7 @@ public class ManaCostBeingPaid {
Predicate<ManaCostShard> predCanBePaid = new Predicate<ManaCostShard>() {
@Override
public boolean apply(ManaCostShard ms) {
return canBePaidWith(ms, mana, pool);
return canBePaidWith(ms, mana, pool, xManaCostPaidByColor);
}
};
@@ -552,7 +556,14 @@ public class ManaCostBeingPaid {
return 5;
}
private static boolean canBePaidWith(final ManaCostShard shard, final Mana mana, final ManaPool pool) {
public static boolean canColoredXShardBePaidByColor(String color, Map<String, Integer> xManaCostPaidByColor) {
if (xManaCostPaidByColor != null && xManaCostPaidByColor.get(color) != null) {
return false;
}
return true;
}
private static boolean canBePaidWith(final ManaCostShard shard, final Mana mana, final ManaPool pool, Map<String, Integer> xManaCostPaidByColor) {
if (shard.isSnow() && !mana.isSnow()) {
return false;
}
@@ -565,6 +576,11 @@ public class ManaCostBeingPaid {
return true;
}
// Check Colored X and see if the color is already used
if (shard == ManaCostShard.COLORED_X && !canColoredXShardBePaidByColor(MagicColor.toShortString(mana.getColor()), xManaCostPaidByColor)) {
return false;
}
byte color = mana.getColor();
return pool.canPayForShardWithColor(shard, color);
}

View File

@@ -0,0 +1,11 @@
Name:Emblazoned Golem
ManaCost:2
Types:Artifact Creature Golem
PT:1/2
K:Kicker:X
K:Spend only colored mana on X. No more than one mana of each color may be spent this way.
K:etbCounter:P1P1:X:CheckSVar$ WasKicked:If CARDNAME was kicked, it enters the battlefield with X +1/+1 counters on it.
SVar:X:Count$xPaid
SVar:WasKicked:Count$Kicked.1.0
DeckHas:Ability$Counters
Oracle:Kicker {X} (You may pay an additional {X} as you cast this spell.)\nSpend only colored mana on X. No more than one mana of each color may be spent this way.\nIf Emblazoned Golem was kicked, it enters the battlefield with X +1/+1 counters on it.

View File

@@ -708,13 +708,17 @@ public class HumanPlay {
ManaCostBeingPaid toPay = new ManaCostBeingPaid(realCost, mc.getRestiction());
String xInCard = source.getSVar("X");
String xColor = ability.getParam("XColor");
if (source.hasKeyword("Spend only colored mana on X. No more than one mana of each color may be spent this way.")) {
xColor = "WUBRGX";
}
if (mc.getAmountOfX() > 0 && !"Count$xPaid".equals(xInCard)) { // announce X will overwrite whatever was in card script
int xPaid = AbilityUtils.calculateAmount(source, "X", ability);
toPay.setXManaCostPaid(xPaid, ability.getParam("XColor"));
toPay.setXManaCostPaid(xPaid, xColor);
ability.setXManaCostPaid(xPaid);
}
else if (ability.getXManaCostPaid() != null) { //ensure pre-announced X value retained
toPay.setXManaCostPaid(ability.getXManaCostPaid(), ability.getParam("XColor"));
toPay.setXManaCostPaid(ability.getXManaCostPaid(), xColor);
}
int timesMultikicked = source.getKickerMagnitude();

View File

@@ -396,6 +396,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
canChooseZero = false;
}
}
if (ability.getHostCard().hasKeyword("Spend only colored mana on X. No more than one mana of each color may be spent this way.")) {
max = 5;
}
}
final int min = canChooseZero ? 0 : 1;