diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java index b814b347224..882b9cc87dd 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -41,6 +41,8 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { } } else if ("GideonBlackblade".equals(aiLogic)) { return SpecialCardAi.GideonBlackblade.consider(ai, sa); + } else if ("SoulEcho".equals(aiLogic)) { + return doTriggerAINoCost(ai, sa, true); } return false; } @@ -60,7 +62,7 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { @Override protected boolean doTriggerAINoCost(final Player aiPlayer, final SpellAbility sa, final boolean mandatory) { - if ("CombustibleGearhulk".equals(sa.getParam("AILogic"))) { + if ("CombustibleGearhulk".equals(sa.getParam("AILogic")) || "SoulEcho".equals(sa.getParam("AILogic"))) { for (final Player p : aiPlayer.getOpponents()) { if (p.canBeTargetedBy(sa)) { sa.resetTargets(); @@ -328,6 +330,10 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { int bestGuessDamage = totalCMC * 3 / revealedCards.size(); return life <= bestGuessDamage ? spells.get(0) : spells.get(1); + } else if ("SoulEcho".equals(logic)) { + Player target = sa.getTargetingPlayer(); + int life = target.getLife(); + return life < 10 ? spells.get(0) : Aggregates.random(spells); } else if ("Pump".equals(logic) || "BestOption".equals(logic)) { List filtered = Lists.newArrayList(); // filter first for the spells which can be done diff --git a/forge-gui/res/cardsfolder/s/soul_echo.txt b/forge-gui/res/cardsfolder/s/soul_echo.txt index 8820056d349..6aa7b34ff23 100644 --- a/forge-gui/res/cardsfolder/s/soul_echo.txt +++ b/forge-gui/res/cardsfolder/s/soul_echo.txt @@ -6,7 +6,7 @@ SVar:X:Count$xPaid S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME if there are no echo counters on it. Otherwise, target opponent may choose that for each 1 damage that would be dealt to you until your next upkeep, you remove an echo counter from CARDNAME instead. SVar:TrigSac:DB$ Sacrifice | Defined$ Self | ConditionPresent$ Card.Self+counters_EQ0_ECHO | SubAbility$ TrigChoose -SVar:TrigChoose:DB$ GenericChoice | ConditionPresent$ Card.Self+counters_GT0_ECHO | ValidTgts$ Opponent | Choices$ RemoveCounters,DealDamage +SVar:TrigChoose:DB$ GenericChoice | AILogic$ SoulEcho | ConditionPresent$ Card.Self+counters_GT0_ECHO | ValidTgts$ Opponent | Choices$ RemoveCounters,DealDamage SVar:DealDamage:DB$ Pump | Defined$ You | SpellDescription$ Damage will be applied to this player's life as usual. SVar:RemoveCounters:DB$ Effect | ReplacementEffects$ Damage | SVars$ Damage,Counters,Y | ExileOnMoved$ Exile | Duration$ UntilYourNextUpkeep | SpellDescription$ For each 1 damage that would be dealt to this player until their next upkeep, they remove an echo counter from CARDNAME instead. SVar:Damage:Event$ DamageDone | ValidTarget$ You | ReplaceWith$ Counters | Description$ For each 1 damage that would be dealt to you until your next upkeep, you remove an echo counter from Soul Echo instead.