mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 10:18:01 +00:00
Support mandatory mana payments
This commit is contained in:
@@ -264,7 +264,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
|||||||
return res.isEmpty() ? null : PaymentDecision.card(res);
|
return res.isEmpty() ? null : PaymentDecision.card(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaymentDecision visit(CostGainLife cost) {
|
public PaymentDecision visit(CostGainLife cost) {
|
||||||
final List<Player> oppsThatCanGainLife = Lists.newArrayList();
|
final List<Player> oppsThatCanGainLife = Lists.newArrayList();
|
||||||
@@ -282,7 +281,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
|||||||
return PaymentDecision.players(oppsThatCanGainLife);
|
return PaymentDecision.players(oppsThatCanGainLife);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaymentDecision visit(CostMill cost) {
|
public PaymentDecision visit(CostMill cost) {
|
||||||
int c = cost.getAbilityAmount(ability);
|
int c = cost.getAbilityAmount(ability);
|
||||||
@@ -681,7 +679,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
|||||||
toRemove += removeCounter(table, prefs, CounterEnumType.LORE, c - toRemove);
|
toRemove += removeCounter(table, prefs, CounterEnumType.LORE, c - toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO add logic to remove positive counters?
|
// TODO add logic to remove positive counters?
|
||||||
if (c > toRemove && cost.counter != null) {
|
if (c > toRemove && cost.counter != null) {
|
||||||
// TODO add logic for Ooze Flux, should probably try to make a token as big as possible
|
// TODO add logic for Ooze Flux, should probably try to make a token as big as possible
|
||||||
|
|||||||
@@ -977,7 +977,7 @@ public class ComputerUtilMana {
|
|||||||
* @param manaSpentToPay list of mana spent
|
* @param manaSpentToPay list of mana spent
|
||||||
* @return whether the floating mana is sufficient to pay the cost fully
|
* @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 test, List<Mana> manaSpentToPay) {
|
||||||
final boolean hasConverge = sa.getHostCard().hasConverge();
|
final boolean hasConverge = sa.getHostCard().hasConverge();
|
||||||
List<ManaCostShard> unpaidShards = cost.getUnpaidShards();
|
List<ManaCostShard> unpaidShards = cost.getUnpaidShards();
|
||||||
|
|||||||
@@ -325,6 +325,10 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
tgtSA = tgtSA.copyWithDefinedCost(abCost);
|
tgtSA = tgtSA.copyWithDefinedCost(abCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!optional) {
|
||||||
|
tgtSA.getPayCosts().setMandatory(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (sa.hasParam("PlayReduceCost")) {
|
if (sa.hasParam("PlayReduceCost")) {
|
||||||
// for Kefnet only can reduce colorless cost
|
// for Kefnet only can reduce colorless cost
|
||||||
String reduce = sa.getParam("PlayReduceCost");
|
String reduce = sa.getParam("PlayReduceCost");
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ public class Cost implements Serializable {
|
|||||||
public final boolean isMandatory() {
|
public final boolean isMandatory() {
|
||||||
return this.isMandatory;
|
return this.isMandatory;
|
||||||
}
|
}
|
||||||
|
public final void setMandatory(boolean b) {
|
||||||
|
isMandatory = b;
|
||||||
|
}
|
||||||
|
|
||||||
public final boolean isAbility() {
|
public final boolean isAbility() {
|
||||||
return this.isAbility;
|
return this.isAbility;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
protected ManaCostBeingPaid manaCost;
|
protected ManaCostBeingPaid manaCost;
|
||||||
protected final SpellAbility saPaidFor;
|
protected final SpellAbility saPaidFor;
|
||||||
protected boolean effect;
|
protected boolean effect;
|
||||||
|
protected boolean mandatory = false;
|
||||||
private final boolean wasFloatingMana;
|
private final boolean wasFloatingMana;
|
||||||
private final Queue<Card> delaySelectCards = new LinkedList<>();
|
private final Queue<Card> delaySelectCards = new LinkedList<>();
|
||||||
|
|
||||||
@@ -406,9 +407,9 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
|
|
||||||
protected void updateButtons() {
|
protected void updateButtons() {
|
||||||
if (supportAutoPay()) {
|
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 {
|
} 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();
|
canPayManaCost = proc.getResult();
|
||||||
}
|
}
|
||||||
if (canPayManaCost) { //enabled Auto button if mana cost can be paid
|
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());
|
showMessage(getMessage(), saPaidFor.getView());
|
||||||
@@ -447,8 +448,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
|
|||||||
if (isAlreadyPaid()) {
|
if (isAlreadyPaid()) {
|
||||||
done();
|
done();
|
||||||
stop();
|
stop();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ import forge.util.Localizer;
|
|||||||
|
|
||||||
public class InputPayManaOfCostPayment extends InputPayMana {
|
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);
|
super(controller, spellAbility, payer, effect);
|
||||||
manaCost = cost;
|
manaCost = cost;
|
||||||
extraMatrix = matrix;
|
extraMatrix = matrix;
|
||||||
|
this.mandatory = mandatory;
|
||||||
applyMatrix();
|
applyMatrix();
|
||||||
|
|
||||||
// Set Mana cost being paid for SA to be able to reference it later
|
// Set Mana cost being paid for SA to be able to reference it later
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
|
import forge.ai.ComputerUtilMana;
|
||||||
import forge.game.cost.*;
|
import forge.game.cost.*;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -30,6 +31,7 @@ import forge.game.card.CardView;
|
|||||||
import forge.game.card.CardZoneTable;
|
import forge.game.card.CardZoneTable;
|
||||||
import forge.game.card.CounterEnumType;
|
import forge.game.card.CounterEnumType;
|
||||||
import forge.game.card.CounterType;
|
import forge.game.card.CounterType;
|
||||||
|
import forge.game.mana.Mana;
|
||||||
import forge.game.mana.ManaConversionMatrix;
|
import forge.game.mana.ManaConversionMatrix;
|
||||||
import forge.game.mana.ManaCostBeingPaid;
|
import forge.game.mana.ManaCostBeingPaid;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -677,7 +679,15 @@ public class HumanPlay {
|
|||||||
}
|
}
|
||||||
if (!toPay.isPaid()) {
|
if (!toPay.isPaid()) {
|
||||||
// Input is somehow clearing out the offering card?
|
// 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.setMessagePrefix(prompt);
|
||||||
inpPayment.showAndWait();
|
inpPayment.showAndWait();
|
||||||
if (!inpPayment.isPaid()) {
|
if (!inpPayment.isPaid()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user