AI logic to blink-reload a planeswalker using Teferi's Time Twist.

This commit is contained in:
Michael Kamensky
2019-05-21 14:39:33 +00:00
committed by swordshine
parent cdeb944a57
commit c5e4518779
7 changed files with 68 additions and 4 deletions

View File

@@ -129,7 +129,10 @@ public enum AiProps { /** */
FLASH_USE_BUFF_AURAS_AS_COMBAT_TRICKS("true"),
FLASH_BUFF_AURA_CHANCE_TO_CAST_EARLY("1"),
FLASH_BUFF_AURA_CHANCE_CAST_AT_EOT("5"),
FLASH_BUFF_AURA_CHANCE_TO_RESPOND_TO_STACK("100"); /** */
FLASH_BUFF_AURA_CHANCE_TO_RESPOND_TO_STACK("100"),
BLINK_RELOAD_PLANESWALKER_CHANCE("30"), /** */
BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY("2"), /** */
BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF("2"); /** */
// Experimental features, must be promoted or removed after extensive testing and, ideally, defaulting
// <-- There are no experimental options here -->

View File

@@ -26,6 +26,7 @@ import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.MyRandom;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
@@ -677,7 +678,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// only use blink or bounce effects
if (!(destination.equals(ZoneType.Exile)
&& (subApi == ApiType.DelayedTrigger || subApi == ApiType.ChangeZone || "DelayedBounce".equals(sa.getParam("AILogic"))))
&& (subApi == ApiType.DelayedTrigger || subApi == ApiType.ChangeZone || "DelayedBlink".equals(sa.getParam("AILogic"))))
&& !destination.equals(ZoneType.Hand)) {
return false;
}
@@ -937,7 +938,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// if it's blink or bounce, try to save my about to die stuff
final boolean blink = (destination.equals(ZoneType.Exile) && (subApi == ApiType.DelayedTrigger
|| "DelayedBounce".equals(sa.getParam("AILogic")) || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered"))));
|| "DelayedBlink".equals(sa.getParam("AILogic")) || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered"))));
if ((destination.equals(ZoneType.Hand) || blink) && (tgt.getMinTargets(sa.getHostCard(), sa) <= 1)) {
// save my about to die stuff
Card tobounce = canBouncePermanent(ai, sa, list);
@@ -1231,6 +1232,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
// filter out untargetables
CardCollectionView aiPermanents = CardLists
.filterControlledBy(list, ai);
CardCollection aiPlaneswalkers = CardLists.filter(aiPermanents, Presets.PLANESWALKERS);
// Felidar Guardian + Saheeli Rai combo support
if (sa.getHostCard().getName().equals("Felidar Guardian")) {
@@ -1274,6 +1276,33 @@ public class ChangeZoneAi extends SpellAbilityAi {
}
}
}
// Reload planeswalkers
else if (!aiPlaneswalkers.isEmpty() && (sa.getHostCard().isSorcery() || !game.getPhaseHandler().isPlayerTurn(ai))) {
int maxLoyaltyToConsider = 2;
int loyaltyDiff = 2;
int chance = 30;
if (ai.getController().isAI()) {
AiController aic = ((PlayerControllerAi) ai.getController()).getAi();
maxLoyaltyToConsider = aic.getIntProperty(AiProps.BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY);
loyaltyDiff = aic.getIntProperty(AiProps.BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF);
chance = aic.getIntProperty(AiProps.BLINK_RELOAD_PLANESWALKER_CHANCE);
}
if (MyRandom.percentTrue(chance)) {
Collections.sort(aiPlaneswalkers, new Comparator<Card>() {
@Override
public int compare(final Card a, final Card b) {
return a.getCounters(CounterType.LOYALTY) - b.getCounters(CounterType.LOYALTY);
}
});
for (Card pw : aiPlaneswalkers) {
int curLoyalty = pw.getCounters(CounterType.LOYALTY);
int freshLoyalty = pw.getCurrentState().getBaseLoyalty();
if (freshLoyalty - curLoyalty >= loyaltyDiff && curLoyalty <= maxLoyaltyToConsider) {
return pw;
}
}
}
}
return null;
}