From f4dd6ba1e7d6438832a025cd717b0f3e07b96701 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 12 Apr 2021 09:08:50 -0400 Subject: [PATCH] added new EachTargetPointer object --- .../src/mage/cards/b/BlatantThievery.java | 46 +----- .../src/mage/cards/t/TemptedByTheOriq.java | 48 +------ .../targetpointer/EachTargetPointer.java | 132 ++++++++++++++++++ 3 files changed, 141 insertions(+), 85 deletions(-) create mode 100644 Mage/src/main/java/mage/target/targetpointer/EachTargetPointer.java diff --git a/Mage.Sets/src/mage/cards/b/BlatantThievery.java b/Mage.Sets/src/mage/cards/b/BlatantThievery.java index 95eebac7c8..9a754b6806 100644 --- a/Mage.Sets/src/mage/cards/b/BlatantThievery.java +++ b/Mage.Sets/src/mage/cards/b/BlatantThievery.java @@ -1,29 +1,21 @@ package mage.cards.b; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; import mage.target.TargetPermanent; import mage.target.targetadjustment.TargetAdjuster; -import mage.target.targetpointer.FixedTargets; +import mage.target.targetpointer.EachTargetPointer; -import java.util.Collection; -import java.util.List; -import java.util.Objects; import java.util.UUID; -import java.util.stream.Collectors; /** * @author emerald000 @@ -34,7 +26,9 @@ public final class BlatantThievery extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}{U}"); // For each opponent, gain control of target permanent that player controls. - this.getSpellAbility().addEffect(new BlatantThieveryEffect()); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true) + .setTargetPointer(new EachTargetPointer()) + .setText("for each opponent, gain control of target permanent that player controls")); this.getSpellAbility().setTargetAdjuster(BlatantThieveryAdjuster.instance); } @@ -69,35 +63,3 @@ enum BlatantThieveryAdjuster implements TargetAdjuster { } } } - -class BlatantThieveryEffect extends OneShotEffect { - - BlatantThieveryEffect() { - super(Outcome.Benefit); - staticText = "for each opponent, gain control of target permanent that player controls"; - } - - private BlatantThieveryEffect(final BlatantThieveryEffect effect) { - super(effect); - } - - @Override - public BlatantThieveryEffect copy() { - return new BlatantThieveryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - List permanents = source - .getTargets() - .stream() - .map(Target::getTargets) - .flatMap(Collection::stream) - .map(game::getPermanent) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - game.addEffect(new GainControlTargetEffect(Duration.Custom, true) - .setTargetPointer(new FixedTargets(permanents, game)), source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java b/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java index 28a43b1259..5a5e52027e 100644 --- a/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java +++ b/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java @@ -1,31 +1,23 @@ package mage.cards.t; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; import mage.target.TargetPermanent; import mage.target.targetadjustment.TargetAdjuster; -import mage.target.targetpointer.FixedTargets; +import mage.target.targetpointer.EachTargetPointer; -import java.util.Collection; -import java.util.List; -import java.util.Objects; import java.util.UUID; -import java.util.stream.Collectors; /** * @author TheElk801 @@ -36,7 +28,10 @@ public final class TemptedByTheOriq extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{U}{U}"); // For each opponent, gain control of up to one target creature or planeswalker that player controls with mana value 3 or less. - this.getSpellAbility().addEffect(new TemptedByTheOriqEffect()); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true) + .setTargetPointer(new EachTargetPointer()) + .setText("for each opponent, gain control of up to one target creature " + + "or planeswalker that player controls with mana value 3 or less")); this.getSpellAbility().setTargetAdjuster(TemptedByTheOriqAdjuster.instance); } @@ -70,36 +65,3 @@ enum TemptedByTheOriqAdjuster implements TargetAdjuster { } } } - -class TemptedByTheOriqEffect extends OneShotEffect { - - TemptedByTheOriqEffect() { - super(Outcome.Benefit); - staticText = "for each opponent, gain control of up to one target creature " + - "or planeswalker that player controls with mana value 3 or less"; - } - - private TemptedByTheOriqEffect(final TemptedByTheOriqEffect effect) { - super(effect); - } - - @Override - public TemptedByTheOriqEffect copy() { - return new TemptedByTheOriqEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - List permanents = source - .getTargets() - .stream() - .map(Target::getTargets) - .flatMap(Collection::stream) - .map(game::getPermanent) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - game.addEffect(new GainControlTargetEffect(Duration.Custom, true) - .setTargetPointer(new FixedTargets(permanents, game)), source); - return true; - } -} diff --git a/Mage/src/main/java/mage/target/targetpointer/EachTargetPointer.java b/Mage/src/main/java/mage/target/targetpointer/EachTargetPointer.java new file mode 100644 index 0000000000..2ae5cdc6ab --- /dev/null +++ b/Mage/src/main/java/mage/target/targetpointer/EachTargetPointer.java @@ -0,0 +1,132 @@ +package mage.target.targetpointer; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.cards.Card; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.Target; + +import java.util.*; +import java.util.stream.Collectors; + +public class EachTargetPointer extends TargetPointerImpl { + + private Map zoneChangeCounter = new HashMap<>(); + + public static EachTargetPointer getInstance() { + return new EachTargetPointer(); + } + + public EachTargetPointer() { + super(); + } + + public EachTargetPointer(final EachTargetPointer targetPointer) { + super(targetPointer); + + this.zoneChangeCounter = new HashMap<>(); + for (Map.Entry entry : targetPointer.zoneChangeCounter.entrySet()) { + this.zoneChangeCounter.put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void init(Game game, Ability source) { + if (!source.getTargets().isEmpty()) { + for (UUID target : source + .getTargets() + .stream() + .map(Target::getTargets) + .flatMap(Collection::stream) + .collect(Collectors.toList())) { + Card card = game.getCard(target); + if (card != null) { + this.zoneChangeCounter.put(target, card.getZoneChangeCounter(game)); + } + } + } + } + + @Override + public List getTargets(Game game, Ability source) { + List target = new ArrayList<>(); + if (!source.getTargets().isEmpty()) { + for (UUID targetId : source + .getTargets() + .stream() + .map(Target::getTargets) + .flatMap(Collection::stream) + .collect(Collectors.toList())) { + Card card = game.getCard(targetId); + if (card != null && zoneChangeCounter.containsKey(targetId) + && card.getZoneChangeCounter(game) != zoneChangeCounter.get(targetId)) { + // but no longer if new permanent is already on the battlefield + Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); + if (permanent == null || permanent.getZoneChangeCounter(game) != zoneChangeCounter.get(targetId)) { + continue; + } + } + target.add(targetId); + } + } + return target; + } + + @Override + public UUID getFirst(Game game, Ability source) { + UUID targetId = source.getFirstTarget(); + if (zoneChangeCounter.containsKey(targetId)) { + Card card = game.getCard(targetId); + if (card != null && zoneChangeCounter.containsKey(targetId) + && card.getZoneChangeCounter(game) != zoneChangeCounter.get(targetId)) { + // because if dies trigger has to trigger as permanent has already moved zone, we have to check if target was on the battlefield immed. before + // but no longer if new permanent is already on the battlefield + Permanent permanent = game.getPermanentOrLKIBattlefield(targetId); + if (permanent == null || permanent.getZoneChangeCounter(game) != zoneChangeCounter.get(targetId)) { + return null; + } + } + } + return targetId; + } + + @Override + public EachTargetPointer copy() { + return new EachTargetPointer(this); + } + + @Override + public FixedTarget getFixedTarget(Game game, Ability source) { + this.init(game, source); + UUID firstId = getFirst(game, source); + if (firstId != null) { + return new FixedTarget(firstId, game.getState().getZoneChangeCounter(firstId)); + } + return null; + + } + + @Override + public Permanent getFirstTargetPermanentOrLKI(Game game, Ability source) { + UUID targetId = source.getFirstTarget(); + Permanent permanent; + if (zoneChangeCounter.containsKey(targetId)) { + permanent = game.getPermanent(targetId); + if (permanent != null && permanent.getZoneChangeCounter(game) == zoneChangeCounter.get(targetId)) { + return permanent; + } + MageObject mageObject = game.getLastKnownInformation(targetId, Zone.BATTLEFIELD, zoneChangeCounter.get(targetId)); + if (mageObject instanceof Permanent) { + return (Permanent) mageObject; + } + } else { + permanent = game.getPermanent(targetId); + if (permanent == null) { + permanent = (Permanent) game.getLastKnownInformation(targetId, Zone.BATTLEFIELD); + } + } + return permanent; + } +}