mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Don't transform X shards of UnlessCost before paying (#5041)
* Refactor fake X shard on UnlessCost
This commit is contained in:
@@ -1415,77 +1415,12 @@ public class AbilityUtils {
|
||||
final boolean execSubsWhenNotPaid = "WhenNotPaid".equals(resolveSubs) || StringUtils.isBlank(resolveSubs);
|
||||
final boolean isSwitched = sa.hasParam("UnlessSwitched");
|
||||
|
||||
// The cost
|
||||
Cost cost;
|
||||
String unlessCost = sa.getParam("UnlessCost").trim();
|
||||
if (unlessCost.equals("CardManaCost")) {
|
||||
cost = new Cost(source.getManaCost(), true);
|
||||
}
|
||||
else if (unlessCost.equals("ChosenManaCost")) {
|
||||
if (!source.hasChosenCard()) {
|
||||
cost = new Cost(ManaCost.ZERO, true);
|
||||
} else {
|
||||
cost = new Cost(Iterables.getFirst(source.getChosenCards(), null).getManaCost(), true);
|
||||
}
|
||||
}
|
||||
else if (unlessCost.equals("ChosenNumber")) {
|
||||
cost = new Cost(new ManaCost(new ManaCostParser(String.valueOf(source.getChosenNumber()))), true);
|
||||
}
|
||||
else if (unlessCost.startsWith("DefinedCost")) {
|
||||
CardCollection definedCards = getDefinedCards(source, unlessCost.split("_")[1], sa);
|
||||
if (definedCards.isEmpty()) {
|
||||
sa.resolve();
|
||||
resolveSubAbilities(sa, game);
|
||||
return;
|
||||
}
|
||||
Card card = definedCards.getFirst();
|
||||
ManaCostBeingPaid newCost = new ManaCostBeingPaid(card.getManaCost());
|
||||
// Check if there's a third underscore for cost modifying
|
||||
if (unlessCost.split("_").length == 3) {
|
||||
String modifier = unlessCost.split("_")[2];
|
||||
if (modifier.startsWith("Minus")) {
|
||||
int max = Integer.parseInt(modifier.substring(5));
|
||||
if (sa.hasParam("UnlessUpTo")) { // Flash
|
||||
max = allPayers.get(0).getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblChooseNumber"), 0, max);
|
||||
}
|
||||
newCost.decreaseGenericMana(max);
|
||||
} else {
|
||||
newCost.increaseGenericMana(Integer.parseInt(modifier.substring(4)));
|
||||
}
|
||||
}
|
||||
cost = new Cost(newCost.toManaCost(), true);
|
||||
}
|
||||
else if (unlessCost.startsWith("DefinedSACost")) {
|
||||
FCollection<SpellAbility> definedSAs = getDefinedSpellAbilities(source, unlessCost.split("_")[1], sa);
|
||||
if (definedSAs.isEmpty()) {
|
||||
sa.resolve();
|
||||
resolveSubAbilities(sa, game);
|
||||
return;
|
||||
}
|
||||
Card host = definedSAs.getFirst().getHostCard();
|
||||
if (host.getManaCost() == null) {
|
||||
cost = new Cost(ManaCost.ZERO, true);
|
||||
} else {
|
||||
int xCount = host.getManaCost().countX();
|
||||
int xPaid = host.getXManaCostPaid() * xCount;
|
||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(host.getManaCost());
|
||||
toPay.decreaseShard(ManaCostShard.X, xCount);
|
||||
toPay.increaseGenericMana(xPaid);
|
||||
cost = new Cost(toPay.toManaCost(), true);
|
||||
}
|
||||
}
|
||||
else if (!StringUtils.isBlank(sa.getSVar(unlessCost)) || !StringUtils.isBlank(source.getSVar(unlessCost))) {
|
||||
// check for X costs (stored in SVars
|
||||
int xCost = calculateAmount(source, TextUtil.fastReplace(sa.getParam("UnlessCost"),
|
||||
" ", ""), sa);
|
||||
//Check for XColor
|
||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(ManaCost.ZERO);
|
||||
byte xColor = ManaAtom.fromName(sa.getParamOrDefault("UnlessXColor", "1"));
|
||||
toPay.increaseShard(ManaCostShard.valueOf(xColor), xCost);
|
||||
cost = new Cost(toPay.toManaCost(), true);
|
||||
}
|
||||
else {
|
||||
cost = new Cost(unlessCost, true);
|
||||
Cost cost = calculateUnlessCost(sa, unlessCost, true);
|
||||
if (cost == null) {
|
||||
sa.resolve();
|
||||
resolveSubAbilities(sa, game);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean alreadyPaid = false;
|
||||
@@ -1510,6 +1445,67 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Cost calculateUnlessCost(SpellAbility sa, String unlessCost, boolean beforePayment) {
|
||||
final Card source = sa.getHostCard();
|
||||
Cost cost;
|
||||
if (unlessCost.equals("ChosenNumber")) {
|
||||
cost = new Cost(new ManaCost(new ManaCostParser(String.valueOf(source.getChosenNumber()))), true);
|
||||
}
|
||||
else if (unlessCost.startsWith("DefinedCost")) {
|
||||
CardCollection definedCards = getDefinedCards(source, unlessCost.split("_")[1], sa);
|
||||
if (definedCards.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Card card = definedCards.getFirst();
|
||||
ManaCostBeingPaid newCost = new ManaCostBeingPaid(card.getManaCost());
|
||||
// Check if there's a third underscore for cost modifying
|
||||
if (unlessCost.split("_").length == 3) {
|
||||
String modifier = unlessCost.split("_")[2];
|
||||
if (modifier.startsWith("Minus")) {
|
||||
int max = Integer.parseInt(modifier.substring(5));
|
||||
if (sa.hasParam("UnlessUpTo") && beforePayment) { // Flash
|
||||
max = sa.getActivatingPlayer().getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblChooseNumber"), 0, max);
|
||||
}
|
||||
newCost.decreaseGenericMana(max);
|
||||
} else {
|
||||
newCost.increaseGenericMana(Integer.parseInt(modifier.substring(4)));
|
||||
}
|
||||
}
|
||||
cost = new Cost(newCost.toManaCost(), true);
|
||||
}
|
||||
else if (unlessCost.startsWith("DefinedSACost")) {
|
||||
FCollection<SpellAbility> definedSAs = getDefinedSpellAbilities(source, unlessCost.split("_")[1], sa);
|
||||
if (definedSAs.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Card host = definedSAs.getFirst().getHostCard();
|
||||
if (host.getManaCost() == null) {
|
||||
cost = new Cost(ManaCost.ZERO, true);
|
||||
} else {
|
||||
int xCount = host.getManaCost().countX();
|
||||
int xPaid = host.getXManaCostPaid() * xCount;
|
||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(host.getManaCost());
|
||||
toPay.decreaseShard(ManaCostShard.X, xCount);
|
||||
toPay.increaseGenericMana(xPaid);
|
||||
cost = new Cost(toPay.toManaCost(), true);
|
||||
}
|
||||
}
|
||||
else if (!StringUtils.isBlank(sa.getSVar(unlessCost)) && !unlessCost.equals("X")) {
|
||||
// check for non-X costs (stored in SVars
|
||||
int xCost = calculateAmount(source, TextUtil.fastReplace(sa.getParam("UnlessCost"),
|
||||
" ", ""), sa);
|
||||
//Check for XColor
|
||||
ManaCostBeingPaid toPay = new ManaCostBeingPaid(ManaCost.ZERO);
|
||||
byte xColor = ManaAtom.fromName(sa.getParamOrDefault("UnlessColor", "1"));
|
||||
toPay.increaseShard(ManaCostShard.valueOf(xColor), xCost);
|
||||
cost = new Cost(toPay.toManaCost(), true);
|
||||
}
|
||||
else {
|
||||
cost = new Cost(unlessCost, true);
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* handleRemembering.
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ManaRefundService {
|
||||
payingAbilities.clear();
|
||||
|
||||
// update battlefield of all activating players - to redraw cards used to pay mana as untapped
|
||||
for(Player p : payers) {
|
||||
for (Player p : payers) {
|
||||
p.getGame().fireEvent(new GameEventZone(ZoneType.Battlefield, p, EventValueChangeType.ComplexUpdate, null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ import forge.game.Game;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.IHasSVars;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.mana.Mana;
|
||||
import forge.game.mana.ManaPool;
|
||||
import forge.game.player.Player;
|
||||
@@ -389,10 +391,19 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
}
|
||||
|
||||
if (restriction.startsWith("CostContains")) {
|
||||
if (restriction.endsWith("X") && sa.costHasManaX()) {
|
||||
Game game = sa.getHostCard().getGame();
|
||||
Cost payment = sa.getPayCosts();
|
||||
if (game.getStack().isResolving() && sa.hasParam("UnlessCost")) {
|
||||
payment = AbilityUtils.calculateUnlessCost(sa, sa.getParam("UnlessCost"), false);
|
||||
}
|
||||
if (payment.hasNoManaCost()) {
|
||||
continue;
|
||||
}
|
||||
// TODO Thassa's Intervention with "twice {X}" is tricky
|
||||
if (restriction.endsWith("X") && payment.getCostMana().getAmountOfX() > 0) {
|
||||
return true;
|
||||
}
|
||||
if (restriction.endsWith("C") && sa.getPayCosts().hasManaCost() && sa.getPayCosts().getCostMana().getMana().getShardCount(ManaCostShard.COLORLESS) > 0) {
|
||||
if (restriction.endsWith("C") && payment.getCostMana().getMana().getShardCount(ManaCostShard.COLORLESS) > 0) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -191,6 +191,13 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
bResolving = b;
|
||||
}
|
||||
|
||||
public final boolean isResolving(Card c) {
|
||||
if (!isResolving() || curResolvingCard == null) {
|
||||
return false;
|
||||
}
|
||||
return c.equals(curResolvingCard);
|
||||
}
|
||||
|
||||
public final boolean canUndo(Player player) {
|
||||
return undoStackOwner == player;
|
||||
}
|
||||
@@ -937,13 +944,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isResolving(Card c) {
|
||||
if (!isResolving() || curResolvingCard == null) {
|
||||
return false;
|
||||
}
|
||||
return c.equals(curResolvingCard);
|
||||
}
|
||||
|
||||
public final boolean hasSourceOnStack(final Card source, final Predicate<SpellAbility> pred) {
|
||||
if (source == null) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user