From 47456bf9c449d1d25098274c65e5527929340e2b Mon Sep 17 00:00:00 2001 From: Alexander Novotny Date: Mon, 3 Jul 2023 20:42:19 -0700 Subject: [PATCH] Fixed issue with `UntapTargetCost` (#10559) * Fixed issue with UntapTargetCost The target was allowed to actually target, so things like Halo Fountain wouldn't work on creatures with shroud. UntapTargetCost also keeps track of the permanents which were untapped, in case those are needed. Changed Benthic Explorers to use new UntapTargetCost * Fixed potential bug with Benthic Explorers --- .../src/mage/cards/b/BenthicExplorers.java | 55 ++----------------- .../costs/common/UntapTargetCost.java | 24 ++++++-- 2 files changed, 25 insertions(+), 54 deletions(-) diff --git a/Mage.Sets/src/mage/cards/b/BenthicExplorers.java b/Mage.Sets/src/mage/cards/b/BenthicExplorers.java index 01923604923..98333b18c7d 100644 --- a/Mage.Sets/src/mage/cards/b/BenthicExplorers.java +++ b/Mage.Sets/src/mage/cards/b/BenthicExplorers.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.Mana; import mage.abilities.Abilities; import mage.abilities.Ability; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.common.UntapTargetCost; import mage.abilities.effects.mana.ManaEffect; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.CardImpl; @@ -19,7 +18,6 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetLandPermanent; -import mage.util.CardUtil; import java.util.ArrayList; import java.util.EnumSet; @@ -49,8 +47,8 @@ public final class BenthicExplorers extends CardImpl { // {T}, Untap a tapped land an opponent controls: Add one mana of any type that land could produce. Ability ability = new BenthicExplorersManaAbility(); - ability.addCost(new BenthicExplorersCost( - new TargetLandPermanent(1, 1, filter, true) + ability.addCost(new UntapTargetCost( + new TargetLandPermanent(filter) )); this.addAbility(ability); } @@ -65,49 +63,6 @@ public final class BenthicExplorers extends CardImpl { } } -class BenthicExplorersCost extends CostImpl { - - private final TargetLandPermanent target; - - public BenthicExplorersCost(TargetLandPermanent target) { - this.target = target; - this.text = "Untap " + target.getDescription(); - } - - public BenthicExplorersCost(final BenthicExplorersCost cost) { - super(cost); - this.target = cost.target.copy(); - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - if (target.choose(Outcome.Untap, controllerId, source.getSourceId(), source, game)) { - for (UUID targetId : target.getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent == null) { - return false; - } - paid |= permanent.untap(game); - if (paid) { - game.getState().setValue("UntapTargetCost" + ability.getSourceId().toString(), permanent); // remember the untapped permanent - } - } - } - return paid; - } - - @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return target.canChoose(controllerId, source, game); - } - - @Override - public BenthicExplorersCost copy() { - return new BenthicExplorersCost(this); - } - -} - class BenthicExplorersManaAbility extends ActivatedManaAbilityImpl { BenthicExplorersManaAbility() { @@ -202,7 +157,9 @@ class BenthicExplorersManaEffect extends ManaEffect { return types; } - Permanent land = (Permanent) game.getState().getValue("UntapTargetCost" + source.getSourceId().toString()); + List untapped = (List) game.getState() + .getValue("UntapTargetCost" + source.getSourceId().toString()); + Permanent land = game.getPermanentOrLKIBattlefield(untapped.get(0)); if (land == null) { return types; } Abilities mana = land.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD); diff --git a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java index cdae3e00688..fe878fa12a4 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/UntapTargetCost.java @@ -6,9 +6,11 @@ import mage.abilities.costs.CostImpl; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.target.common.TargetControlledPermanent; +import mage.target.TargetPermanent; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -16,11 +18,14 @@ import java.util.UUID; */ public class UntapTargetCost extends CostImpl { - private final TargetControlledPermanent target; + private final TargetPermanent target; - public UntapTargetCost(TargetControlledPermanent target) { + public UntapTargetCost(TargetPermanent target) { this.target = target; this.text = makeText(target); + + // It will never target as part of a cost + this.target.setNotTarget(true); } public UntapTargetCost(final UntapTargetCost cost) { @@ -33,13 +38,22 @@ public class UntapTargetCost extends CostImpl { if (!target.choose(Outcome.Untap, controllerId, source.getSourceId(), source, game)) { return paid; } + List untapped = new ArrayList<>(); for (UUID targetId : target.getTargets()) { Permanent permanent = game.getPermanent(targetId); if (permanent == null) { return false; } - paid |= permanent.untap(game); + + if (permanent.untap(game)) { + untapped.add(targetId); + } + } + + game.getState().setValue("UntapTargetCost" + ability.getSourceId().toString(), untapped); // remember the untapped permanent + + paid |= untapped.size() >= target.getMinNumberOfTargets(); return paid; } @@ -53,7 +67,7 @@ public class UntapTargetCost extends CostImpl { return new UntapTargetCost(this); } - private static String makeText(TargetControlledPermanent target) { + private static String makeText(TargetPermanent target) { StringBuilder sb = new StringBuilder("untap "); if (target.getMaxNumberOfTargets() > 1) { sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets()));