From cac7ac2a8a1fe83ce9dcbdf0c17be6ac62e1a1ad Mon Sep 17 00:00:00 2001 From: Hythonia Date: Tue, 4 May 2021 12:12:26 +0200 Subject: [PATCH] Remove UnlessAI from shocklands and boltlands --- .../main/java/forge/ai/ComputerUtilCost.java | 46 ++++++++++--------- ...deems_awakening_agadeem_the_undercrypt.txt | 2 +- forge-gui/res/cardsfolder/b/blood_crypt.txt | 2 +- forge-gui/res/cardsfolder/b/breeding_pool.txt | 2 +- ...emerias_call_emeria_shattered_skyclave.txt | 2 +- .../res/cardsfolder/g/godless_shrine.txt | 2 +- .../res/cardsfolder/h/hallowed_fountain.txt | 2 +- .../res/cardsfolder/o/overgrown_tomb.txt | 2 +- .../res/cardsfolder/s/sacred_foundry.txt | 2 +- .../sea_gate_restoration_sea_gate_reborn.txt | 2 +- ..._smashing_shatterskull_the_hammer_pass.txt | 2 +- forge-gui/res/cardsfolder/s/steam_vents.txt | 2 +- .../res/cardsfolder/s/stomping_ground.txt | 2 +- forge-gui/res/cardsfolder/t/temple_garden.txt | 2 +- 14 files changed, 37 insertions(+), 35 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index aafc950f898..cc1ef10ecd2 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -3,6 +3,7 @@ package forge.ai; import java.util.List; import java.util.Set; +import forge.game.ability.ApiType; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -557,7 +558,6 @@ public class ComputerUtilCost { boolean payForOwnOnly = "OnlyOwn".equals(aiLogic); boolean payOwner = sa.hasParam("UnlessAI") && aiLogic.startsWith("Defined"); boolean payNever = "Never".equals(aiLogic); - boolean lifeUntap = aiLogic.startsWith("UntapFor"); boolean isMine = sa.getActivatingPlayer().equals(payer); if (payNever) { return false; } @@ -572,27 +572,6 @@ public class ComputerUtilCost { if (sa.getHostCard() == null || payer.equals(sa.getHostCard().getController())) { return false; } - } else if (lifeUntap) { - final int needLife = Integer.parseInt(aiLogic.split("UntapFor")[1]); - if (payer.getLife() > needLife && payer.canPayLife(needLife - 1)) { - final int landsize = payer.getLandsInPlay().size() + 1; - for (Card c : payer.getCardsIn(ZoneType.Hand)) { - // if the new land size would equal the CMC of a card in AIs hand, consider playing it untapped, - // otherwise don't bother running other checks - if (landsize != c.getCMC()) { - continue; - } - // try to determine in the AI is actually planning to play a spell ability from the card - boolean willPlay = ComputerUtil.hasReasonToPlayCardThisTurn(payer, c); - // try to determine if the mana shards provided by the lands would be applicable to pay the mana cost - boolean canPay = c.getManaCost().canBePaidWithAvaliable(ColorSet.fromNames(getAvailableManaColors(payer, source)).getColor()); - - if (canPay && willPlay) { - return true; - } - } - } - return false; } else if ("Paralyze".equals(aiLogic)) { final Card c = source.getEnchantingCard(); if (c == null || c.isUntapped()) { @@ -630,6 +609,29 @@ public class ComputerUtilCost { return false; } + // Check for shocklands and similar ETB replacement effects + if (sa.hasParam("ETB") && sa.getApi().equals(ApiType.Tap)) { + for (final CostPart part : cost.getCostParts()) { + if (part instanceof CostPayLife) { + final CostPayLife lifeCost = (CostPayLife) part; + Integer amount = lifeCost.convertAmount(); + if (payer.getLife() > (amount + 1) && payer.canPayLife(amount)) { + final int landsize = payer.getLandsInPlay().size() + 1; + for (Card c : payer.getCardsIn(ZoneType.Hand)) { + // Check if the AI has enough lands to play the card + if (landsize != c.getCMC()) { + continue; + } + // Check if the AI intends to play the card and if it can pay for it with the mana it has + boolean willPlay = ComputerUtil.hasReasonToPlayCardThisTurn(payer, c); + boolean canPay = c.getManaCost().canBePaidWithAvaliable(ColorSet.fromNames(getAvailableManaColors(payer, source)).getColor()); + return canPay && willPlay; + } + } + } + } + } + // AI will only pay when it's not already payed and only opponents abilities if (alreadyPaid || (payers.size() > 1 && (isMine && !payForOwnOnly))) { return false; diff --git a/forge-gui/res/cardsfolder/a/agadeems_awakening_agadeem_the_undercrypt.txt b/forge-gui/res/cardsfolder/a/agadeems_awakening_agadeem_the_undercrypt.txt index 99b264e1f18..c0ac659ebe4 100644 --- a/forge-gui/res/cardsfolder/a/agadeems_awakening_agadeem_the_undercrypt.txt +++ b/forge-gui/res/cardsfolder/a/agadeems_awakening_agadeem_the_undercrypt.txt @@ -14,6 +14,6 @@ Name:Agadeem, the Undercrypt ManaCost:no cost Types:Land K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | UnlessAI$ UntapFor3 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}. Oracle:As Agadeem, the Undercrypt enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped.\n{T}: Add {B}. diff --git a/forge-gui/res/cardsfolder/b/blood_crypt.txt b/forge-gui/res/cardsfolder/b/blood_crypt.txt index be69deec7b3..bf9bd1574ef 100644 --- a/forge-gui/res/cardsfolder/b/blood_crypt.txt +++ b/forge-gui/res/cardsfolder/b/blood_crypt.txt @@ -2,5 +2,5 @@ Name:Blood Crypt ManaCost:no cost Types:Land Swamp Mountain K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {B} or {R}.)\nAs Blood Crypt enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/b/breeding_pool.txt b/forge-gui/res/cardsfolder/b/breeding_pool.txt index f377915aaaf..1d101c3851f 100644 --- a/forge-gui/res/cardsfolder/b/breeding_pool.txt +++ b/forge-gui/res/cardsfolder/b/breeding_pool.txt @@ -2,5 +2,5 @@ Name:Breeding Pool ManaCost:no cost Types:Land Forest Island K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {G} or {U}.)\nAs Breeding Pool enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/e/emerias_call_emeria_shattered_skyclave.txt b/forge-gui/res/cardsfolder/e/emerias_call_emeria_shattered_skyclave.txt index c9918d12dd9..63c40701075 100644 --- a/forge-gui/res/cardsfolder/e/emerias_call_emeria_shattered_skyclave.txt +++ b/forge-gui/res/cardsfolder/e/emerias_call_emeria_shattered_skyclave.txt @@ -13,6 +13,6 @@ Name:Emeria, Shattered Skyclave ManaCost:no cost Types:Land K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | UnlessAI$ UntapFor3 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}. Oracle:As Emeria, Shattered Skyclave enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped.\n{T}: Add {W}. diff --git a/forge-gui/res/cardsfolder/g/godless_shrine.txt b/forge-gui/res/cardsfolder/g/godless_shrine.txt index e99c4d73151..ee29953a243 100644 --- a/forge-gui/res/cardsfolder/g/godless_shrine.txt +++ b/forge-gui/res/cardsfolder/g/godless_shrine.txt @@ -2,5 +2,5 @@ Name:Godless Shrine ManaCost:no cost Types:Land Plains Swamp K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {W} or {B}.)\nAs Godless Shrine enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/h/hallowed_fountain.txt b/forge-gui/res/cardsfolder/h/hallowed_fountain.txt index 43a652160a1..f6c18313e18 100644 --- a/forge-gui/res/cardsfolder/h/hallowed_fountain.txt +++ b/forge-gui/res/cardsfolder/h/hallowed_fountain.txt @@ -2,5 +2,5 @@ Name:Hallowed Fountain ManaCost:no cost Types:Land Plains Island K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {W} or {U}.)\nAs Hallowed Fountain enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/o/overgrown_tomb.txt b/forge-gui/res/cardsfolder/o/overgrown_tomb.txt index 93145de485c..991068edb34 100644 --- a/forge-gui/res/cardsfolder/o/overgrown_tomb.txt +++ b/forge-gui/res/cardsfolder/o/overgrown_tomb.txt @@ -2,5 +2,5 @@ Name:Overgrown Tomb ManaCost:no cost Types:Land Swamp Forest K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {B} or {G}.)\nAs Overgrown Tomb enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/s/sacred_foundry.txt b/forge-gui/res/cardsfolder/s/sacred_foundry.txt index cd6a453fc40..1a1b05b7470 100644 --- a/forge-gui/res/cardsfolder/s/sacred_foundry.txt +++ b/forge-gui/res/cardsfolder/s/sacred_foundry.txt @@ -2,5 +2,5 @@ Name:Sacred Foundry ManaCost:no cost Types:Land Mountain Plains K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {R} or {W}.)\nAs Sacred Foundry enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/s/sea_gate_restoration_sea_gate_reborn.txt b/forge-gui/res/cardsfolder/s/sea_gate_restoration_sea_gate_reborn.txt index 07ba14269a4..7bfa0f2d5eb 100644 --- a/forge-gui/res/cardsfolder/s/sea_gate_restoration_sea_gate_reborn.txt +++ b/forge-gui/res/cardsfolder/s/sea_gate_restoration_sea_gate_reborn.txt @@ -14,6 +14,6 @@ Name:Sea Gate, Reborn ManaCost:no cost Types:Land K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | UnlessAI$ UntapFor3 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}. Oracle:As Sea Gate, Reborn enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped.\n{T}: Add {U}. diff --git a/forge-gui/res/cardsfolder/s/shatterskull_smashing_shatterskull_the_hammer_pass.txt b/forge-gui/res/cardsfolder/s/shatterskull_smashing_shatterskull_the_hammer_pass.txt index 1a6917f0707..7543e70ad2c 100644 --- a/forge-gui/res/cardsfolder/s/shatterskull_smashing_shatterskull_the_hammer_pass.txt +++ b/forge-gui/res/cardsfolder/s/shatterskull_smashing_shatterskull_the_hammer_pass.txt @@ -14,6 +14,6 @@ Name:Shatterskull, the Hammer Pass ManaCost:no cost Types:Land K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | UnlessAI$ UntapFor3 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<3> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}. Oracle:As Shatterskull, the Hammer Pass enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped.\n{T}: Add {R}. diff --git a/forge-gui/res/cardsfolder/s/steam_vents.txt b/forge-gui/res/cardsfolder/s/steam_vents.txt index 7252ff25d03..2c3282acc91 100644 --- a/forge-gui/res/cardsfolder/s/steam_vents.txt +++ b/forge-gui/res/cardsfolder/s/steam_vents.txt @@ -2,5 +2,5 @@ Name:Steam Vents ManaCost:no cost Types:Land Island Mountain K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {U} or {R}.)\nAs Steam Vents enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/s/stomping_ground.txt b/forge-gui/res/cardsfolder/s/stomping_ground.txt index d29099624cc..134d8bbb4ad 100644 --- a/forge-gui/res/cardsfolder/s/stomping_ground.txt +++ b/forge-gui/res/cardsfolder/s/stomping_ground.txt @@ -2,5 +2,5 @@ Name:Stomping Ground ManaCost:no cost Types:Land Mountain Forest K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {R} or {G}.)\nAs Stomping Ground enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/t/temple_garden.txt b/forge-gui/res/cardsfolder/t/temple_garden.txt index b405d9a7451..3039bf05e26 100644 --- a/forge-gui/res/cardsfolder/t/temple_garden.txt +++ b/forge-gui/res/cardsfolder/t/temple_garden.txt @@ -2,5 +2,5 @@ Name:Temple Garden ManaCost:no cost Types:Land Forest Plains K:ETBReplacement:Other:DBTap -SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | UnlessAI$ UntapFor2 | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. +SVar:DBTap:DB$ Tap | ETB$ True | Defined$ Self | UnlessCost$ PayLife<2> | UnlessPayer$ You | StackDescription$ enters the battlefield tapped. | SpellDescription$ As CARDNAME enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped. Oracle:({T}: Add {G} or {W}.)\nAs Temple Garden enters the battlefield, you may pay 2 life. If you don't, it enters the battlefield tapped.