diff --git a/Mage.Sets/src/mage/cards/i/IntrudeOnTheMind.java b/Mage.Sets/src/mage/cards/i/IntrudeOnTheMind.java new file mode 100644 index 000000000000..bf55022d1409 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IntrudeOnTheMind.java @@ -0,0 +1,161 @@ +package mage.cards.i; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +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.counters.CounterType; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Thopter00ColorlessToken; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; + +/** + * + * @author DominionSpy + */ +public final class IntrudeOnTheMind extends CardImpl { + + public IntrudeOnTheMind(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}"); + + // Reveal the top five cards of your library and separate them into two piles. An opponent chooses one of those piles. Put that pile into your hand and the other into your graveyard. + // Create a 0/0 colorless Thopter artifact creature token with flying, then put a +1/+1 counter on it for each card put into your graveyard this way. + this.getSpellAbility().addEffect(new IntrudeOnTheMindEffect()); + } + + private IntrudeOnTheMind(final IntrudeOnTheMind card) { + super(card); + } + + @Override + public IntrudeOnTheMind copy() { + return new IntrudeOnTheMind(this); + } +} + +class IntrudeOnTheMindEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("cards to put in the first pile"); + + IntrudeOnTheMindEffect() { + super(Outcome.DrawCard); + staticText = "Reveal the top five cards of your library and separate them into two piles. " + + "An opponent chooses one of those piles. Put that pile into your hand and the other into your graveyard. " + + "Create a 0/0 colorless Thopter artifact creature token with flying, " + + "then put a +1/+1 counter on it for each card put into your graveyard this way."; + } + + private IntrudeOnTheMindEffect(final IntrudeOnTheMindEffect effect) { + super(effect); + } + + @Override + public IntrudeOnTheMindEffect copy() { + return new IntrudeOnTheMindEffect(this); + } + + /** + * Pile-choosing logic based on {@link mage.abilities.effects.common.RevealAndSeparatePilesEffect}. + */ + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + + Cards allCards = new CardsImpl(controller.getLibrary().getTopCards(game, 5)); + Cards cards = allCards.copy(); + controller.revealCards(source, cards, game); + + TargetCard target = new TargetCard(0, cards.size(), Zone.LIBRARY, filter); + List pile1 = new ArrayList<>(); + controller.choose(Outcome.Neutral, cards, target, source, game); + target.getTargets() + .stream() + .map(game::getCard) + .filter(Objects::nonNull) + .forEach(pile1::add); + cards.removeIf(target.getTargets()::contains); + List pile2 = new ArrayList<>(); + pile2.addAll(cards.getCards(game)); + + Player opponent = getOpponent(controller, game, source); + if (opponent == null) { + return false; + } + boolean choice = opponent.choosePile(outcome, "Choose a pile to put into hand.", pile1, pile2, game); + + Zone pile1Zone = choice ? Zone.HAND : Zone.GRAVEYARD; + Zone pile2Zone = choice ? Zone.GRAVEYARD : Zone.HAND; + + game.informPlayers("Pile 1, going to " + pile1Zone + ": " + (pile1.isEmpty() ? " (none)" : + pile1.stream().map(MageObject::getName).collect(Collectors.joining(", ")))); + cards.clear(); + cards.addAllCards(pile1); + controller.moveCards(cards, pile1Zone, source, game); + + game.informPlayers("Pile 2, going to " + pile2Zone + ": " + (pile2.isEmpty() ? " (none)" : + pile2.stream().map(MageObject::getName).collect(Collectors.joining(", ")))); + cards.clear(); + cards.addAllCards(pile2); + controller.moveCards(cards, pile2Zone, source, game); + + Token token = new Thopter00ColorlessToken(); + token.putOntoBattlefield(1, game, source); + + allCards.retainZone(Zone.GRAVEYARD, game); + int count = allCards.size(); + if (count <= 0) { + return true; + } + for (UUID tokenId : token.getLastAddedTokenIds()) { + Permanent permanent = game.getPermanent(tokenId); + if (permanent == null) { + continue; + } + permanent.addCounters(CounterType.P1P1.createInstance(count), source.getControllerId(), source, game); + } + return true; + } + + private static Player getOpponent(Player controller, Game game, Ability source) { + Player opponent; + Set opponents = game.getOpponents(source.getControllerId()); + if (opponents.isEmpty()) { + return null; + } + if (opponents.size() == 1) { + opponent = game.getPlayer(opponents.iterator().next()); + } else { + Target targetOpponent = new TargetOpponent(true); + controller.chooseTarget(Outcome.Neutral, targetOpponent, source, game); + opponent = game.getPlayer(targetOpponent.getFirstTarget()); + if (opponent == null) { + return null; + } + game.informPlayers(controller.getLogName() + " chose " + opponent.getLogName() + " to choose the piles"); + } + return opponent; + } +} diff --git a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java index ee9548ee5cf9..26fb9e14ea8f 100644 --- a/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java +++ b/Mage.Sets/src/mage/sets/MurdersAtKarlovManor.java @@ -133,6 +133,7 @@ private MurdersAtKarlovManor() { cards.add(new SetCardInfo("Innocent Bystander", 133, Rarity.COMMON, mage.cards.i.InnocentBystander.class)); cards.add(new SetCardInfo("Inside Source", 19, Rarity.COMMON, mage.cards.i.InsideSource.class)); cards.add(new SetCardInfo("Insidious Roots", 208, Rarity.UNCOMMON, mage.cards.i.InsidiousRoots.class)); + cards.add(new SetCardInfo("Intrude on the Mind", 61, Rarity.MYTHIC, mage.cards.i.IntrudeOnTheMind.class)); cards.add(new SetCardInfo("Island", 273, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("It Doesn't Add Up", 89, Rarity.UNCOMMON, mage.cards.i.ItDoesntAddUp.class)); cards.add(new SetCardInfo("Izoni, Center of the Web", 209, Rarity.RARE, mage.cards.i.IzoniCenterOfTheWeb.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/Thopter00ColorlessToken.java b/Mage/src/main/java/mage/game/permanent/token/Thopter00ColorlessToken.java new file mode 100644 index 000000000000..dd5d8a3a99aa --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/Thopter00ColorlessToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +public class Thopter00ColorlessToken extends TokenImpl { + + public Thopter00ColorlessToken() { + super("Thopter Token", "0/0 colorless Thopter artifact creature token with flying"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.THOPTER); + power = new MageInt(0); + toughness = new MageInt(0); + + addAbility(FlyingAbility.getInstance()); + } + + private Thopter00ColorlessToken(final Thopter00ColorlessToken token) { + super(token); + } + + @Override + public Thopter00ColorlessToken copy() { + return new Thopter00ColorlessToken(this); + } +}