mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +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;
|
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) {
|
public static int damageFromETB(final Player player, final Card permanent) {
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
final Game game = player.getGame();
|
final Game game = player.getGame();
|
||||||
|
|||||||
@@ -170,8 +170,9 @@ public class DamageDealAi extends DamageAiBase {
|
|||||||
final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
|
final List<Card> killables = CardLists.filter(hPlay, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
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")
|
||||||
&& !(c.getSVar("SacMe").length() > 0);
|
|| (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>() {
|
list = CardLists.filter(list, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
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 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
|
}); // leaves all creatures that will be destroyed
|
||||||
} // -X/-X end
|
} // -X/-X end
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
tapList.remove(c);
|
tapList.remove(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tapList.size() == 0) {
|
if (tapList.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
Card choice = null;
|
Card choice = null;
|
||||||
|
|
||||||
if (tapList.size() == 0) {
|
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) {
|
if (!mandatory) {
|
||||||
sa.resetTargets();
|
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
|
// if only creatures take the best
|
||||||
choice = ComputerUtilCard.getBestCreatureAI(tapList);
|
choice = ComputerUtilCard.getBestCreatureAI(tapList);
|
||||||
} else {
|
} else {
|
||||||
@@ -76,7 +76,7 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (choice == null) { // can't find anything left
|
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) {
|
if (!mandatory) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
}
|
}
|
||||||
@@ -117,9 +117,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
final Player opp = ai.getOpponent();
|
final Player opp = ai.getOpponent();
|
||||||
final Game game = ai.getGame();
|
final Game game = ai.getGame();
|
||||||
CardCollection tapList = CardLists.filterControlledBy(game.getCardsIn(ZoneType.Battlefield), ai.getOpponents());
|
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.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source);
|
||||||
tapList = CardLists.getTargetableCards(tapList, sa);
|
tapList = CardLists.getTargetableCards(tapList, sa);
|
||||||
|
tapList = CardLists.filter(tapList, Presets.UNTAPPED);
|
||||||
tapList = CardLists.filter(tapList, new Predicate<Card>() {
|
tapList = CardLists.filter(tapList, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
@@ -162,17 +162,18 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean goodTargets = false;
|
||||||
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
|
while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
|
||||||
Card choice = null;
|
Card choice = null;
|
||||||
|
|
||||||
if (tapList.isEmpty()) {
|
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) {
|
if (!mandatory) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (!ComputerUtil.shouldCastLessThanMax(ai, source)) {
|
if (!goodTargets && !ComputerUtil.shouldCastLessThanMax(ai, source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -180,8 +181,11 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhaseHandler phase = game.getPhaseHandler();
|
PhaseHandler phase = game.getPhaseHandler();
|
||||||
if (phase.isPlayerTurn(ai)
|
Card primeTarget = ComputerUtil.getKilledByTargeting(sa, tapList);
|
||||||
&& phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
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.
|
// Tap creatures possible blockers before combat during AI's turn.
|
||||||
List<Card> attackers;
|
List<Card> attackers;
|
||||||
if (phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_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 (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) {
|
if (!mandatory) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user