From 91a648c50d9a487cef25c151e01a0e26f0113bf5 Mon Sep 17 00:00:00 2001
From: 4825764518 <100122841+4825764518@users.noreply.github.com>
Date: Mon, 17 Feb 2025 19:57:55 -0500
Subject: [PATCH] [ACR] Implement Viewpoint Synchronization (#13358)
---
Mage.Sets/src/mage/cards/c/Cultivate.java | 4 +-
.../src/mage/cards/f/FlareOfCultivation.java | 4 +-
.../src/mage/cards/f/FlourishingBloomKin.java | 4 +-
Mage.Sets/src/mage/cards/k/KodamasReach.java | 4 +-
Mage.Sets/src/mage/cards/n/NavigationOrb.java | 4 +-
.../src/mage/cards/n/NissasPilgrimage.java | 6 +--
Mage.Sets/src/mage/cards/p/Peregrination.java | 4 +-
.../cards/v/ViewpointSynchronization.java | 32 ++++++++++++++++
Mage.Sets/src/mage/sets/AssassinsCreed.java | 4 +-
...ntoBattlefieldTappedRestInHandEffect.java} | 37 ++++++++++++-------
10 files changed, 73 insertions(+), 30 deletions(-)
create mode 100644 Mage.Sets/src/mage/cards/v/ViewpointSynchronization.java
rename Mage/src/main/java/mage/abilities/effects/common/search/{SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect.java => SearchLibraryPutOntoBattlefieldTappedRestInHandEffect.java} (53%)
diff --git a/Mage.Sets/src/mage/cards/c/Cultivate.java b/Mage.Sets/src/mage/cards/c/Cultivate.java
index db5b9a96978..aec124c0685 100644
--- a/Mage.Sets/src/mage/cards/c/Cultivate.java
+++ b/Mage.Sets/src/mage/cards/c/Cultivate.java
@@ -1,6 +1,6 @@
package mage.cards.c;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.filter.StaticFilters;
@@ -17,7 +17,7 @@ public final class Cultivate extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
// Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.
- this.getSpellAbility().addEffect(new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(
+ this.getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS)));
}
diff --git a/Mage.Sets/src/mage/cards/f/FlareOfCultivation.java b/Mage.Sets/src/mage/cards/f/FlareOfCultivation.java
index a69263f3436..fd4ae247357 100644
--- a/Mage.Sets/src/mage/cards/f/FlareOfCultivation.java
+++ b/Mage.Sets/src/mage/cards/f/FlareOfCultivation.java
@@ -3,7 +3,7 @@ package mage.cards.f;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -35,7 +35,7 @@ public final class FlareOfCultivation extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(filter)).setRuleAtTheTop(true));
// Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.
- this.getSpellAbility().addEffect(new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(
+ this.getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS)
));
}
diff --git a/Mage.Sets/src/mage/cards/f/FlourishingBloomKin.java b/Mage.Sets/src/mage/cards/f/FlourishingBloomKin.java
index 66aa3e6824d..49f20b54d04 100644
--- a/Mage.Sets/src/mage/cards/f/FlourishingBloomKin.java
+++ b/Mage.Sets/src/mage/cards/f/FlourishingBloomKin.java
@@ -9,7 +9,7 @@ import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.constants.Duration;
@@ -56,7 +56,7 @@ public final class FlourishingBloomKin extends CardImpl {
// When Flourishing Bloom-Kin is turned face up, search your library for up to two Forest cards and reveal them.
// Put one of them onto the battlefield tapped and the other into your hand, then shuffle.
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(
- new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 2, filterForestCards))
+ new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 2, filterForestCards))
.setText("search your library for up to two Forest cards and reveal them. Put one of them onto the battlefield tapped and the other into your hand, then shuffle")));
}
diff --git a/Mage.Sets/src/mage/cards/k/KodamasReach.java b/Mage.Sets/src/mage/cards/k/KodamasReach.java
index c7544159381..79f14925c3d 100644
--- a/Mage.Sets/src/mage/cards/k/KodamasReach.java
+++ b/Mage.Sets/src/mage/cards/k/KodamasReach.java
@@ -1,6 +1,6 @@
package mage.cards.k;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.SubType;
@@ -19,7 +19,7 @@ public final class KodamasReach extends CardImpl {
this.subtype.add(SubType.ARCANE);
// Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.
- this.getSpellAbility().addEffect(new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(
+ this.getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS)));
}
diff --git a/Mage.Sets/src/mage/cards/n/NavigationOrb.java b/Mage.Sets/src/mage/cards/n/NavigationOrb.java
index 799b476eba3..57eab146ae4 100644
--- a/Mage.Sets/src/mage/cards/n/NavigationOrb.java
+++ b/Mage.Sets/src/mage/cards/n/NavigationOrb.java
@@ -5,7 +5,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterCard;
@@ -32,7 +32,7 @@ public final class NavigationOrb extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {2}, {T}, Sacrifice Navigation Orb: Search your library for up to two basic land cards and/or Gate cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.
- Ability ability = new SimpleActivatedAbility(new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(
+ Ability ability = new SimpleActivatedAbility(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
new TargetCardInLibrary(0, 2, filter)), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
diff --git a/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java b/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java
index 1938a494e79..a1bdc5302ca 100644
--- a/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java
+++ b/Mage.Sets/src/mage/cards/n/NissasPilgrimage.java
@@ -4,7 +4,7 @@ package mage.cards.n;
import java.util.UUID;
import mage.abilities.condition.common.SpellMasteryCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -32,8 +32,8 @@ public final class NissasPilgrimage extends CardImpl {
// Search your library for up to two basic Forest cards, reveal those cards, and put one onto the battlefield tapped and the rest into your hand. Then shuffle.
// Spell Mastery — If there are two or more instant and/or sorcery cards in your graveyard, search your library for up to three basic Forest cards instead of two.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 3, filter)),
- new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 2, filter)),
+ new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 3, filter)),
+ new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(new TargetCardInLibrary(0, 2, filter)),
SpellMasteryCondition.instance,
"Search your library for up to two basic Forest cards, reveal those cards, and put one onto the battlefield tapped and the rest into your hand. Then shuffle."
+ "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, search your library for up to three basic Forest cards instead of two."));
diff --git a/Mage.Sets/src/mage/cards/p/Peregrination.java b/Mage.Sets/src/mage/cards/p/Peregrination.java
index 8795a057aa0..6c28c14090d 100644
--- a/Mage.Sets/src/mage/cards/p/Peregrination.java
+++ b/Mage.Sets/src/mage/cards/p/Peregrination.java
@@ -1,7 +1,7 @@
package mage.cards.p;
import mage.abilities.effects.Effect;
-import mage.abilities.effects.common.search.SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.*;
import mage.constants.CardType;
@@ -19,7 +19,7 @@ public final class Peregrination extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Search your library for up to two basic land cards, reveal those cards, and put one onto the battlefield tapped and the other into your hand. Shuffle, then scry 1.
- this.getSpellAbility().addEffect(new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(
+ this.getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS))
.setText("search your library for up to two basic land cards, reveal those cards, and put one onto the battlefield tapped and the other into your hand. Shuffle"));
Effect effect = new ScryEffect(1);
diff --git a/Mage.Sets/src/mage/cards/v/ViewpointSynchronization.java b/Mage.Sets/src/mage/cards/v/ViewpointSynchronization.java
new file mode 100644
index 00000000000..ac35df8e58d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/v/ViewpointSynchronization.java
@@ -0,0 +1,32 @@
+package mage.cards.v;
+
+import mage.abilities.effects.common.search.SearchLibraryPutOntoBattlefieldTappedRestInHandEffect;
+import mage.abilities.keyword.FreerunningAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.StaticFilters;
+import mage.target.common.TargetCardInLibrary;
+
+import java.util.UUID;
+
+public class ViewpointSynchronization extends CardImpl {
+ public ViewpointSynchronization(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}");
+
+ this.addAbility(new FreerunningAbility("{2}{G}"));
+
+ // Search your library for up to three basic land cards and reveal them. Put two of them onto the battlefield tapped and the other in your hand, then shuffle.
+ this.getSpellAbility().addEffect(new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(
+ new TargetCardInLibrary(0, 3, StaticFilters.FILTER_CARD_BASIC_LANDS), 2));
+ }
+
+ public ViewpointSynchronization(ViewpointSynchronization card) {
+ super(card);
+ }
+
+ @Override
+ public ViewpointSynchronization copy() {
+ return new ViewpointSynchronization(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/AssassinsCreed.java b/Mage.Sets/src/mage/sets/AssassinsCreed.java
index 2dcb67a87d1..f4eb6fffbea 100644
--- a/Mage.Sets/src/mage/sets/AssassinsCreed.java
+++ b/Mage.Sets/src/mage/sets/AssassinsCreed.java
@@ -321,8 +321,8 @@ public final class AssassinsCreed extends ExpansionSet {
cards.add(new SetCardInfo("Towering Viewpoint", 263, Rarity.UNCOMMON, mage.cards.t.ToweringViewpoint.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Towering Viewpoint", 77, Rarity.UNCOMMON, mage.cards.t.ToweringViewpoint.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tranquilize", 284, Rarity.COMMON, mage.cards.t.Tranquilize.class));
- //cards.add(new SetCardInfo("Viewpoint Synchronization", 223, Rarity.UNCOMMON, mage.cards.v.ViewpointSynchronization.class, NON_FULL_USE_VARIOUS));
- //cards.add(new SetCardInfo("Viewpoint Synchronization", 43, Rarity.UNCOMMON, mage.cards.v.ViewpointSynchronization.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Viewpoint Synchronization", 223, Rarity.UNCOMMON, mage.cards.v.ViewpointSynchronization.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Viewpoint Synchronization", 43, Rarity.UNCOMMON, mage.cards.v.ViewpointSynchronization.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Waterlogged Grove", 116, Rarity.RARE, mage.cards.w.WaterloggedGrove.class));
//cards.add(new SetCardInfo("What Must Be Done", 11, Rarity.RARE, mage.cards.w.WhatMustBeDone.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("What Must Be Done", 157, Rarity.RARE, mage.cards.w.WhatMustBeDone.class, NON_FULL_USE_VARIOUS));
diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOntoBattlefieldTappedRestInHandEffect.java
similarity index 53%
rename from Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect.java
rename to Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOntoBattlefieldTappedRestInHandEffect.java
index ab7e06d9e6e..3788fb5c54b 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryPutOntoBattlefieldTappedRestInHandEffect.java
@@ -12,27 +12,37 @@ import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
+import mage.util.CardUtil;
/**
* @author BetaSteward_at_googlemail.com, edited by Cguy7777
*/
-public class SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect extends SearchEffect {
+public class SearchLibraryPutOntoBattlefieldTappedRestInHandEffect extends SearchEffect {
- private static final FilterCard filter = new FilterCard("card to put on the battlefield tapped");
+ private final FilterCard filter;
+ private final int numToBattlefield;
- public SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(TargetCardInLibrary target) {
+ public SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(TargetCardInLibrary target, int numToBattlefield) {
super(target, Outcome.PutLandInPlay);
staticText = "search your library for " + target.getDescription() +
- ", reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle";
+ ", reveal those cards, put " + CardUtil.numberToText(numToBattlefield) + " onto the battlefield tapped and the other into your hand, then shuffle";
+ this.filter = new FilterCard((numToBattlefield > 1 ? "cards" : "card") + "to put on the battlefield tapped");
+ this.numToBattlefield = numToBattlefield;
}
- protected SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(final SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect effect) {
+ public SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(TargetCardInLibrary target) {
+ this(target, 1);
+ }
+
+ protected SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(final SearchLibraryPutOntoBattlefieldTappedRestInHandEffect effect) {
super(effect);
+ this.filter = effect.filter.copy();
+ this.numToBattlefield = effect.numToBattlefield;
}
@Override
- public SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect copy() {
- return new SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect(this);
+ public SearchLibraryPutOntoBattlefieldTappedRestInHandEffect copy() {
+ return new SearchLibraryPutOntoBattlefieldTappedRestInHandEffect(this);
}
@Override
@@ -49,14 +59,15 @@ public class SearchLibraryPutOneOntoBattlefieldTappedRestInHandEffect extends Se
controller.revealCards(sourceObject.getIdName(), revealed, game);
if (target.getTargets().size() >= 2) {
- TargetCardInLibrary targetCardToBattlefield = new TargetCardInLibrary(filter);
- controller.choose(Outcome.PutLandInPlay, revealed, targetCardToBattlefield, source, game);
+ int maxToBattlefield = Math.min(numToBattlefield, target.getTargets().size());
+ TargetCardInLibrary targetCardsToBattlefield = new TargetCardInLibrary(maxToBattlefield, filter);
+ controller.choose(Outcome.PutLandInPlay, revealed, targetCardsToBattlefield, source, game);
- Card cardToBattlefield = revealed.get(targetCardToBattlefield.getFirstTarget(), game);
+ Cards cardsToBattlefield = new CardsImpl(targetCardsToBattlefield.getTargets());
Cards cardsToHand = new CardsImpl(revealed);
- if (cardToBattlefield != null) {
- controller.moveCards(cardToBattlefield, Zone.BATTLEFIELD, source, game, true, false, false, null);
- cardsToHand.remove(cardToBattlefield);
+ if (!cardsToBattlefield.isEmpty()) {
+ controller.moveCards(cardsToBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, true, false, false, null);
+ cardsToHand.removeAll(cardsToBattlefield);
}
controller.moveCardsToHandWithInfo(cardsToHand, source, game, true);