From 832ebf00964d084aef9da4d048b35b8c80a3c4a9 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Wed, 19 Nov 2025 09:31:53 -0500 Subject: [PATCH] [TLE] Implement Wan Shi Tong, All-Knowing --- .../mage/cards/d/DutifulKnowledgeSeeker.java | 50 ++-------------- .../mage/cards/w/WanShiTongAllKnowing.java | 54 +++++++++++++++++ .../sets/AvatarTheLastAirbenderEternal.java | 2 + ...tIntoLibraryOneOrMoreTriggeredAbility.java | 60 +++++++++++++++++++ 4 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/w/WanShiTongAllKnowing.java create mode 100644 Mage/src/main/java/mage/abilities/common/PutIntoLibraryOneOrMoreTriggeredAbility.java diff --git a/Mage.Sets/src/mage/cards/d/DutifulKnowledgeSeeker.java b/Mage.Sets/src/mage/cards/d/DutifulKnowledgeSeeker.java index 1b188ac2554..ce5ff3fb41c 100644 --- a/Mage.Sets/src/mage/cards/d/DutifulKnowledgeSeeker.java +++ b/Mage.Sets/src/mage/cards/d/DutifulKnowledgeSeeker.java @@ -2,8 +2,7 @@ package mage.cards.d; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.BatchTriggeredAbility; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.PutIntoGraveFromAnywhereSourceTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.PutOnLibraryTargetEffect; @@ -12,15 +11,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeBatchEvent; -import mage.game.events.ZoneChangeEvent; import mage.target.common.TargetCardInGraveyard; -import java.util.Objects; import java.util.UUID; /** @@ -37,7 +30,9 @@ public final class DutifulKnowledgeSeeker extends CardImpl { this.toughness = new MageInt(2); // Whenever one or more cards are put into a library from anywhere, put a +1/+1 counter on this creature. - this.addAbility(new DutifulKnowledgeSeekerTriggeredAbility()); + this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + )); // {3}: Put target card from a graveyard on the bottom of its owner's library. Ability ability = new SimpleActivatedAbility(new PutOnLibraryTargetEffect(false), new GenericManaCost(3)); @@ -54,40 +49,3 @@ public final class DutifulKnowledgeSeeker extends CardImpl { return new DutifulKnowledgeSeeker(this); } } - -class DutifulKnowledgeSeekerTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { - - DutifulKnowledgeSeekerTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance())); - this.setTriggerPhrase("Whenever one or more cards are put into a library from anywhere, "); - } - - private DutifulKnowledgeSeekerTriggeredAbility(final DutifulKnowledgeSeekerTriggeredAbility ability) { - super(ability); - } - - @Override - public DutifulKnowledgeSeekerTriggeredAbility copy() { - return new DutifulKnowledgeSeekerTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; - } - - @Override - public boolean checkEvent(ZoneChangeEvent event, Game game) { - return Zone.LIBRARY.match(event.getToZone()); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return this - .getFilteredEvents((ZoneChangeBatchEvent) event, game) - .stream() - .map(GameEvent::getTargetId) - .map(game::getCard) - .anyMatch(Objects::nonNull); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WanShiTongAllKnowing.java b/Mage.Sets/src/mage/cards/w/WanShiTongAllKnowing.java new file mode 100644 index 00000000000..b815237b611 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WanShiTongAllKnowing.java @@ -0,0 +1,54 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.PutIntoLibraryOneOrMoreTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.permanent.token.SpiritWorldToken; +import mage.target.common.TargetNonlandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WanShiTongAllKnowing extends CardImpl { + + public WanShiTongAllKnowing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Wan Shi Tong enters, target nonland permanent's owner puts it into their library second from the top or on the bottom. + Ability ability = new EntersBattlefieldTriggeredAbility(new PutOnTopOrBottomLibraryTargetEffect(2, false)); + ability.addTarget(new TargetNonlandPermanent()); + this.addAbility(ability); + + // Whenever one or more cards are put into a library from anywhere, create two 1/1 colorless Spirit creature tokens with "This token can't block or be blocked by non-Spirit creatures." + this.addAbility(new PutIntoLibraryOneOrMoreTriggeredAbility(new CreateTokenEffect(new SpiritWorldToken(), 2))); + } + + private WanShiTongAllKnowing(final WanShiTongAllKnowing card) { + super(card); + } + + @Override + public WanShiTongAllKnowing copy() { + return new WanShiTongAllKnowing(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index 53fd88a4b96..63b728a7f6d 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -304,6 +304,8 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Valorous Stance", 154, Rarity.UNCOMMON, mage.cards.v.ValorousStance.class)); cards.add(new SetCardInfo("Visions of Beyond", 21, Rarity.MYTHIC, mage.cards.v.VisionsOfBeyond.class)); cards.add(new SetCardInfo("Volcanic Torrent", 37, Rarity.MYTHIC, mage.cards.v.VolcanicTorrent.class)); + cards.add(new SetCardInfo("Wan Shi Tong, All-Knowing", 182, Rarity.MYTHIC, mage.cards.w.WanShiTongAllKnowing.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Wan Shi Tong, All-Knowing", 98, Rarity.MYTHIC, mage.cards.w.WanShiTongAllKnowing.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Warship Scout", 244, Rarity.COMMON, mage.cards.w.WarshipScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Warship Scout", 285, Rarity.COMMON, mage.cards.w.WarshipScout.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Warstorm Surge", 38, Rarity.MYTHIC, mage.cards.w.WarstormSurge.class)); diff --git a/Mage/src/main/java/mage/abilities/common/PutIntoLibraryOneOrMoreTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/PutIntoLibraryOneOrMoreTriggeredAbility.java new file mode 100644 index 00000000000..072eb4ba031 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/PutIntoLibraryOneOrMoreTriggeredAbility.java @@ -0,0 +1,60 @@ +package mage.abilities.common; + +import mage.abilities.BatchTriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeBatchEvent; +import mage.game.events.ZoneChangeEvent; + +import java.util.Objects; + +/** + * @author TheElk801 + */ +public class PutIntoLibraryOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { + + public PutIntoLibraryOneOrMoreTriggeredAbility(Effect effect) { + this(effect, false); + } + + public PutIntoLibraryOneOrMoreTriggeredAbility(Effect effect, boolean optional) { + this(Zone.BATTLEFIELD, effect, optional); + } + + public PutIntoLibraryOneOrMoreTriggeredAbility(Zone zone, Effect effect, boolean optional) { + super(zone, effect, optional); + this.setTriggerPhrase("Whenever one or more cards are put into a library from anywhere, "); + } + + private PutIntoLibraryOneOrMoreTriggeredAbility(final PutIntoLibraryOneOrMoreTriggeredAbility ability) { + super(ability); + } + + @Override + public PutIntoLibraryOneOrMoreTriggeredAbility copy() { + return new PutIntoLibraryOneOrMoreTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE_BATCH; + } + + @Override + public boolean checkEvent(ZoneChangeEvent event, Game game) { + return Zone.LIBRARY.match(event.getToZone()); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return this + .getFilteredEvents((ZoneChangeBatchEvent) event, game) + .stream() + .map(GameEvent::getTargetId) + .map(game::getCard) + .anyMatch(Objects::nonNull); + } +}