mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
- Allow AI to use ChangeZone effects against a blocker before trying to bounce its own attacker. Ensure that the AI will use its removal on a blocker if it can save an attacker
This commit is contained in:
@@ -901,11 +901,34 @@ public class ComputerUtilCard {
|
|||||||
public static boolean useRemovalNow(final SpellAbility sa, final Card c, final int dmg, ZoneType destination) {
|
public static boolean useRemovalNow(final SpellAbility sa, final Card c, final int dmg, ZoneType destination) {
|
||||||
final Player ai = sa.getActivatingPlayer();
|
final Player ai = sa.getActivatingPlayer();
|
||||||
final Player opp = ai.getOpponent();
|
final Player opp = ai.getOpponent();
|
||||||
final PhaseHandler ph = ai.getGame().getPhaseHandler();
|
final Game game = ai.getGame();
|
||||||
|
final PhaseHandler ph = game.getPhaseHandler();
|
||||||
|
|
||||||
final int costRemoval = sa.getHostCard().getCMC();
|
final int costRemoval = sa.getHostCard().getCMC();
|
||||||
final int costTarget = c.getCMC();
|
final int costTarget = c.getCMC();
|
||||||
|
|
||||||
|
//interrupt 1:remove blocker to save my attacker
|
||||||
|
if (ph.is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||||
|
Combat currCombat = game.getCombat();
|
||||||
|
if (currCombat != null && currCombat.getAllBlockers().contains(c)) {
|
||||||
|
for (Card attacker : currCombat.getAttackersBlockedBy(c)) {
|
||||||
|
List<Card> blockers = currCombat.getBlockers(attacker);
|
||||||
|
ComputerUtilCard.sortByEvaluateCreature(blockers);
|
||||||
|
Combat combat = new Combat(ai);
|
||||||
|
combat.addAttacker(attacker, opp);
|
||||||
|
for (Card blocker : blockers) {
|
||||||
|
if (blocker == c) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
combat.addBlocker(attacker, blocker);
|
||||||
|
}
|
||||||
|
if (!ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, combat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//burn and curse spells
|
//burn and curse spells
|
||||||
float valueBurn = 0;
|
float valueBurn = 0;
|
||||||
if (dmg > 0) {
|
if (dmg > 0) {
|
||||||
@@ -956,7 +979,7 @@ public class ComputerUtilCard {
|
|||||||
valueTempo *= 2; //prefer to cast at opponent EOT
|
valueTempo *= 2; //prefer to cast at opponent EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
//interrupt 1:opponent pumping target (only works if the pump target is the chosen best target to begin with)
|
//interrupt 2:opponent pumping target (only works if the pump target is the chosen best target to begin with)
|
||||||
final MagicStack stack = ai.getGame().getStack();
|
final MagicStack stack = ai.getGame().getStack();
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
final SpellAbility topStack = stack.peekAbility();
|
final SpellAbility topStack = stack.peekAbility();
|
||||||
|
|||||||
@@ -726,6 +726,33 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
// Don't blink cards that will die.
|
// Don't blink cards that will die.
|
||||||
aiPermanents = ComputerUtil.getSafeTargets(ai, sa, aiPermanents);
|
aiPermanents = ComputerUtil.getSafeTargets(ai, sa, aiPermanents);
|
||||||
|
|
||||||
|
// Removal on blocker to save my creature
|
||||||
|
if (tgt.getMinTargets(sa.getHostCard(), sa) <= 1) {
|
||||||
|
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
|
||||||
|
Combat currCombat = game.getCombat();
|
||||||
|
for (Card attacker : currCombat.getAttackers()) {
|
||||||
|
if (ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, currCombat) && !currCombat.getBlockers(attacker).isEmpty()) {
|
||||||
|
List<Card> blockers = currCombat.getBlockers(attacker);
|
||||||
|
ComputerUtilCard.sortByEvaluateCreature(blockers);
|
||||||
|
Combat combat = new Combat(ai);
|
||||||
|
combat.addAttacker(attacker, ai.getOpponent());
|
||||||
|
for (Card blocker : blockers) {
|
||||||
|
combat.addBlocker(attacker, blocker);
|
||||||
|
}
|
||||||
|
for (Card blocker : blockers) {
|
||||||
|
combat.removeFromCombat(blocker);
|
||||||
|
if (!ComputerUtilCombat.attackerWouldBeDestroyed(ai, attacker, combat) && sa.canTarget(blocker)) {
|
||||||
|
sa.getTargets().add(blocker);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
combat.addBlocker(attacker, blocker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if it's blink or bounce, try to save my about to die stuff
|
// if it's blink or bounce, try to save my about to die stuff
|
||||||
if ((destination.equals(ZoneType.Hand) || (destination.equals(ZoneType.Exile)
|
if ((destination.equals(ZoneType.Hand) || (destination.equals(ZoneType.Exile)
|
||||||
&& (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))))
|
&& (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))))
|
||||||
|
|||||||
Reference in New Issue
Block a user