From 70ffc77a5b03a8bd4235303a7e4fb6648c89ff13 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 14 Nov 2025 10:27:59 -0500 Subject: [PATCH] [TLA] Implement Elemental Teachings --- .../src/mage/cards/e/ElementalTeachings.java | 37 ++++++++ Mage.Sets/src/mage/cards/g/GiftsUngiven.java | 73 ++------------- .../src/mage/cards/r/RealmsUncharted.java | 79 ++-------------- .../src/mage/sets/AvatarTheLastAirbender.java | 2 + ...rchLibraryForFourDifferentCardsEffect.java | 92 +++++++++++++++++++ 5 files changed, 143 insertions(+), 140 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/e/ElementalTeachings.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryForFourDifferentCardsEffect.java diff --git a/Mage.Sets/src/mage/cards/e/ElementalTeachings.java b/Mage.Sets/src/mage/cards/e/ElementalTeachings.java new file mode 100644 index 00000000000..b4c1fb32884 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElementalTeachings.java @@ -0,0 +1,37 @@ +package mage.cards.e; + +import mage.abilities.effects.common.search.SearchLibraryForFourDifferentCardsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PutCards; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ElementalTeachings extends CardImpl { + + public ElementalTeachings(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{G}"); + + this.subtype.add(SubType.LESSON); + + // Search your library for up to four land cards with different names and reveal them. An opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest onto the battlefield tapped, then shuffle. + this.getSpellAbility().addEffect(new SearchLibraryForFourDifferentCardsEffect( + StaticFilters.FILTER_CARD_LANDS, PutCards.BATTLEFIELD_TAPPED, false + )); + } + + private ElementalTeachings(final ElementalTeachings card) { + super(card); + } + + @Override + public ElementalTeachings copy() { + return new ElementalTeachings(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GiftsUngiven.java b/Mage.Sets/src/mage/cards/g/GiftsUngiven.java index 88b3ff747e2..a50cad504ac 100644 --- a/Mage.Sets/src/mage/cards/g/GiftsUngiven.java +++ b/Mage.Sets/src/mage/cards/g/GiftsUngiven.java @@ -1,20 +1,11 @@ package mage.cards.g; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryForFourDifferentCardsEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetCardWithDifferentNameInLibrary; +import mage.constants.PutCards; +import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; import java.util.UUID; @@ -28,7 +19,9 @@ public final class GiftsUngiven extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); // Search your library for up to four cards with different names and reveal them. Target opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest into your hand. Then shuffle your library. - this.getSpellAbility().addEffect(new GiftsUngivenEffect()); + this.getSpellAbility().addEffect(new SearchLibraryForFourDifferentCardsEffect( + StaticFilters.FILTER_CARD_CARDS, PutCards.HAND, true + )); this.getSpellAbility().addTarget(new TargetOpponent()); } @@ -41,57 +34,3 @@ public final class GiftsUngiven extends CardImpl { return new GiftsUngiven(this); } } - -class GiftsUngivenEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCard("cards with different names"); - private static final FilterCard filter2 = new FilterCard("cards to put in graveyard"); - - public GiftsUngivenEffect() { - super(Outcome.DrawCard); - this.staticText = "Search your library for up to four cards with different names and reveal them. " + - "Target opponent chooses two of those cards. Put the chosen cards into your graveyard " + - "and the rest into your hand. Then shuffle"; - } - - private GiftsUngivenEffect(final GiftsUngivenEffect effect) { - super(effect); - } - - @Override - public GiftsUngivenEffect copy() { - return new GiftsUngivenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); - if (player == null || opponent == null) { - return false; - } - TargetCardInLibrary target = new TargetCardWithDifferentNameInLibrary(0, 4, filter); - player.searchLibrary(target, source, game); - Cards cards = new CardsImpl(target.getTargets()); - cards.retainZone(Zone.LIBRARY, game); - if (cards.isEmpty()) { - player.shuffleLibrary(source, game); - } - player.revealCards(source, cards, game); - - if (cards.size() > 2) { - Cards cardsToKeep = new CardsImpl(); - cardsToKeep.addAll(cards); - TargetCard targetDiscard = new TargetCard(2, Zone.LIBRARY, filter2); - if (opponent.choose(Outcome.Discard, cards, targetDiscard, source, game)) { - cardsToKeep.removeIf(targetDiscard.getTargets()::contains); - cards.removeAll(cardsToKeep); - } - player.moveCards(cardsToKeep, Zone.HAND, source, game); - } - - player.moveCards(cards, Zone.GRAVEYARD, source, game); - player.shuffleLibrary(source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RealmsUncharted.java b/Mage.Sets/src/mage/cards/r/RealmsUncharted.java index 2b7e09fafd6..309c2e9b903 100644 --- a/Mage.Sets/src/mage/cards/r/RealmsUncharted.java +++ b/Mage.Sets/src/mage/cards/r/RealmsUncharted.java @@ -1,22 +1,11 @@ package mage.cards.r; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryForFourDifferentCardsEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.common.FilterLandCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetCardWithDifferentNameInLibrary; -import mage.target.common.TargetOpponent; +import mage.constants.PutCards; +import mage.filter.StaticFilters; import java.util.UUID; @@ -29,7 +18,9 @@ public final class RealmsUncharted extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); // Search your library for four land cards with different names and reveal them. An opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest into your hand. Then shuffle your library. - this.getSpellAbility().addEffect(new RealmsUnchartedEffect()); + this.getSpellAbility().addEffect(new SearchLibraryForFourDifferentCardsEffect( + StaticFilters.FILTER_CARD_LANDS, PutCards.HAND, false + )); } private RealmsUncharted(final RealmsUncharted card) { @@ -41,61 +32,3 @@ public final class RealmsUncharted extends CardImpl { return new RealmsUncharted(this); } } - -class RealmsUnchartedEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterLandCard("land cards with different names"); - private static final FilterCard filter2 = new FilterCard("cards to put in graveyard"); - - public RealmsUnchartedEffect() { - super(Outcome.DrawCard); - this.staticText = "Search your library for up to four land cards with different names and reveal them. " + - "An opponent chooses two of those cards. Put the chosen cards into your graveyard " + - "and the rest into your hand. Then shuffle"; - } - - private RealmsUnchartedEffect(final RealmsUnchartedEffect effect) { - super(effect); - } - - @Override - public RealmsUnchartedEffect copy() { - return new RealmsUnchartedEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - TargetCardInLibrary targetCards = new TargetCardWithDifferentNameInLibrary(0, 4, filter); - player.searchLibrary(targetCards, source, game); - Cards cards = new CardsImpl(targetCards.getTargets()); - cards.retainZone(Zone.LIBRARY, game); - if (cards.isEmpty()) { - player.shuffleLibrary(source, game); - } - player.revealCards(source, cards, game); - - if (cards.size() > 2) { - TargetOpponent targetOpponent = new TargetOpponent(); - targetOpponent.withNotTarget(true); - player.choose(outcome, targetOpponent, source, game); - Player opponent = game.getPlayer(targetOpponent.getFirstTarget()); - if (opponent != null) { - Cards cardsToKeep = new CardsImpl(cards); - TargetCard targetDiscard = new TargetCard(2, Zone.LIBRARY, filter2); - if (opponent.choose(Outcome.Discard, cards, targetDiscard, source, game)) { - cardsToKeep.removeIf(targetDiscard.getTargets()::contains); - cards.removeAll(cardsToKeep); - } - player.moveCards(cardsToKeep, Zone.HAND, source, game); - } - } - - player.moveCards(cards, Zone.GRAVEYARD, source, game); - player.shuffleLibrary(source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 08950b1fb44..129d6eb50a2 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -132,6 +132,8 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Earthbending Lesson", 176, Rarity.COMMON, mage.cards.e.EarthbendingLesson.class)); cards.add(new SetCardInfo("Earthen Ally", 177, Rarity.RARE, mage.cards.e.EarthenAlly.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Earthen Ally", 377, Rarity.RARE, mage.cards.e.EarthenAlly.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elemental Teachings", 178, Rarity.RARE, mage.cards.e.ElementalTeachings.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Elemental Teachings", 378, Rarity.RARE, mage.cards.e.ElementalTeachings.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ember Island Production", 48, Rarity.UNCOMMON, mage.cards.e.EmberIslandProduction.class)); cards.add(new SetCardInfo("Energybending", 2, Rarity.UNCOMMON, mage.cards.e.Energybending.class)); cards.add(new SetCardInfo("Enter the Avatar State", 18, Rarity.UNCOMMON, mage.cards.e.EnterTheAvatarState.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryForFourDifferentCardsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryForFourDifferentCardsEffect.java new file mode 100644 index 00000000000..c49f7ff6225 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchLibraryForFourDifferentCardsEffect.java @@ -0,0 +1,92 @@ +package mage.abilities.effects.common.search; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.constants.PutCards; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCardWithDifferentNameInLibrary; +import mage.target.common.TargetOpponent; + +/** + * @author TheElk801 + */ +public class SearchLibraryForFourDifferentCardsEffect extends OneShotEffect { + + private final FilterCard filter; + private final PutCards putCards; + private final boolean useTargetPointer; + private static final FilterCard filter2 = new FilterCard("cards to put in graveyard"); + + public SearchLibraryForFourDifferentCardsEffect(FilterCard filter, PutCards putCards, boolean useTargetPointer) { + super(Outcome.Benefit); + this.filter = filter; + this.putCards = putCards; + this.useTargetPointer = useTargetPointer; + staticText = "search your library for up to four " + filter + + " with different names and reveal them. " + (useTargetPointer ? "Target" : "An") + + " opponent chooses two of those cards. Put the chosen cards into your graveyard and the rest " + + putCards.getMessage(false, false) + ", then shuffle"; + } + + private SearchLibraryForFourDifferentCardsEffect(final SearchLibraryForFourDifferentCardsEffect effect) { + super(effect); + this.filter = effect.filter; + this.putCards = effect.putCards; + this.useTargetPointer = effect.useTargetPointer; + } + + @Override + public SearchLibraryForFourDifferentCardsEffect copy() { + return new SearchLibraryForFourDifferentCardsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetCardInLibrary targetCards = new TargetCardWithDifferentNameInLibrary(0, 4, filter); + player.searchLibrary(targetCards, source, game); + Cards cards = new CardsImpl(targetCards.getTargets()); + cards.retainZone(Zone.LIBRARY, game); + player.revealCards(source, cards, game); + if (cards.isEmpty()) { + player.shuffleLibrary(source, game); + return true; + } + + Cards toGrave = new CardsImpl(); + if (cards.size() > 2) { + Player opponent; + if (useTargetPointer) { + opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + } else { + TargetPlayer target = new TargetOpponent(true); + player.choose(outcome, target, source, game); + opponent = game.getPlayer(target.getFirstTarget()); + } + if (opponent != null) { + TargetCard targetDiscard = new TargetCard(2, Zone.LIBRARY, filter2); + opponent.choose(Outcome.Discard, cards, targetDiscard, source, game); + toGrave.addAll(targetDiscard.getTargets()); + } + } else { + toGrave.addAll(cards); + } + cards.removeAll(toGrave); + player.moveCards(toGrave, Zone.GRAVEYARD, source, game); + putCards.moveCards(player, cards, source, game); + player.shuffleLibrary(source, game); + return true; + } +}