mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'paycheat' into 'master'
Fix casting SA while refusing to pay CostSacrifice See merge request core-developers/forge!4881
This commit is contained in:
@@ -2227,11 +2227,11 @@ public class AiController {
|
|||||||
|
|
||||||
private boolean checkAiSpecificRestrictions(final SpellAbility sa) {
|
private boolean checkAiSpecificRestrictions(final SpellAbility sa) {
|
||||||
// AI-specific restrictions specified as activation parameters in spell abilities
|
// AI-specific restrictions specified as activation parameters in spell abilities
|
||||||
|
|
||||||
if (sa.hasParam("AILifeThreshold")) {
|
if (sa.hasParam("AILifeThreshold")) {
|
||||||
return player.getLife() > Integer.parseInt(sa.getParam("AILifeThreshold"));
|
return player.getLife() > Integer.parseInt(sa.getParam("AILifeThreshold"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -354,7 +354,6 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
|||||||
return PaymentDecision.number(c);
|
return PaymentDecision.number(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaymentDecision visit(CostPutCardToLib cost) {
|
public PaymentDecision visit(CostPutCardToLib cost) {
|
||||||
if (cost.payCostFromSource()) {
|
if (cost.payCostFromSource()) {
|
||||||
|
|||||||
@@ -331,11 +331,14 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Card getCardPreference(final Player ai, final Card activate, final String pref, final CardCollection typeList) {
|
public static Card getCardPreference(final Player ai, final Card activate, final String pref, final CardCollection typeList) {
|
||||||
|
return getCardPreference(ai, activate, pref, typeList, null);
|
||||||
|
}
|
||||||
|
public static Card getCardPreference(final Player ai, final Card activate, final String pref, final CardCollection typeList, SpellAbility sa) {
|
||||||
final Game game = ai.getGame();
|
final Game game = ai.getGame();
|
||||||
String prefDef = "";
|
String prefDef = "";
|
||||||
if (activate != null) {
|
if (activate != null) {
|
||||||
prefDef = activate.getSVar("AIPreference");
|
prefDef = activate.getSVar("AIPreference");
|
||||||
final String[] prefGroups = activate.getSVar("AIPreference").split("\\|");
|
final String[] prefGroups = prefDef.split("\\|");
|
||||||
for (String prefGroup : prefGroups) {
|
for (String prefGroup : prefGroups) {
|
||||||
final String[] prefValid = prefGroup.trim().split("\\$");
|
final String[] prefValid = prefGroup.trim().split("\\$");
|
||||||
if (prefValid[0].equals(pref) && !prefValid[1].startsWith("Special:")) {
|
if (prefValid[0].equals(pref) && !prefValid[1].startsWith("Special:")) {
|
||||||
@@ -346,8 +349,8 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
for (String validItem : prefValid[1].split(",")) {
|
for (String validItem : prefValid[1].split(",")) {
|
||||||
final CardCollection prefList = CardLists.getValidCards(typeList, validItem, activate.getController(), activate, null);
|
final CardCollection prefList = CardLists.getValidCards(typeList, validItem, activate.getController(), activate, null);
|
||||||
int threshold = getAIPreferenceParameter(activate, "CreatureEvalThreshold");
|
int threshold = getAIPreferenceParameter(activate, "CreatureEvalThreshold", sa);
|
||||||
int minNeeded = getAIPreferenceParameter(activate, "MinCreaturesBelowThreshold");
|
int minNeeded = getAIPreferenceParameter(activate, "MinCreaturesBelowThreshold", sa);
|
||||||
|
|
||||||
if (threshold != -1) {
|
if (threshold != -1) {
|
||||||
List<Card> toRemove = Lists.newArrayList();
|
List<Card> toRemove = Lists.newArrayList();
|
||||||
@@ -390,7 +393,7 @@ public class ComputerUtil {
|
|||||||
final CardCollection sacMeList = CardLists.filter(typeList, new Predicate<Card>() {
|
final CardCollection sacMeList = CardLists.filter(typeList, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
return (c.hasSVar("SacMe") && (Integer.parseInt(c.getSVar("SacMe")) == priority));
|
return c.hasSVar("SacMe") && (Integer.parseInt(c.getSVar("SacMe")) == priority);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!sacMeList.isEmpty()) {
|
if (!sacMeList.isEmpty()) {
|
||||||
@@ -419,6 +422,7 @@ public class ComputerUtil {
|
|||||||
if (!nonCreatures.isEmpty()) {
|
if (!nonCreatures.isEmpty()) {
|
||||||
return ComputerUtilCard.getWorstAI(nonCreatures);
|
return ComputerUtilCard.getWorstAI(nonCreatures);
|
||||||
} else if (!typeList.isEmpty()) {
|
} else if (!typeList.isEmpty()) {
|
||||||
|
// TODO make sure survival is possible in case the creature blocks a trampler
|
||||||
return ComputerUtilCard.getWorstAI(typeList);
|
return ComputerUtilCard.getWorstAI(typeList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,7 +509,7 @@ public class ComputerUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAIPreferenceParameter(final Card c, final String paramName) {
|
public static int getAIPreferenceParameter(final Card c, final String paramName, SpellAbility sa) {
|
||||||
if (!c.hasSVar("AIPreferenceParams")) {
|
if (!c.hasSVar("AIPreferenceParams")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -520,7 +524,21 @@ public class ComputerUtil {
|
|||||||
case "CreatureEvalThreshold":
|
case "CreatureEvalThreshold":
|
||||||
// Threshold of 150 is just below the level of a 1/1 mana dork or a 2/2 baseline creature with no keywords
|
// Threshold of 150 is just below the level of a 1/1 mana dork or a 2/2 baseline creature with no keywords
|
||||||
if (paramName.equals(parName)) {
|
if (paramName.equals(parName)) {
|
||||||
return Integer.parseInt(parValue);
|
int num = 0;
|
||||||
|
try {
|
||||||
|
num = Integer.parseInt(parValue);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
String[] valParts = StringUtils.split(parValue, "/");
|
||||||
|
CardCollection foundCards = AbilityUtils.getDefinedCards(c, valParts[0], sa);
|
||||||
|
if (!foundCards.isEmpty()) {
|
||||||
|
num = ComputerUtilCard.evaluateCreature(foundCards.get(0));
|
||||||
|
}
|
||||||
|
valParts[0] = Integer.toString(num);
|
||||||
|
if (valParts.length > 1) {
|
||||||
|
num = AbilityUtils.doXMath(num, valParts[1], c, sa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "MinCreaturesBelowThreshold":
|
case "MinCreaturesBelowThreshold":
|
||||||
@@ -543,9 +561,8 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability));
|
typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability));
|
||||||
|
|
||||||
if ((target != null) && target.getController() == ai) {
|
// don't sacrifice the card we're pumping
|
||||||
typeList.remove(target); // don't sacrifice the card we're pumping
|
typeList = ComputerUtilCost.paymentChoicesWithoutTargets(typeList, ability, ai);
|
||||||
}
|
|
||||||
|
|
||||||
if (typeList.size() < amount) {
|
if (typeList.size() < amount) {
|
||||||
return null;
|
return null;
|
||||||
@@ -573,9 +590,8 @@ public class ComputerUtil {
|
|||||||
final Card target, final int amount, SpellAbility sa) {
|
final Card target, final int amount, SpellAbility sa) {
|
||||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
||||||
|
|
||||||
if ((target != null) && target.getController() == ai) {
|
// don't exile the card we're pumping
|
||||||
typeList.remove(target); // don't exile the card we're pumping
|
typeList = ComputerUtilCost.paymentChoicesWithoutTargets(typeList, sa, ai);
|
||||||
}
|
|
||||||
|
|
||||||
if (typeList.size() < amount) {
|
if (typeList.size() < amount) {
|
||||||
return null;
|
return null;
|
||||||
@@ -594,9 +610,8 @@ public class ComputerUtil {
|
|||||||
final Card target, final int amount, SpellAbility sa) {
|
final Card target, final int amount, SpellAbility sa) {
|
||||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
||||||
|
|
||||||
if ((target != null) && target.getController() == ai) {
|
// don't move the card we're pumping
|
||||||
typeList.remove(target); // don't move the card we're pumping
|
typeList = ComputerUtilCost.paymentChoicesWithoutTargets(typeList, sa, ai);
|
||||||
}
|
|
||||||
|
|
||||||
if (typeList.size() < amount) {
|
if (typeList.size() < amount) {
|
||||||
return null;
|
return null;
|
||||||
@@ -718,12 +733,10 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static CardCollection chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount, SpellAbility sa) {
|
public static CardCollection chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount, SpellAbility sa) {
|
||||||
final CardCollection typeList =
|
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, sa);
|
||||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, sa);
|
|
||||||
if ((target != null) && target.getController() == ai) {
|
// don't bounce the card we're pumping
|
||||||
// don't bounce the card we're pumping
|
typeList = ComputerUtilCost.paymentChoicesWithoutTargets(typeList, sa, ai);
|
||||||
typeList.remove(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeList.size() < amount) {
|
if (typeList.size() < amount) {
|
||||||
return new CardCollection();
|
return new CardCollection();
|
||||||
@@ -743,7 +756,7 @@ public class ComputerUtil {
|
|||||||
CardCollection remaining = new CardCollection(cardlist);
|
CardCollection remaining = new CardCollection(cardlist);
|
||||||
final CardCollection sacrificed = new CardCollection();
|
final CardCollection sacrificed = new CardCollection();
|
||||||
final Card host = source.getHostCard();
|
final Card host = source.getHostCard();
|
||||||
final int considerSacThreshold = getAIPreferenceParameter(host, "CreatureEvalThreshold");
|
final int considerSacThreshold = getAIPreferenceParameter(host, "CreatureEvalThreshold", source);
|
||||||
|
|
||||||
if ("OpponentOnly".equals(source.getParam("AILogic"))) {
|
if ("OpponentOnly".equals(source.getParam("AILogic"))) {
|
||||||
if(!source.getActivatingPlayer().isOpponentOf(ai)) {
|
if(!source.getActivatingPlayer().isOpponentOf(ai)) {
|
||||||
@@ -3026,6 +3039,6 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import org.apache.commons.lang3.ObjectUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ import forge.game.card.CardCollection;
|
|||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardFactoryUtil;
|
import forge.game.card.CardFactoryUtil;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
import forge.game.card.CardUtil;
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.card.CounterEnumType;
|
import forge.game.card.CounterEnumType;
|
||||||
@@ -270,7 +273,10 @@ public class ComputerUtilCost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final CardCollection sacList = new CardCollection();
|
final CardCollection sacList = new CardCollection();
|
||||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
||||||
|
|
||||||
|
// don't sacrifice the card we're pumping
|
||||||
|
typeList = paymentChoicesWithoutTargets(typeList, sourceAbility, ai);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (count < amount) {
|
while (count < amount) {
|
||||||
@@ -320,11 +326,14 @@ public class ComputerUtilCost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final CardCollection sacList = new CardCollection();
|
final CardCollection sacList = new CardCollection();
|
||||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
||||||
|
|
||||||
|
// don't sacrifice the card we're pumping
|
||||||
|
typeList = paymentChoicesWithoutTargets(typeList, sourceAbility, ai);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (count < amount) {
|
while (count < amount) {
|
||||||
Card prefCard = ComputerUtil.getCardPreference(ai, source, "SacCost", typeList);
|
Card prefCard = ComputerUtil.getCardPreference(ai, source, "SacCost", typeList, sourceAbility);
|
||||||
if (prefCard == null) {
|
if (prefCard == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -407,7 +416,7 @@ public class ComputerUtilCost {
|
|||||||
* @return true, if successful
|
* @return true, if successful
|
||||||
*/
|
*/
|
||||||
public static boolean checkSacrificeCost(final Player ai, final Cost cost, final Card source, final SpellAbility sourceAbility) {
|
public static boolean checkSacrificeCost(final Player ai, final Cost cost, final Card source, final SpellAbility sourceAbility) {
|
||||||
return checkSacrificeCost(ai, cost, source, sourceAbility,true);
|
return checkSacrificeCost(ai, cost, source, sourceAbility, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,8 +429,8 @@ public class ComputerUtilCost {
|
|||||||
* @param cost
|
* @param cost
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static boolean shouldPayCost(final Player ai, final Card hostCard, final Cost cost) {
|
public static boolean shouldPayCost(final Player ai, final Card hostCard, final Cost cost) {
|
||||||
|
|
||||||
for (final CostPart part : cost.getCostParts()) {
|
for (final CostPart part : cost.getCostParts()) {
|
||||||
if (part instanceof CostPayLife) {
|
if (part instanceof CostPayLife) {
|
||||||
if (!ai.cantLoseForZeroOrLessLife()) {
|
if (!ai.cantLoseForZeroOrLessLife()) {
|
||||||
@@ -741,4 +750,12 @@ public class ComputerUtilCost {
|
|||||||
}
|
}
|
||||||
return ObjectUtils.defaultIfNull(val, 0);
|
return ObjectUtils.defaultIfNull(val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CardCollection paymentChoicesWithoutTargets(Iterable<Card> choices, SpellAbility source, Player ai) {
|
||||||
|
if (source.usesTargeting()) {
|
||||||
|
final CardCollection targets = new CardCollection(source.getTargets().getTargetCards());
|
||||||
|
choices = Iterables.filter(choices, Predicates.not(Predicates.and(CardPredicates.isController(ai), Predicates.in(targets))));
|
||||||
|
}
|
||||||
|
return new CardCollection(choices);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,9 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected boolean willPayCosts(Player ai, SpellAbility sa, Cost cost, Card source) {
|
protected boolean willPayCosts(Player ai, SpellAbility sa, Cost cost, Card source) {
|
||||||
|
|
||||||
final String type = sa.getParam("CounterType");
|
final String type = sa.getParam("CounterType");
|
||||||
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
||||||
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
if (!super.willPayCosts(ai, sa, cost, source)) {
|
if (!super.willPayCosts(ai, sa, cost, source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -225,8 +223,7 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sa.canTarget(ai)) {
|
if (sa.canTarget(ai)) {
|
||||||
// don't target itself when its forced to add poison
|
// don't target itself when its forced to add poison counters too
|
||||||
// counters too
|
|
||||||
if (!ai.getCounters().isEmpty()) {
|
if (!ai.getCounters().isEmpty()) {
|
||||||
if (!eachExisting || ai.getPoisonCounters() < 5) {
|
if (!eachExisting || ai.getPoisonCounters() < 5) {
|
||||||
sa.getTargets().add(ai);
|
sa.getTargets().add(ai);
|
||||||
@@ -480,7 +477,6 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
list = CardLists.filter(list, new Predicate<Card>() {
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
|
|
||||||
// don't put the counter on the dead creature
|
// don't put the counter on the dead creature
|
||||||
if (sacSelf && c.equals(source)) {
|
if (sacSelf && c.equals(source)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -493,6 +489,8 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
Card sacTarget = ComputerUtil.getCardPreference(ai, source, "SacCost", list);
|
Card sacTarget = ComputerUtil.getCardPreference(ai, source, "SacCost", list);
|
||||||
// this card is planned to be sacrificed during cost payment, so don't target it
|
// this card is planned to be sacrificed during cost payment, so don't target it
|
||||||
// (otherwise the AI can cheat by activating this SA and not paying the sac cost, e.g. Extruder)
|
// (otherwise the AI can cheat by activating this SA and not paying the sac cost, e.g. Extruder)
|
||||||
|
// TODO needs update if amount > 1 gets printed,
|
||||||
|
// maybe also check putting the counter on that exact creature is more important than sacrificing it (though unlikely?)
|
||||||
list.remove(sacTarget);
|
list.remove(sacTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,7 +615,7 @@ public class CountersPutAi extends SpellAbilityAi {
|
|||||||
// Instant +1/+1
|
// Instant +1/+1
|
||||||
if (type.equals("P1P1") && !SpellAbilityAi.isSorcerySpeed(sa)) {
|
if (type.equals("P1P1") && !SpellAbilityAi.isSorcerySpeed(sa)) {
|
||||||
if (!(ph.getNextTurn() == ai && ph.is(PhaseType.END_OF_TURN) && abCost.isReusuableResource())) {
|
if (!(ph.getNextTurn() == ai && ph.is(PhaseType.END_OF_TURN) && abCost.isReusuableResource())) {
|
||||||
return false; // only if next turn and cost is reusable
|
return false; // only if next turn and cost is reusable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -540,8 +540,7 @@ public class PumpAi extends PumpAiBase {
|
|||||||
|
|
||||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), ai, source, sa);
|
list = CardLists.getValidCards(list, tgt.getValidTgts(), ai, source, sa);
|
||||||
if (game.getStack().isEmpty()) {
|
if (game.getStack().isEmpty()) {
|
||||||
// If the cost is tapping, don't activate before declare
|
// If the cost is tapping, don't activate before declare attack/block
|
||||||
// attack/block
|
|
||||||
if (sa.getPayCosts().hasTapCost()) {
|
if (sa.getPayCosts().hasTapCost()) {
|
||||||
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||||
&& game.getPhaseHandler().isPlayerTurn(ai)) {
|
&& game.getPhaseHandler().isPlayerTurn(ai)) {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ public class SacrificeAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canPlayAI(Player ai, SpellAbility sa) {
|
protected boolean canPlayAI(Player ai, SpellAbility sa) {
|
||||||
|
|
||||||
return sacrificeTgtAI(ai, sa);
|
return sacrificeTgtAI(ai, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ public class PaymentDecision {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static PaymentDecision number(int c) {
|
public static PaymentDecision number(int c) {
|
||||||
return new PaymentDecision(c);
|
return new PaymentDecision(c);
|
||||||
}
|
}
|
||||||
@@ -77,7 +76,6 @@ public class PaymentDecision {
|
|||||||
return new PaymentDecision(null, manas, null, null, null);
|
return new PaymentDecision(null, manas, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ S:Mode$ Continuous | Affected$ Creature.ChosenType+YouCtrl | AddPower$ 1 | AddTo
|
|||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:PlayMain1:TRUE
|
SVar:PlayMain1:TRUE
|
||||||
SVar:AIPreference:SacCost$Creature.ChosenType+Other
|
SVar:AIPreference:SacCost$Creature.ChosenType+Other
|
||||||
|
SVar:AIPreferenceParams:CreatureEvalThreshold$ Targeted/Plus.10
|
||||||
A:AB$ Pump | Cost$ 1 Sac<1/Creature.ChosenType/creature of the chosen type> | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | KW$ Indestructible | SpellDescription$ Target creature you control gains indestructible until end of turn.
|
A:AB$ Pump | Cost$ 1 Sac<1/Creature.ChosenType/creature of the chosen type> | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | KW$ Indestructible | SpellDescription$ Target creature you control gains indestructible until end of turn.
|
||||||
Oracle:As Etchings of the Chosen enters the battlefield, choose a creature type.\nCreatures you control of the chosen type get +1/+1.\n{1}, Sacrifice a creature of the chosen type: Target creature you control gains indestructible until end of turn.
|
Oracle:As Etchings of the Chosen enters the battlefield, choose a creature type.\nCreatures you control of the chosen type get +1/+1.\n{1}, Sacrifice a creature of the chosen type: Target creature you control gains indestructible until end of turn.
|
||||||
|
|||||||
Reference in New Issue
Block a user