From 15d389a5ba53dfca68e5d5b989dce14f16e6aeb2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 13 Apr 2019 12:01:31 -0400 Subject: [PATCH] Implemented Tamiyo, Collector of Tales --- .../mage/cards/t/TamiyoCollectorOfTales.java | 157 ++++++++++++++++++ Mage.Sets/src/mage/sets/WarOfTheSpark.java | 1 + .../effects/common/ChooseACardNameEffect.java | 5 +- 3 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java diff --git a/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java b/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java new file mode 100644 index 00000000000..b2352caa2ec --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TamiyoCollectorOfTales.java @@ -0,0 +1,157 @@ +package mage.cards.t; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.*; +import mage.cards.repository.CardRepository; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.PermanentCard; +import mage.game.stack.Spell; +import mage.game.stack.StackAbility; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +import static mage.constants.Outcome.Benefit; + +/** + * @author TheElk801 + */ +public final class TamiyoCollectorOfTales extends CardImpl { + + public TamiyoCollectorOfTales(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.TAMIYO); + this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5)); + + // Spells and abilities your opponents control can't cause you to discard cards or sacrifice permanents. + this.addAbility(new SimpleStaticAbility(new TamiyoCollectorOfTalesRuleEffect())); + + // +1: Choose a nonland card name, then reveal the top four cards of your library. Put all cards with the chosen name from among them into your hand and the rest into your graveyard. + this.addAbility(new LoyaltyAbility(new TamiyoCollectorOfTalesEffect(), 1)); + + // -3: Return target card from your graveyard to your hand. + Ability ability = new LoyaltyAbility(new ReturnToHandTargetEffect(), -3); + ability.addTarget(new TargetCardInYourGraveyard()); + this.addAbility(ability); + } + + private TamiyoCollectorOfTales(final TamiyoCollectorOfTales card) { + super(card); + } + + @Override + public TamiyoCollectorOfTales copy() { + return new TamiyoCollectorOfTales(this); + } +} + +class TamiyoCollectorOfTalesRuleEffect extends ContinuousRuleModifyingEffectImpl { + + TamiyoCollectorOfTalesRuleEffect() { + super(Duration.WhileOnBattlefield, Benefit); + staticText = "Spells and abilities your opponents control can't " + + "cause you to discard cards or sacrifice permanents"; + } + + private TamiyoCollectorOfTalesRuleEffect(final TamiyoCollectorOfTalesRuleEffect effect) { + super(effect); + } + + @Override + public TamiyoCollectorOfTalesRuleEffect copy() { + return new TamiyoCollectorOfTalesRuleEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SACRIFICE_PERMANENT + || event.getType() == GameEvent.EventType.DISCARD_CARD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getPlayerId().equals(source.getControllerId())) { + MageObject object = game.getObject(event.getSourceId()); + if (object instanceof PermanentCard) { + if (game.getOpponents(source.getControllerId()).contains(((PermanentCard) object).getControllerId())) { + return true; + } + } + if (object instanceof Spell) { + if (game.getOpponents(source.getControllerId()).contains(((Spell) object).getControllerId())) { + return true; + } + } + if (object instanceof Card) { + if (game.getOpponents(source.getControllerId()).contains(((Card) object).getOwnerId())) { + return true; + } + } + if (object instanceof StackAbility) { + if (game.getOpponents(source.getControllerId()).contains(((StackAbility) object).getControllerId())) { + return true; + } + } + } + return false; + } +} + +class TamiyoCollectorOfTalesEffect extends OneShotEffect { + + TamiyoCollectorOfTalesEffect() { + super(Outcome.Benefit); + staticText = "Choose a nonland card name, then reveal the top four cards of your library. " + + "Put all cards with the chosen name from among them into your hand and the rest into your graveyard."; + } + + private TamiyoCollectorOfTalesEffect(final TamiyoCollectorOfTalesEffect effect) { + super(effect); + } + + @Override + public TamiyoCollectorOfTalesEffect copy() { + return new TamiyoCollectorOfTalesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Choice choice = new ChoiceImpl(); + choice.setChoices(CardRepository.instance.getNonLandNames()); + choice.setMessage("Choose a nonland card name"); + if (!player.choose(outcome, choice, game)) { + return false; + } + game.informPlayers(source.getSourceObject(game).getLogName() + ", chosen name: [" + choice.getChoice() + ']'); + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4)); + Cards cards2 = new CardsImpl(); + player.revealCards(source, cards, game); + for (Card card : cards.getCards(game)) { + if (card.getName().equals(choice.getChoice())) { + cards2.add(card); + } + } + cards.removeAll(cards2); + player.moveCards(cards, Zone.GRAVEYARD, source, game); + player.moveCards(cards2, Zone.HAND, source, game); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/WarOfTheSpark.java b/Mage.Sets/src/mage/sets/WarOfTheSpark.java index 6e1026bcd07..91df13df271 100644 --- a/Mage.Sets/src/mage/sets/WarOfTheSpark.java +++ b/Mage.Sets/src/mage/sets/WarOfTheSpark.java @@ -183,6 +183,7 @@ public final class WarOfTheSpark extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 257, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 258, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tamiyo's Epiphany", 71, Rarity.COMMON, mage.cards.t.TamiyosEpiphany.class)); + cards.add(new SetCardInfo("Tamiyo, Collector of Tales", 220, Rarity.RARE, mage.cards.t.TamiyoCollectorOfTales.class)); cards.add(new SetCardInfo("Teferi, Time Raveler", 221, Rarity.RARE, mage.cards.t.TeferiTimeRaveler.class)); cards.add(new SetCardInfo("Tenth District Legionnaire", 222, Rarity.UNCOMMON, mage.cards.t.TenthDistrictLegionnaire.class)); cards.add(new SetCardInfo("Teyo's Lightshield", 33, Rarity.COMMON, mage.cards.t.TeyosLightshield.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ChooseACardNameEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ChooseACardNameEffect.java index 86edae8d1f2..79aea129afc 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ChooseACardNameEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ChooseACardNameEffect.java @@ -13,7 +13,6 @@ import mage.players.Player; import mage.util.CardUtil; /** - * * @author LevelX2 */ public class ChooseACardNameEffect extends OneShotEffect { @@ -92,11 +91,11 @@ public class ChooseACardNameEffect extends OneShotEffect { if (controller.choose(Outcome.Detriment, cardChoice, game)) { String cardName = cardChoice.getChoice(); if (!game.isSimulation()) { - game.informPlayers(sourceObject.getLogName() + ", named card: [" + cardName + ']'); + game.informPlayers(sourceObject.getLogName() + ", chosen name: [" + cardName + ']'); } game.getState().setValue(source.getSourceId().toString() + INFO_KEY, cardName); if (sourceObject instanceof Permanent) { - ((Permanent) sourceObject).addInfo(INFO_KEY, CardUtil.addToolTipMarkTags("Named card: " + cardName), game); + ((Permanent) sourceObject).addInfo(INFO_KEY, CardUtil.addToolTipMarkTags("Chosen name: " + cardName), game); } return true; }