mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
- Improved AI targeting opponents cards with "When CARDNAME becomes the target of a spell or ability, sacrifice it.".
This commit is contained in:
@@ -1732,6 +1732,17 @@ public class ComputerUtil {
|
||||
return safeCards;
|
||||
}
|
||||
|
||||
public static Card getKilledByTargeting(final SpellAbility sa, CardCollectionView validCards) {
|
||||
CardCollection killables = new CardCollection(validCards);
|
||||
killables = CardLists.filter(killables, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.getController() != sa.getActivatingPlayer() && c.getSVar("Targeting").equals("Dies");
|
||||
}
|
||||
});
|
||||
return ComputerUtilCard.getBestCreatureAI(killables);
|
||||
}
|
||||
|
||||
public static int damageFromETB(final Player player, final Card permanent) {
|
||||
int damage = 0;
|
||||
final Game game = player.getGame();
|
||||
|
||||
@@ -170,7 +170,8 @@ public class DamageDealAi extends DamageAiBase {
|
||||
final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return (ComputerUtilCombat.getEnoughDamageToKill(c, d, source, false, noPrevention) <= d) && !ComputerUtil.canRegenerate(ai, c)
|
||||
return c.getSVar("Targeting").equals("Dies")
|
||||
|| (ComputerUtilCombat.getEnoughDamageToKill(c, d, source, false, noPrevention) <= d) && !ComputerUtil.canRegenerate(ai, c)
|
||||
&& !(c.getSVar("SacMe").length() > 0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -467,10 +467,10 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
if (c.getNetToughness() <= -defense) {
|
||||
if (c.getSVar("Targeting").equals("Dies") || c.getNetToughness() <= -defense) {
|
||||
return true; // can kill indestructible creatures
|
||||
}
|
||||
return ((ComputerUtilCombat.getDamageToKill(c) <= -defense) && !c.hasKeyword("Indestructible"));
|
||||
return (ComputerUtilCombat.getDamageToKill(c) <= -defense && !c.hasKeyword("Indestructible"));
|
||||
}
|
||||
}); // leaves all creatures that will be destroyed
|
||||
} // -X/-X end
|
||||
|
||||
@@ -47,7 +47,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
tapList.remove(c);
|
||||
}
|
||||
|
||||
if (tapList.size() == 0) {
|
||||
if (tapList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
Card choice = null;
|
||||
|
||||
if (tapList.size() == 0) {
|
||||
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) {
|
||||
if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa) || sa.getTargets().getNumTargeted() == 0) {
|
||||
if (!mandatory) {
|
||||
sa.resetTargets();
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
||||
if (CardLists.getNotType(tapList, "Creature").isEmpty()) {
|
||||
// if only creatures take the best
|
||||
choice = ComputerUtilCard.getBestCreatureAI(tapList);
|
||||
} else {
|
||||
@@ -76,7 +76,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
|
||||
if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa) || sa.getTargets().getNumTargeted() == 0) {
|
||||
if (!mandatory) {
|
||||
sa.resetTargets();
|
||||
}
|
||||
@@ -117,9 +117,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
final Player opp = ai.getOpponent();
|
||||
final Game game = ai.getGame();
|
||||
CardCollection tapList = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponents());
|
||||
tapList = CardLists.filter(tapList, Presets.UNTAPPED);
|
||||
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source);
|
||||
tapList = CardLists.getTargetableCards(tapList, sa);
|
||||
tapList = CardLists.filter(tapList, Presets.UNTAPPED);
|
||||
tapList = CardLists.filter(tapList, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
@@ -162,17 +162,18 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean goodTargets = false;
|
||||
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
|
||||
Card choice = null;
|
||||
|
||||
if (tapList.isEmpty()) {
|
||||
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) || (sa.getTargets().getNumTargeted() == 0)) {
|
||||
if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa) || sa.getTargets().getNumTargeted() == 0) {
|
||||
if (!mandatory) {
|
||||
sa.resetTargets();
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (!ComputerUtil.shouldCastLessThanMax(ai, source)) {
|
||||
if (!goodTargets && !ComputerUtil.shouldCastLessThanMax(ai, source)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -180,8 +181,11 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
PhaseHandler phase = game.getPhaseHandler();
|
||||
if (phase.isPlayerTurn(ai)
|
||||
&& phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||
Card primeTarget = ComputerUtil.getKilledByTargeting(sa, tapList);
|
||||
if (primeTarget != null) {
|
||||
choice = primeTarget;
|
||||
goodTargets = true;
|
||||
} else if (phase.isPlayerTurn(ai) && phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||
// Tap creatures possible blockers before combat during AI's turn.
|
||||
List<Card> attackers;
|
||||
if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
|
||||
@@ -224,7 +228,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa)) || (sa.getTargets().getNumTargeted() == 0)) {
|
||||
if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa) || sa.getTargets().getNumTargeted() == 0) {
|
||||
if (!mandatory) {
|
||||
sa.resetTargets();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user