diff --git a/Mage.Sets/src/mage/cards/s/SmugglersSurprise.java b/Mage.Sets/src/mage/cards/s/SmugglersSurprise.java new file mode 100644 index 00000000000..115fdfb429c --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SmugglersSurprise.java @@ -0,0 +1,113 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.MillThenPutInHandEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.SpreeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class SmugglersSurprise extends CardImpl { + + private static final FilterCard filterCard = new FilterCard("creature and/or land cards"); + + static { + filterCard.add(Predicates.or(CardType.CREATURE.getPredicate(), CardType.LAND.getPredicate())); + } + + private static final FilterPermanent filter = new FilterCreaturePermanent("Creatures you control with power 4 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.OR_GREATER, 4)); + } + + public SmugglersSurprise(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}"); + + // Spree + this.addAbility(new SpreeAbility(this)); + + // + {2} -- Mill four cards. You may put up to two creature and/or land cards from among the milled cards into your hand. + this.getSpellAbility().addEffect(new MillThenPutInHandEffect( + 4, filterCard, null, true, 4 + )); + this.getSpellAbility().withFirstModeCost(new GenericManaCost(2)); + + // + {4}{G} -- You may put up to two creature cards from your hand onto the battlefield. + this.getSpellAbility().addMode(new Mode(new SmugglersSurpriseEffect()) + .withCost(new ManaCostsImpl<>("{4}{G}"))); + + // + {1} -- Creatures you control with power 4 or greater gain hexproof and indestructible until end of turn. + this.getSpellAbility().addMode(new Mode( + new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, filter) + .setText("Creatures you control with power 4 or greater gain hexproof")) + .addEffect(new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn, filter) + .setText(" and indestructible until end of turn")) + .withCost(new GenericManaCost(1)) + ); + } + + private SmugglersSurprise(final SmugglersSurprise card) { + super(card); + } + + @Override + public SmugglersSurprise copy() { + return new SmugglersSurprise(this); + } +} + +class SmugglersSurpriseEffect extends OneShotEffect { + + SmugglersSurpriseEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "You may put up to two creature cards from your hand onto the battlefield"; + } + + private SmugglersSurpriseEffect(final SmugglersSurpriseEffect effect) { + super(effect); + } + + @Override + public SmugglersSurpriseEffect copy() { + return new SmugglersSurpriseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + TargetCardInHand target = new TargetCardInHand(0, 2, new FilterCreatureCard("creature cards")); + if (controller.choose(Outcome.PutCreatureInPlay, target, source, game)) { + return controller.moveCards( + new CardsImpl(target.getTargets()).getCards(game), + Zone.BATTLEFIELD, source, game + ); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java b/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java index 9ce6568d284..0f1d5c416cc 100644 --- a/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java +++ b/Mage.Sets/src/mage/sets/OutlawsOfThunderJunction.java @@ -237,6 +237,7 @@ public final class OutlawsOfThunderJunction extends ExpansionSet { cards.add(new SetCardInfo("Slickshot Lockpicker", 67, Rarity.UNCOMMON, mage.cards.s.SlickshotLockpicker.class)); cards.add(new SetCardInfo("Slickshot Show-Off", 146, Rarity.RARE, mage.cards.s.SlickshotShowOff.class)); cards.add(new SetCardInfo("Slickshot Vault-Buster", 68, Rarity.COMMON, mage.cards.s.SlickshotVaultBuster.class)); + cards.add(new SetCardInfo("Smuggler's Surprise", 180, Rarity.RARE, mage.cards.s.SmugglersSurprise.class)); cards.add(new SetCardInfo("Snakeskin Veil", 181, Rarity.COMMON, mage.cards.s.SnakeskinVeil.class)); cards.add(new SetCardInfo("Soured Springs", 264, Rarity.COMMON, mage.cards.s.SouredSprings.class)); cards.add(new SetCardInfo("Spinewoods Armadillo", 182, Rarity.UNCOMMON, mage.cards.s.SpinewoodsArmadillo.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/MillThenPutInHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/MillThenPutInHandEffect.java index 7987db6360a..6fe59413224 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/MillThenPutInHandEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/MillThenPutInHandEffect.java @@ -15,6 +15,10 @@ import mage.players.Player; import mage.target.TargetCard; import mage.util.CardUtil; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + /** * @author TheElk801 */ @@ -22,6 +26,7 @@ public class MillThenPutInHandEffect extends OneShotEffect { private final int amount; private final boolean optional; + private final int maxAmountReturned; // maximum number of cards returned. e.g. 2 for "up to two" private final FilterCard filter; private final Effect otherwiseEffect; private String textFromAmong = "the milled cards"; // for text gen @@ -54,10 +59,15 @@ public class MillThenPutInHandEffect extends OneShotEffect { } public MillThenPutInHandEffect(int amount, FilterCard filter, Effect otherwiseEffect, boolean optional) { + this(amount, filter, otherwiseEffect, optional, 1); + } + + public MillThenPutInHandEffect(int amount, FilterCard filter, Effect otherwiseEffect, boolean optional, int maxReturnedCard) { super(Outcome.Benefit); this.amount = amount; this.filter = filter; this.optional = optional; + this.maxAmountReturned = maxReturnedCard; this.otherwiseEffect = otherwiseEffect; } @@ -66,6 +76,7 @@ public class MillThenPutInHandEffect extends OneShotEffect { this.amount = effect.amount; this.optional = effect.optional; this.filter = effect.filter; + this.maxAmountReturned = effect.maxAmountReturned; this.otherwiseEffect = effect.otherwiseEffect; this.textFromAmong = effect.textFromAmong; } @@ -85,13 +96,18 @@ public class MillThenPutInHandEffect extends OneShotEffect { if (cards.isEmpty()) { return applyOtherwiseEffect(game, source); } - TargetCard target = new TargetCard(optional ? 0 : 1, 1, Zone.ALL, filter); + TargetCard target = new TargetCard(optional ? 0 : maxAmountReturned, maxAmountReturned, Zone.ALL, filter); player.choose(Outcome.DrawCard, cards, target, source, game); - Card card = game.getCard(target.getFirstTarget()); - if (card == null) { + Set returned = target + .getTargets() + .stream() + .map(game::getCard) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + if (returned.isEmpty()) { return applyOtherwiseEffect(game, source); } - return player.moveCards(card, Zone.HAND, source, game); + return player.moveCards(returned, Zone.HAND, source, game); } private boolean applyOtherwiseEffect(Game game, Ability source) { @@ -120,6 +136,10 @@ public class MillThenPutInHandEffect extends OneShotEffect { sb.append(" cards. "); sb.append(optional ? "You may " : "Then "); sb.append("put "); + if (maxAmountReturned > 1) { + sb.append(optional ? "up to " : ""); + sb.append(CardUtil.numberToText(amount) + " "); + } sb.append(filter.getMessage()); sb.append(" from among "); sb.append(textFromAmong);