mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
AI logic for Veil of Summer (#4149)
* - AI logic for Veil of Summer. * - Simplify implementation.
This commit is contained in:
@@ -1683,6 +1683,41 @@ public class SpecialCardAi {
|
||||
}
|
||||
}
|
||||
|
||||
// Veil of Summer
|
||||
public static class VeilOfSummer {
|
||||
public static boolean consider(final Player ai, final SpellAbility sa) {
|
||||
// check the top ability on stack if it's (a) an opponent's counterspell targeting the AI's spell;
|
||||
// (b) a black or a blue spell targeting something that belongs to the AI
|
||||
Game game = ai.getGame();
|
||||
if (game.getStack().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SpellAbility topSA = game.getStack().peekAbility();
|
||||
if (topSA.usesTargeting() && topSA.getActivatingPlayer().isOpponentOf(ai)) {
|
||||
if (topSA.getApi() == ApiType.Counter) {
|
||||
SpellAbility tgtSpell = topSA.getTargets().getFirstTargetedSpell();
|
||||
if (tgtSpell != null && tgtSpell.getActivatingPlayer().equals(ai)) {
|
||||
return true;
|
||||
}
|
||||
} else if (topSA.getHostCard().isBlack() || topSA.getHostCard().isBlue()) {
|
||||
for (Player tgtP : topSA.getTargets().getTargetPlayers()) {
|
||||
if (tgtP.equals(ai)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (Card tgtC : topSA.getTargets().getTargetCards()) {
|
||||
if (tgtC.getController().equals(ai)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Volrath's Shapeshifter
|
||||
public static class VolrathsShapeshifter {
|
||||
public static boolean consider(final Player ai, final SpellAbility sa) {
|
||||
|
||||
@@ -132,18 +132,6 @@ public class DrawAi extends SpellAbilityAi {
|
||||
*/
|
||||
@Override
|
||||
protected boolean checkPhaseRestrictions(Player ai, SpellAbility sa, PhaseHandler ph) {
|
||||
String logic = sa.getParamOrDefault("AILogic", "");
|
||||
|
||||
if (logic.startsWith("LifeLessThan.")) {
|
||||
// LifeLessThan logic presupposes activation as soon as possible in an
|
||||
// attempt to save the AI from dying
|
||||
return true;
|
||||
} else if (logic.equals("AtOppEOT")) {
|
||||
return ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn().equals(ai);
|
||||
} else if (logic.equals("RespondToOwnActivation")) {
|
||||
return !ai.getGame().getStack().isEmpty() && ai.getGame().getStack().peekAbility().getHostCard().equals(sa.getHostCard());
|
||||
}
|
||||
|
||||
// Sacrificing a creature in response to something dangerous is generally good in any phase
|
||||
boolean isSacCost = false;
|
||||
if (sa.getPayCosts() != null && sa.getPayCosts().hasSpecificCostType(CostSacrifice.class)) {
|
||||
@@ -169,7 +157,17 @@ public class DrawAi extends SpellAbilityAi {
|
||||
*/
|
||||
@Override
|
||||
protected boolean checkPhaseRestrictions(Player ai, SpellAbility sa, PhaseHandler ph, String logic) {
|
||||
if ((!ph.getNextTurn().equals(ai) || ph.getPhase().isBefore(PhaseType.END_OF_TURN))
|
||||
if (logic.equals("VeilOfSummer")) {
|
||||
return SpecialCardAi.VeilOfSummer.consider(ai, sa); // this is more of a counterspell than a true draw card, so it's timed by the card-specific logic
|
||||
} else if (logic.startsWith("LifeLessThan.")) {
|
||||
// LifeLessThan logic presupposes activation as soon as possible in an
|
||||
// attempt to save the AI from dying
|
||||
return true;
|
||||
} else if (logic.equals("AtOppEOT")) {
|
||||
return ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn().equals(ai);
|
||||
} else if (logic.equals("RespondToOwnActivation")) {
|
||||
return !ai.getGame().getStack().isEmpty() && ai.getGame().getStack().peekAbility().getHostCard().equals(sa.getHostCard());
|
||||
} else if ((!ph.getNextTurn().equals(ai) || ph.getPhase().isBefore(PhaseType.END_OF_TURN))
|
||||
&& !sa.hasParam("PlayerTurn") && !isSorcerySpeed(sa, ai)
|
||||
&& ai.getCardsIn(ZoneType.Hand).size() > 1 && !ComputerUtil.activateForCost(sa, ai)
|
||||
&& !"YawgmothsBargain".equals(logic)) {
|
||||
|
||||
Reference in New Issue
Block a user