From 192ebb144cbf3fc22bc9f511f8ba767d56c58975 Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Sun, 21 Feb 2021 19:14:04 +0300 Subject: [PATCH 1/2] - Somewhat improve the AI logic for Vivien, Monsters' Advocate and LifeLoseAi / Liliana, Death Mage --- .../java/forge/ai/ability/ChooseGenericEffectAi.java | 2 ++ .../src/main/java/forge/ai/ability/LifeLoseAi.java | 11 ++++++----- .../res/cardsfolder/v/vivien_monsters_advocate.txt | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) 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 882b9cc87dd..6c0c8d1990a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -43,6 +43,8 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { return SpecialCardAi.GideonBlackblade.consider(ai, sa); } else if ("SoulEcho".equals(aiLogic)) { return doTriggerAINoCost(ai, sa, true); + } else if ("Always".equals(aiLogic)) { + return true; } return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java index c7f8f13f404..2437c97a49a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java @@ -101,6 +101,12 @@ public class LifeLoseAi extends SpellAbilityAi { final String amountStr = sa.getParam("LifeAmount"); int amount = 0; + if (sa.usesTargeting()) { + if (!doTgt(ai, sa, false)) { + return false; + } + } + if (amountStr.equals("X") && sa.getSVar(amountStr).equals("Count$xPaid")) { // Set PayX here to maximum value. amount = ComputerUtilCost.getMaxXValue(sa, ai); @@ -117,11 +123,6 @@ public class LifeLoseAi extends SpellAbilityAi { return false; } - if (sa.usesTargeting()) { - if (!doTgt(ai, sa, false)) { - return false; - } - } final PlayerCollection tgtPlayers = getPlayers(ai, sa); if (ComputerUtil.playImmediately(ai, sa)) { diff --git a/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt b/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt index 8d49056e2fe..d6f28a156f9 100755 --- a/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt +++ b/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt @@ -6,12 +6,12 @@ S:Mode$ Continuous | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | S:Mode$ Continuous | Affected$ Creature.TopLibrary+YouCtrl | MayPlay$ True | AffectedZone$ Library | Description$ You may cast creature spells from the top of your library. SVar:NonStackingEffect:True A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ g_3_3_beast | TokenOwner$ You | LegacyImage$ g 3 3 beast iko | RememberTokens$ True | SubAbility$ DBGenericChoice | SpellDescription$ Create a 3/3 green Beast creature token. Put your choice of a vigilance counter, a reach counter, or a trample counter on it. -SVar:DBGenericChoice:DB$ GenericChoice | Defined$ You | Choices$ Vigilance,Reach,Trample +SVar:DBGenericChoice:DB$ GenericChoice | Defined$ You | Choices$ Vigilance,Reach,Trample | AILogic$ Always SVar:Reach:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a token to put a reach counter on | CounterType$ Reach | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Reach SVar:Trample:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a token to put a trample counter on | CounterType$ Trample | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Trample SVar:Vigilance:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a token to put a vigilance counter on | CounterType$ Vigilance | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Vigilance SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | SVars$ DBSearch,X | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. +A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | SVars$ DBSearch,X | AILogic$ Main1 | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. SVar:TrigSearch:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | OneOff$ True | TriggerZones$ Command | Execute$ DBSearch | TriggerDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. SVar:DBSearch:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLTX | References$ X | ChangeNum$ 1 SVar:X:TriggerCount$CastSACMC From eb68d4be04ad924315df223d07d75841e8b006fc Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Sun, 21 Feb 2021 21:41:01 +0300 Subject: [PATCH 2/2] - Better EffectAi for Vivien, Monsters' Advocate --- .../src/main/java/forge/ai/ability/EffectAi.java | 13 ++++++++----- .../res/cardsfolder/v/vivien_monsters_advocate.txt | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java index 566746434aa..16999292f12 100644 --- a/forge-ai/src/main/java/forge/ai/ability/EffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/EffectAi.java @@ -1,11 +1,8 @@ package forge.ai.ability; -import java.util.List; - import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; - import forge.ai.*; import forge.game.Game; import forge.game.ability.ApiType; @@ -21,6 +18,8 @@ import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; import forge.util.MyRandom; +import java.util.List; + public class EffectAi extends SpellAbilityAi { @Override protected boolean canPlayAI(final Player ai,final SpellAbility sa) { @@ -102,11 +101,15 @@ public class EffectAi extends SpellAbilityAi { } randomReturn = true; } else if (logic.equals("ChainVeil")) { - if (!phase.isPlayerTurn(ai) || !phase.getPhase().equals(PhaseType.MAIN2) - || CardLists.getType(ai.getCardsIn(ZoneType.Battlefield), "Planeswalker").isEmpty()) { + if (!phase.isPlayerTurn(ai) || !phase.getPhase().equals(PhaseType.MAIN2) + || CardLists.getType(ai.getCardsIn(ZoneType.Battlefield), "Planeswalker").isEmpty()) { return false; } randomReturn = true; + } else if (logic.equals("WillCastCreature") && ai.isAI()) { + AiController aic = ((PlayerControllerAi)ai.getController()).getAi(); + SpellAbility saCreature = aic.predictSpellToCastInMain2(ApiType.PermanentCreature); + randomReturn = saCreature != null && ComputerUtilMana.canPayManaCost(saCreature, ai, 0); } else if (logic.equals("Always")) { randomReturn = true; } else if (logic.equals("Main1")) { diff --git a/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt b/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt index d6f28a156f9..1b45749c192 100755 --- a/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt +++ b/forge-gui/res/cardsfolder/v/vivien_monsters_advocate.txt @@ -11,7 +11,7 @@ SVar:Reach:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a t SVar:Trample:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a token to put a trample counter on | CounterType$ Trample | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Trample SVar:Vigilance:DB$ PutCounter | Choices$ Card.IsRemembered | ChoiceTitle$ Choose a token to put a vigilance counter on | CounterType$ Vigilance | CounterNum$ 1 | SubAbility$ DBCleanup | SpellDescription$ Vigilance SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | SVars$ DBSearch,X | AILogic$ Main1 | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. +A:AB$ Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Ultimate$ True | Triggers$ TrigSearch | SVars$ DBSearch,X | AILogic$ WillCastCreature | SpellDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. SVar:TrigSearch:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | OneOff$ True | TriggerZones$ Command | Execute$ DBSearch | TriggerDescription$ When you cast your next creature spell this turn, search your library for a creature card with lesser converted mana cost, put it onto the battlefield, then shuffle your library. SVar:DBSearch:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.cmcLTX | References$ X | ChangeNum$ 1 SVar:X:TriggerCount$CastSACMC