Support mandatory mana payments

This commit is contained in:
tool4EvEr
2021-12-23 16:46:08 +01:00
parent fddd12b103
commit 1e0bcc070a
7 changed files with 26 additions and 11 deletions

View File

@@ -264,7 +264,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
return res.isEmpty() ? null : PaymentDecision.card(res);
}
@Override
public PaymentDecision visit(CostGainLife cost) {
final List<Player> oppsThatCanGainLife = Lists.newArrayList();
@@ -282,7 +281,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
return PaymentDecision.players(oppsThatCanGainLife);
}
@Override
public PaymentDecision visit(CostMill cost) {
int c = cost.getAbilityAmount(ability);
@@ -681,7 +679,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
toRemove += removeCounter(table, prefs, CounterEnumType.LORE, c - toRemove);
}
// TODO add logic to remove positive counters?
if (c > toRemove && cost.counter != null) {
// TODO add logic for Ooze Flux, should probably try to make a token as big as possible

View File

@@ -977,7 +977,7 @@ public class ComputerUtilMana {
* @param manaSpentToPay list of mana spent
* @return whether the floating mana is sufficient to pay the cost fully
*/
private static boolean payManaCostFromPool(final ManaCostBeingPaid cost, final SpellAbility sa, final Player ai,
public static boolean payManaCostFromPool(final ManaCostBeingPaid cost, final SpellAbility sa, final Player ai,
final boolean test, List<Mana> manaSpentToPay) {
final boolean hasConverge = sa.getHostCard().hasConverge();
List<ManaCostShard> unpaidShards = cost.getUnpaidShards();

View File

@@ -325,6 +325,10 @@ public class PlayEffect extends SpellAbilityEffect {
tgtSA = tgtSA.copyWithDefinedCost(abCost);
}
if (!optional) {
tgtSA.getPayCosts().setMandatory(true);
}
if (sa.hasParam("PlayReduceCost")) {
// for Kefnet only can reduce colorless cost
String reduce = sa.getParam("PlayReduceCost");

View File

@@ -186,6 +186,9 @@ public class Cost implements Serializable {
public final boolean isMandatory() {
return this.isMandatory;
}
public final void setMandatory(boolean b) {
isMandatory = b;
}
public final boolean isAbility() {
return this.isAbility;

View File

@@ -44,6 +44,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
protected ManaCostBeingPaid manaCost;
protected final SpellAbility saPaidFor;
protected boolean effect;
protected boolean mandatory = false;
private final boolean wasFloatingMana;
private final Queue<Card> delaySelectCards = new LinkedList<>();
@@ -406,9 +407,9 @@ public abstract class InputPayMana extends InputSyncronizedBase {
protected void updateButtons() {
if (supportAutoPay()) {
getController().getGui().updateButtons(getOwner(), Localizer.getInstance().getMessage("lblAuto"), Localizer.getInstance().getMessage("lblCancel"), false, true, false);
getController().getGui().updateButtons(getOwner(), Localizer.getInstance().getMessage("lblAuto"), Localizer.getInstance().getMessage("lblCancel"), false, !mandatory, false);
} else {
getController().getGui().updateButtons(getOwner(), "", Localizer.getInstance().getMessage("lblCancel"), false, true, false);
getController().getGui().updateButtons(getOwner(), "", Localizer.getInstance().getMessage("lblCancel"), false, !mandatory, false);
}
}
@@ -430,7 +431,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
canPayManaCost = proc.getResult();
}
if (canPayManaCost) { //enabled Auto button if mana cost can be paid
getController().getGui().updateButtons(getOwner(), Localizer.getInstance().getMessage("lblAuto"), Localizer.getInstance().getMessage("lblCancel"), true, true, true);
getController().getGui().updateButtons(getOwner(), Localizer.getInstance().getMessage("lblAuto"), Localizer.getInstance().getMessage("lblCancel"), true, !mandatory, true);
}
}
showMessage(getMessage(), saPaidFor.getView());
@@ -447,8 +448,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
if (isAlreadyPaid()) {
done();
stop();
}
else {
} else {
FThreads.invokeInEdtNowOrLater(new Runnable() {
@Override
public void run() {

View File

@@ -14,10 +14,11 @@ import forge.util.Localizer;
public class InputPayManaOfCostPayment extends InputPayMana {
public InputPayManaOfCostPayment(final PlayerControllerHuman controller, ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer, ManaConversionMatrix matrix, boolean effect) {
public InputPayManaOfCostPayment(final PlayerControllerHuman controller, ManaCostBeingPaid cost, SpellAbility spellAbility, Player payer, ManaConversionMatrix matrix, boolean effect, boolean mandatory) {
super(controller, spellAbility, payer, effect);
manaCost = cost;
extraMatrix = matrix;
this.mandatory = mandatory;
applyMatrix();
// Set Mana cost being paid for SA to be able to reference it later

View File

@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import forge.ImageKeys;
import forge.ai.ComputerUtilMana;
import forge.game.cost.*;
import forge.game.spellability.SpellAbilityStackInstance;
import org.apache.commons.lang3.StringUtils;
@@ -30,6 +31,7 @@ import forge.game.card.CardView;
import forge.game.card.CardZoneTable;
import forge.game.card.CounterEnumType;
import forge.game.card.CounterType;
import forge.game.mana.Mana;
import forge.game.mana.ManaConversionMatrix;
import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player;
@@ -677,7 +679,15 @@ public class HumanPlay {
}
if (!toPay.isPaid()) {
// Input is somehow clearing out the offering card?
inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator, matrix, effect);
// forced cast must use pool mana
// TODO this introduces a small risk to lock up the GUI if the human "wastes" enough mana for abilities like Doubling Cube
boolean mandatory = false;
if (matrix instanceof CostPayment && ((CostPayment) matrix).getCost().isMandatory()) {
mandatory = ComputerUtilMana.payManaCostFromPool(new ManaCostBeingPaid(toPay), ability, activator, true, new ArrayList<Mana>());
}
inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator, matrix, effect, mandatory);
inpPayment.setMessagePrefix(prompt);
inpPayment.showAndWait();
if (!inpPayment.isPaid()) {