mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
AI logic to blink-reload a planeswalker using Teferi's Time Twist.
This commit is contained in:
committed by
swordshine
parent
cdeb944a57
commit
c5e4518779
@@ -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 -->
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -252,6 +252,14 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||
|
||||
# Use a blink spell to reload a planeswalker's loyalty (e.g. Teferi's Time Twist)
|
||||
# A chance (per check) to activate this ability
|
||||
BLINK_RELOAD_PLANESWALKER_CHANCE=15
|
||||
# Maximum loyalty at which the planeswalker needs to be in order to activate the blink-reload
|
||||
BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY=2
|
||||
# The difference between maximum loyalty and base loyalty of the planeswalker in order to consider blink-reloading it
|
||||
BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF=2
|
||||
|
||||
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||
|
||||
@@ -253,6 +253,14 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||
|
||||
# Use a blink spell to reload a planeswalker's loyalty (e.g. Teferi's Time Twist)
|
||||
# A chance (per check) to activate this ability
|
||||
BLINK_RELOAD_PLANESWALKER_CHANCE=30
|
||||
# Maximum loyalty at which the planeswalker needs to be in order to activate the blink-reload
|
||||
BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY=2
|
||||
# The difference between maximum loyalty and base loyalty of the planeswalker in order to consider blink-reloading it
|
||||
BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF=2
|
||||
|
||||
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||
|
||||
@@ -253,6 +253,14 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=400
|
||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=5
|
||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=5
|
||||
|
||||
# Use a blink spell to reload a planeswalker's loyalty (e.g. Teferi's Time Twist)
|
||||
# A chance (per check) to activate this ability
|
||||
BLINK_RELOAD_PLANESWALKER_CHANCE=70
|
||||
# Maximum loyalty at which the planeswalker needs to be in order to activate the blink-reload
|
||||
BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY=2
|
||||
# The difference between maximum loyalty and base loyalty of the planeswalker in order to consider blink-reloading it
|
||||
BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF=1
|
||||
|
||||
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||
|
||||
@@ -253,6 +253,14 @@ BOUNCE_ALL_ELSEWHERE_CREAT_EVAL_DIFF=200
|
||||
BOUNCE_ALL_TO_HAND_NONCREAT_EVAL_DIFF=3
|
||||
BOUNCE_ALL_ELSEWHERE_NONCREAT_EVAL_DIFF=3
|
||||
|
||||
# Use a blink spell to reload a planeswalker's loyalty (e.g. Teferi's Time Twist)
|
||||
# A chance (per check) to activate this ability
|
||||
BLINK_RELOAD_PLANESWALKER_CHANCE=60
|
||||
# Maximum loyalty at which the planeswalker needs to be in order to activate the blink-reload
|
||||
BLINK_RELOAD_PLANESWALKER_MAX_LOYALTY=2
|
||||
# The difference between maximum loyalty and base loyalty of the planeswalker in order to consider blink-reloading it
|
||||
BLINK_RELOAD_PLANESWALKER_LOYALTY_DIFF=1
|
||||
|
||||
# If enabled, the AI will try to pair up cards to present to the opponent so that a specific card may be picked,
|
||||
# it'll also try to grab Accumulated Knowledge and Take Inventory more actively, as well as interact with the Trix
|
||||
# combo deck more appropriately. In Reanimator decks, this logic will make the AI pick the fattest threats in the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Teferi's Time Twist
|
||||
ManaCost:1 U
|
||||
Types:Instant
|
||||
A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Permanent.YouCtrl | TgtPrompt$ Select target permanent you control | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | AILogic$ DelayedBounce | SubAbility$ DBAnimate | SpellDescription$ Exile target permanent you control. Return that card to the battlefield under its owner’s control at the beginning of the next end step. If it enters the battlefield as a creature, it enters with an additional +1/+1 counter on it.
|
||||
A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Permanent.YouCtrl | TgtPrompt$ Select target permanent you control | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | AILogic$ DelayedBlink | SubAbility$ DBAnimate | SpellDescription$ Exile target permanent you control. Return that card to the battlefield under its owner’s control at the beginning of the next end step. If it enters the battlefield as a creature, it enters with an additional +1/+1 counter on it.
|
||||
SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Keywords$ etbCounter:P1P1:1:ValidCard$ Creature.IsRemembered | RememberObjects$ Remembered | SubAbility$ DelTrig | AILogic$ Always
|
||||
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigBounce | RememberObjects$ Remembered | AILogic$ Always | TriggerDescription$ Return that card to the battlefield under its owner’s control at the beginning of the next end step. If it enters the battlefield as a creature, it enters with an additional +1/+1 counter on it.
|
||||
SVar:TrigBounce:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRemembered
|
||||
|
||||
Reference in New Issue
Block a user