diff --git a/Mage.Sets/src/mage/cards/r/RaphaelsTechnique.java b/Mage.Sets/src/mage/cards/r/RaphaelsTechnique.java new file mode 100644 index 00000000000..645a3dee9ad --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaphaelsTechnique.java @@ -0,0 +1,76 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SneakAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RaphaelsTechnique extends CardImpl { + + public RaphaelsTechnique(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}{R}"); + + // Sneak {2}{R} + this.addAbility(new SneakAbility(this, "{2}{R}")); + + // Each player may discard their hand and draw seven cards. + this.getSpellAbility().addEffect(new RaphaelsTechniqueEffect()); + } + + private RaphaelsTechnique(final RaphaelsTechnique card) { + super(card); + } + + @Override + public RaphaelsTechnique copy() { + return new RaphaelsTechnique(this); + } +} + +class RaphaelsTechniqueEffect extends OneShotEffect { + + RaphaelsTechniqueEffect() { + super(Outcome.Benefit); + staticText = "each player may discard their hand and draw seven cards"; + } + + private RaphaelsTechniqueEffect(final RaphaelsTechniqueEffect effect) { + super(effect); + } + + @Override + public RaphaelsTechniqueEffect copy() { + return new RaphaelsTechniqueEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + List wheelers = new ArrayList<>(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null && player.chooseUse( + Outcome.DrawCard, "Discard your hand and draw seven?", source, game + )) { + game.informPlayers(player.getName() + " chooses to discard their hand and draw seven"); + wheelers.add(player); + } + } + for (Player player : wheelers) { + player.discard(player.getHand(), false, source, game); + player.drawCards(7, source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java index 1836fdada0a..6869ab8e888 100644 --- a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java +++ b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java @@ -29,6 +29,7 @@ public final class TeenageMutantNinjaTurtles extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 313, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 253, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 310, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Raphael's Technique", 105, Rarity.RARE, mage.cards.r.RaphaelsTechnique.class)); cards.add(new SetCardInfo("Super Shredder", 83, Rarity.MYTHIC, mage.cards.s.SuperShredder.class)); cards.add(new SetCardInfo("Swamp", 255, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Swamp", 312, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/keyword/SneakAbility.java b/Mage/src/main/java/mage/abilities/keyword/SneakAbility.java new file mode 100644 index 00000000000..d38089c2278 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/SneakAbility.java @@ -0,0 +1,77 @@ +package mage.abilities.keyword; + +import mage.MageIdentifier; +import mage.abilities.SpellAbility; +import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.SpellAbilityType; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.UnblockedPredicate; +import mage.game.Game; +import mage.target.common.TargetControlledPermanent; + +import java.util.Set; + +/** + * @author TheElk801 + */ +public class SneakAbility extends SpellAbility { + + public static final String SNEAK_ACTIVATION_VALUE_KEY = "sneakActivation"; + private static final FilterControlledPermanent filter = new FilterControlledPermanent("unblocked attacker you control"); + + static { + filter.add(UnblockedPredicate.instance); + filter.add(AttackingPredicate.instance); + } + + public SneakAbility(Card card, String manaString) { + super(card.getSpellAbility()); + this.newId(); + this.setCardName(card.getName() + " with Sneak"); + timing = TimingRule.INSTANT; + zone = Zone.HAND; + spellAbilityType = SpellAbilityType.BASE_ALTERNATE; + + this.clearManaCosts(); + this.clearManaCostsToPay(); + this.addCost(new ManaCostsImpl<>(manaString)); + this.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(filter))); + + this.setRuleAtTheTop(true); + } + + protected SneakAbility(final SneakAbility ability) { + super(ability); + } + + @Override + public boolean activate(Game game, Set allowedIdentifiers, boolean noMana) { + if (!super.activate(game, allowedIdentifiers, noMana) + || game.getStep().getType() != PhaseStep.DECLARE_BLOCKERS) { + return false; + } + this.setCostsTag(SNEAK_ACTIVATION_VALUE_KEY, null); + return true; + } + + @Override + public SneakAbility copy() { + return new SneakAbility(this); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder("Sneak "); + sb.append(getManaCosts().getText()); + sb.append(" (You may cast this spell for "); + sb.append(getManaCosts().getText()); + sb.append(" if you also return an unblocked attacker you control to hand during the declare blockers step.)"); + return sb.toString(); + } +} diff --git a/Utils/keywords.txt b/Utils/keywords.txt index a2e1ccb4ebe..84b42818d1a 100644 --- a/Utils/keywords.txt +++ b/Utils/keywords.txt @@ -126,6 +126,7 @@ Shroud|instance| Soulbond|new| Soulshift|number| Skulk|new| +Sneak|card, manaString| Spectacle|card, cost| Spree|card| Squad|cost|