[TMT] Implement Raphael's Technique

This commit is contained in:
theelk801 2025-10-10 16:30:48 -04:00
parent 1c134ac2c2
commit 159933cc8a
4 changed files with 155 additions and 0 deletions

View file

@ -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<Player> 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;
}
}

View file

@ -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("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", 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("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("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", 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)); cards.add(new SetCardInfo("Swamp", 312, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));

View file

@ -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<MageIdentifier> 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(" <i>(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.)</i>");
return sb.toString();
}
}

View file

@ -126,6 +126,7 @@ Shroud|instance|
Soulbond|new| Soulbond|new|
Soulshift|number| Soulshift|number|
Skulk|new| Skulk|new|
Sneak|card, manaString|
Spectacle|card, cost| Spectacle|card, cost|
Spree|card| Spree|card|
Squad|cost| Squad|cost|