mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
AbilityUtils: don't crash when CardTrait is null
This commit is contained in:
@@ -214,7 +214,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
CardCollectionView chosen = ComputerUtil.chooseExileFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
CardCollectionView chosen = ComputerUtil.chooseExileFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c, ability);
|
||||
return null == chosen ? null : PaymentDecision.card(chosen);
|
||||
}
|
||||
}
|
||||
@@ -421,7 +421,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
chosen = chosen.subList(0, c);
|
||||
}
|
||||
else {
|
||||
chosen = ComputerUtil.choosePutToLibraryFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
|
||||
chosen = ComputerUtil.choosePutToLibraryFrom(player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c, ability);
|
||||
}
|
||||
return chosen.isEmpty() ? null : PaymentDecision.card(chosen);
|
||||
}
|
||||
@@ -493,7 +493,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
type = TextUtil.fastReplace(type, "+withTotalPowerGE", "");
|
||||
totap = ComputerUtil.chooseTapTypeAccumulatePower(player, type, ability, !cost.canTapSource, Integer.parseInt(totalP), exclude);
|
||||
} else {
|
||||
totap = ComputerUtil.chooseTapType(player, type, source, !cost.canTapSource, c, exclude);
|
||||
totap = ComputerUtil.chooseTapType(player, type, source, !cost.canTapSource, c, exclude, ability);
|
||||
}
|
||||
|
||||
if (totap == null) {
|
||||
@@ -536,7 +536,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
|
||||
}
|
||||
|
||||
CardCollectionView res = ComputerUtil.chooseReturnType(player, cost.getType(), source, ability.getTargetCard(), c);
|
||||
CardCollectionView res = ComputerUtil.chooseReturnType(player, cost.getType(), source, ability.getTargetCard(), c, ability);
|
||||
return res.isEmpty() ? null : PaymentDecision.card(res);
|
||||
}
|
||||
|
||||
@@ -854,7 +854,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
|
||||
c = AbilityUtils.calculateAmount(source, amount, ability);
|
||||
}
|
||||
|
||||
CardCollectionView list = ComputerUtil.chooseUntapType(player, cost.getType(), source, cost.canUntapSource, c);
|
||||
CardCollectionView list = ComputerUtil.chooseUntapType(player, cost.getType(), source, cost.canUntapSource, c, ability);
|
||||
|
||||
if (list == null) {
|
||||
System.out.println("Couldn't find a valid card to untap for: " + source.getName());
|
||||
|
||||
@@ -539,7 +539,7 @@ public class ComputerUtil {
|
||||
|
||||
public static CardCollection chooseSacrificeType(final Player ai, final String type, final SpellAbility ability, final Card target, final int amount) {
|
||||
final Card source = ability.getHostCard();
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, null);
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, ability);
|
||||
|
||||
typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability));
|
||||
|
||||
@@ -570,8 +570,8 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
public static CardCollection chooseExileFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
|
||||
final Card target, final int amount) {
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, null);
|
||||
final Card target, final int amount, SpellAbility sa) {
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
||||
|
||||
if ((target != null) && target.getController() == ai) {
|
||||
typeList.remove(target); // don't exile the card we're pumping
|
||||
@@ -591,8 +591,8 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
public static CardCollection choosePutToLibraryFrom(final Player ai, final ZoneType zone, final String type, final Card activate,
|
||||
final Card target, final int amount) {
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, null);
|
||||
final Card target, final int amount, SpellAbility sa) {
|
||||
CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(zone), type.split(";"), activate.getController(), activate, sa);
|
||||
|
||||
if ((target != null) && target.getController() == ai) {
|
||||
typeList.remove(target); // don't move the card we're pumping
|
||||
@@ -615,14 +615,11 @@ public class ComputerUtil {
|
||||
return list;
|
||||
}
|
||||
|
||||
public static CardCollection chooseTapType(final Player ai, final String type, final Card activate, final boolean tap, final int amount) {
|
||||
return chooseTapType(ai, type, activate, tap, amount, CardCollection.EMPTY);
|
||||
}
|
||||
public static CardCollection chooseTapType(final Player ai, final String type, final Card activate, final boolean tap, final int amount, final CardCollectionView exclude) {
|
||||
public static CardCollection chooseTapType(final Player ai, final String type, final Card activate, final boolean tap, final int amount, final CardCollectionView exclude, SpellAbility sa) {
|
||||
CardCollection all = new CardCollection(ai.getCardsIn(ZoneType.Battlefield));
|
||||
all.removeAll(exclude);
|
||||
CardCollection typeList =
|
||||
CardLists.getValidCards(all, type.split(";"), activate.getController(), activate, null);
|
||||
CardLists.getValidCards(all, type.split(";"), activate.getController(), activate, sa);
|
||||
|
||||
// is this needed?
|
||||
typeList = CardLists.filter(typeList, Presets.UNTAPPED);
|
||||
@@ -695,9 +692,9 @@ public class ComputerUtil {
|
||||
return tapList;
|
||||
}
|
||||
|
||||
public static CardCollection chooseUntapType(final Player ai, final String type, final Card activate, final boolean untap, final int amount) {
|
||||
public static CardCollection chooseUntapType(final Player ai, final String type, final Card activate, final boolean untap, final int amount, SpellAbility sa) {
|
||||
CardCollection typeList =
|
||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, null);
|
||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, sa);
|
||||
|
||||
// is this needed?
|
||||
typeList = CardLists.filter(typeList, Presets.TAPPED);
|
||||
@@ -720,9 +717,9 @@ public class ComputerUtil {
|
||||
return untapList;
|
||||
}
|
||||
|
||||
public static CardCollection chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount) {
|
||||
public static CardCollection chooseReturnType(final Player ai, final String type, final Card activate, final Card target, final int amount, SpellAbility sa) {
|
||||
final CardCollection typeList =
|
||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), activate.getController(), activate, null);
|
||||
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
|
||||
typeList.remove(target);
|
||||
@@ -970,7 +967,7 @@ public class ComputerUtil {
|
||||
}
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard(), null).contains(card)) {
|
||||
if (CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), controller, sa.getHostCard(), sa).contains(card)) {
|
||||
prevented += AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa);
|
||||
}
|
||||
|
||||
@@ -1586,9 +1583,8 @@ public class ComputerUtil {
|
||||
if (threatApi == null) {
|
||||
return threatened;
|
||||
}
|
||||
final TargetRestrictions tgt = topStack.getTargetRestrictions();
|
||||
|
||||
if (tgt == null) {
|
||||
if (!topStack.usesTargeting()) {
|
||||
if (topStack.hasParam("Defined")) {
|
||||
objects = AbilityUtils.getDefinedObjects(source, topStack.getParam("Defined"), topStack);
|
||||
} else if (topStack.hasParam("ValidCards")) {
|
||||
@@ -1685,7 +1681,7 @@ public class ComputerUtil {
|
||||
|
||||
if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) {
|
||||
boolean canSave = ComputerUtilCombat.predictDamageTo(c, dmg - toughness, source, false) < ComputerUtilCombat.getDamageToKill(c);
|
||||
if ((tgt == null && !grantIndestructible && !canSave)
|
||||
if ((!topStack.usesTargeting() && !grantIndestructible && !canSave)
|
||||
|| (!grantIndestructible && !grantShroud && !canSave)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1745,7 +1741,7 @@ public class ComputerUtil {
|
||||
final boolean cantSave = c.getNetToughness() + toughness <= dmg
|
||||
|| (!c.hasKeyword(Keyword.INDESTRUCTIBLE) && c.getShieldCount() == 0 && !grantIndestructible
|
||||
&& (dmg >= toughness + ComputerUtilCombat.getDamageToKill(c)));
|
||||
if (cantSave && (tgt == null || !grantShroud)) {
|
||||
if (cantSave && (!topStack.usesTargeting() || !grantShroud)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1758,7 +1754,7 @@ public class ComputerUtil {
|
||||
}
|
||||
|
||||
if (saviourApi == ApiType.Protection) {
|
||||
if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
if (!topStack.usesTargeting() || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1795,13 +1791,13 @@ public class ComputerUtil {
|
||||
if (saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll
|
||||
|| saviorWithSubsApi == ApiType.Pump
|
||||
|| saviorWithSubsApi == ApiType.PumpAll) {
|
||||
if ((tgt == null && !grantIndestructible)
|
||||
if ((!topStack.usesTargeting() && !grantIndestructible)
|
||||
|| (!grantShroud && !grantIndestructible)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (saviourApi == ApiType.Protection) {
|
||||
if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
if (!topStack.usesTargeting() || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1830,11 +1826,11 @@ public class ComputerUtil {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) && (tgt == null || !grantShroud)) {
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll) && (!topStack.usesTargeting() || !grantShroud)) {
|
||||
continue;
|
||||
}
|
||||
if (saviourApi == ApiType.Protection) {
|
||||
if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
if (!topStack.usesTargeting() || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1858,11 +1854,11 @@ public class ComputerUtil {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll && tgt == null) && !grantShroud) {
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll && !topStack.usesTargeting()) && !grantShroud) {
|
||||
continue;
|
||||
}
|
||||
if (saviourApi == ApiType.Protection) {
|
||||
if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
if (!topStack.usesTargeting() || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1879,11 +1875,11 @@ public class ComputerUtil {
|
||||
if (o instanceof Card) {
|
||||
final Card c = (Card) o;
|
||||
// give Shroud to targeted creatures
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll && tgt == null) && !grantShroud) {
|
||||
if ((saviourApi == ApiType.Pump || saviourApi == ApiType.PumpAll && !topStack.usesTargeting()) && !grantShroud) {
|
||||
continue;
|
||||
}
|
||||
if (saviourApi == ApiType.Protection) {
|
||||
if (tgt == null || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
if (!topStack.usesTargeting() || (ProtectAi.toProtectFrom(source, saviour) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1913,7 +1913,7 @@ public class ComputerUtilCard {
|
||||
|
||||
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
|
||||
|
||||
list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card, null);
|
||||
list = CardLists.getValidCards(list, needsToPlay.split(","), card.getController(), card, sa);
|
||||
if (list.isEmpty()) {
|
||||
return AiPlayDecision.MissingNeededCards;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ public class ComputerUtilCost {
|
||||
* the source
|
||||
* @return true, if successful
|
||||
*/
|
||||
public static boolean checkDiscardCost(final Player ai, final Cost cost, final Card source) {
|
||||
public static boolean checkDiscardCost(final Player ai, final Cost cost, final Card source, SpellAbility sa) {
|
||||
if (cost == null) {
|
||||
return true;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ public class ComputerUtilCost {
|
||||
if (type.equals("CARDNAME") && source.getAbilityText().contains("Bloodrush")) {
|
||||
continue;
|
||||
}
|
||||
final CardCollection typeList = CardLists.getValidCards(hand, type.split(","), source.getController(), source, null);
|
||||
final CardCollection typeList = CardLists.getValidCards(hand, type.split(","), source.getController(), source, sa);
|
||||
if (typeList.size() > ai.getMaxHandSize()) {
|
||||
continue;
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public class ComputerUtilCost {
|
||||
}
|
||||
|
||||
final CardCollection sacList = new CardCollection();
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, null);
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
||||
|
||||
int count = 0;
|
||||
while (count < amount) {
|
||||
@@ -320,7 +320,7 @@ public class ComputerUtilCost {
|
||||
}
|
||||
|
||||
final CardCollection sacList = new CardCollection();
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, null);
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, sourceAbility);
|
||||
|
||||
int count = 0;
|
||||
while (count < amount) {
|
||||
@@ -641,7 +641,7 @@ public class ComputerUtilCost {
|
||||
return checkLifeCost(payer, cost, source, 4, sa)
|
||||
&& checkDamageCost(payer, cost, source, 4)
|
||||
&& (isMine || checkSacrificeCost(payer, cost, source, sa))
|
||||
&& (isMine || checkDiscardCost(payer, cost, source))
|
||||
&& (isMine || checkDiscardCost(payer, cost, source, sa))
|
||||
&& (!source.getName().equals("Tyrannize") || payer.getCardsIn(ZoneType.Hand).size() > 2)
|
||||
&& (!source.getName().equals("Perplex") || payer.getCardsIn(ZoneType.Hand).size() < 2)
|
||||
&& (!source.getName().equals("Breaking Point") || payer.getCreaturesInPlay().size() > 1)
|
||||
@@ -722,7 +722,7 @@ public class ComputerUtilCost {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), part.getType().split(";"), source.getController(), source, null);
|
||||
final CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), part.getType().split(";"), source.getController(), source, sa);
|
||||
|
||||
int count = 0;
|
||||
while (count < val) {
|
||||
|
||||
@@ -127,7 +127,7 @@ public abstract class SpellAbilityAi {
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, cost, source, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, cost, source, sa)) {
|
||||
|
||||
@@ -288,7 +288,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||
for (final CostPart part : abCost.getCostParts()) {
|
||||
if (part instanceof CostDiscard) {
|
||||
CostDiscard cd = (CostDiscard) part;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||
boolean aiLogicAllowsDiscard = sa.hasParam("AILogic") && sa.getParam("AILogic").startsWith("DiscardAll");
|
||||
|
||||
if (!aiLogicAllowsDiscard) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.google.common.collect.Lists;
|
||||
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.ComputerUtilCombat;
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameObject;
|
||||
@@ -47,20 +46,7 @@ public class ChooseSourceAi extends SpellAbilityAi {
|
||||
final Card source = sa.getHostCard();
|
||||
|
||||
if (abCost != null) {
|
||||
// AI currently disabled for these costs
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, abCost, source, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, abCost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkRemoveCounterCost(abCost, source, sa)) {
|
||||
if (!willPayCosts(ai, sa, abCost, source)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class CountersPutAllAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("DiscardLands".equals(sa.getParam("AILogic")) && !ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
if ("DiscardLands".equals(sa.getParam("AILogic")) && !ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.List;
|
||||
import forge.ai.ComputerUtil;
|
||||
import forge.ai.ComputerUtilCard;
|
||||
import forge.ai.ComputerUtilCombat;
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameObject;
|
||||
@@ -37,20 +36,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
||||
|
||||
final Cost cost = sa.getPayCosts();
|
||||
|
||||
// temporarily disabled until better AI
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, cost, hostCard, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, cost, hostCard, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkRemoveCounterCost(cost, hostCard, sa)) {
|
||||
if (!willPayCosts(ai, sa, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.cost.Cost;
|
||||
@@ -22,19 +20,7 @@ public class DamagePreventAllAi extends SpellAbilityAi {
|
||||
final Cost cost = sa.getPayCosts();
|
||||
|
||||
// temporarily disabled until better AI
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, cost, hostCard, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, cost, hostCard, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkRemoveCounterCost(cost, hostCard, sa)) {
|
||||
if (!willPayCosts(ai, sa, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,26 +32,11 @@ public class DiscardAi extends SpellAbilityAi {
|
||||
final Cost abCost = sa.getPayCosts();
|
||||
final String aiLogic = sa.getParamOrDefault("AILogic", "");
|
||||
|
||||
if (abCost != null) {
|
||||
// AI currently disabled for these costs
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, abCost, source, sa)) {
|
||||
// temporarily disabled until better AI
|
||||
if (!willPayCosts(ai, sa, abCost, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, abCost, source, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkRemoveCounterCost(abCost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ("Chandra, Flamecaller".equals(sourceName)) {
|
||||
final int hand = ai.getCardsIn(ZoneType.Hand).size();
|
||||
return MyRandom.getRandom().nextFloat() < (1.0 / (1 + hand));
|
||||
|
||||
@@ -100,7 +100,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source,sa)) {
|
||||
AiCostDecision aiDecisions = new AiCostDecision(ai, sa);
|
||||
for (final CostPart part : cost.getCostParts()) {
|
||||
if (part instanceof CostDiscard) {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class LifeGainAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source)) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package forge.ai.ability;
|
||||
|
||||
|
||||
import forge.ai.ComputerUtilCost;
|
||||
import forge.ai.SpellAbilityAi;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.cost.Cost;
|
||||
@@ -21,19 +19,7 @@ public class ProtectAllAi extends SpellAbilityAi {
|
||||
final Cost cost = sa.getPayCosts();
|
||||
|
||||
// temporarily disabled until better AI
|
||||
if (!ComputerUtilCost.checkLifeCost(ai, cost, hostCard, 4, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkSacrificeCost(ai, cost, hostCard, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputerUtilCost.checkRemoveCounterCost(cost, hostCard, sa)) {
|
||||
if (!willPayCosts(ai, sa, cost, hostCard)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,11 +48,10 @@ public class TapAi extends TapAiBase {
|
||||
|
||||
final Card source = sa.getHostCard();
|
||||
final Cost abCost = sa.getPayCosts();
|
||||
if (abCost != null) {
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source)) {
|
||||
|
||||
if (!ComputerUtilCost.checkDiscardCost(ai, abCost, source, sa)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sa.usesTargeting()) {
|
||||
boolean bFlag = false;
|
||||
|
||||
@@ -52,7 +52,7 @@ public class UntapAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComputerUtilCost.checkDiscardCost(ai, cost, sa.getHostCard());
|
||||
return ComputerUtilCost.checkDiscardCost(ai, cost, sa.getHostCard(), sa);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1606,7 +1606,7 @@ public class AbilityUtils {
|
||||
final String s2 = AbilityUtils.applyAbilityTextChangeEffects(s, ctb);
|
||||
final String[] l = s2.split("/");
|
||||
final String expr = CardFactoryUtil.extractOperators(s2);
|
||||
final Player player = ctb instanceof SpellAbility ? ((SpellAbility)ctb).getActivatingPlayer() : ctb.getHostCard().getController();
|
||||
final Player player = ctb == null ? null : ctb instanceof SpellAbility ? ((SpellAbility)ctb).getActivatingPlayer() : ctb.getHostCard().getController();
|
||||
|
||||
final String[] sq;
|
||||
sq = l[0].split("\\.");
|
||||
|
||||
Reference in New Issue
Block a user