diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index 69a93d90230..9506c7d5422 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -424,11 +424,6 @@ public class AiCostDecision extends CostDecisionMakerBase { return PaymentDecision.card(source); } if (cost.getAmount().equals("All")) { - /*CardCollectionView typeList = new CardCollection(activator.getCardsIn(ZoneType.Battlefield)); - typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), activator, source); - if (activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - typeList = CardLists.getNotType(typeList, "Creature"); - }*/ // Does the AI want to use Sacrifice All? return null; } @@ -441,7 +436,7 @@ public class AiCostDecision extends CostDecisionMakerBase { c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability); } - CardCollectionView list = ComputerUtil.chooseSacrificeType(player, cost.getType(), source, ability.getTargetCard(), c); + CardCollectionView list = ComputerUtil.chooseSacrificeType(player, cost.getType(), ability, ability.getTargetCard(), c); return PaymentDecision.card(list); } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 998785b3c92..77d14d0f995 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -372,11 +372,11 @@ public class ComputerUtil { return null; } - public static CardCollection chooseSacrificeType(final Player ai, final String type, final Card source, 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(); CardCollection typeList = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), type.split(";"), source.getController(), source, null); - if (ai.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - typeList = CardLists.getNotType(typeList, "Creature"); - } + + typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability)); if ((target != null) && target.getController() == ai && typeList.contains(target)) { typeList.remove(target); // don't sacrifice the card we're pumping diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 17a94c4c463..df07f175213 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3991,6 +3991,10 @@ public class Card extends GameEntity implements Comparable { if (!getExiledWith().equals(host)) { return false; } + } else if (property.equals("CanBeSacrificedBy")) { + if (!canBeSacrificedBy(spellAbility)) { + return false; + } } else if (property.startsWith("AttachedBy")) { if (!isEquippedBy(source) && !isEnchantedBy(source) && !isFortifiedBy(source)) { return false; @@ -6641,8 +6645,21 @@ public class Card extends GameEntity implements Comparable { if (!canBeSacrificed()) { return false; } - return !(source != null && getController().isOpponentOf(source.getActivatingPlayer()) - && getController().hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")); + + if (source == null){ + return false; + } + + if (isCreature() && source.getActivatingPlayer().hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { + return false; + } + + if (getController().isOpponentOf(source.getActivatingPlayer()) + && getController().hasKeyword("Spells and abilities your opponents control can't cause you to sacrifice permanents.")) { + return false; + } + + return true; } public CardRules getRules() { diff --git a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java index 836e18a2dfa..2833e4b4aca 100644 --- a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java +++ b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java @@ -93,9 +93,6 @@ public class CostSacrifice extends CostPartWithList { typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source, ability); final Integer amount = this.convertAmount(); - if (activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - typeList = CardLists.getNotType(typeList, "Creature"); - } typeList = CardLists.filter(typeList, CardPredicates.canBeSacrificedBy(ability)); if (!needsAnnoucement && (amount != null) && (typeList.size() < amount)) { @@ -106,13 +103,8 @@ public class CostSacrifice extends CostPartWithList { // if X is defined, it needs to be calculated and checked, if X is // choice, it can be Paid even if it's 0 } - else { - if (!source.canBeSacrificed()) { - return false; - } - else if (source.isCreature() && activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - return false; - } + else if (!source.canBeSacrificedBy(ability)) { + return false; } return true; diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index e9f49259365..768d7488f19 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -1024,9 +1024,6 @@ public class HumanCostDecision extends CostDecisionMakerBase { CardCollectionView list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.canBeSacrificedBy(ability)); list = CardLists.getValidCards(list, type.split(";"), player, source, ability); - if (player.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - list = CardLists.getNotType(list, "Creature"); - } if (cost.payCostFromSource()) { if (source.getController() == ability.getActivatingPlayer() && source.isInPlay()) {