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