Delve abilities - removed unnecessary windows with exiled cards (except few cards that can use it);

This commit is contained in:
Oleg Agafonov 2025-02-11 22:15:59 +04:00
parent e2557c1d1b
commit ba0e5a1aed
29 changed files with 75 additions and 39 deletions

View file

@ -20,7 +20,8 @@ public final class BecomeImmense extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{G}");
// Delve (Each card you exile from your graveyard while casting this spell pays for {1}.)
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Target creature gets +6/+6 until end of turn
this.getSpellAbility().addEffect(new BoostTargetEffect(6, 6, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -20,7 +20,8 @@ public final class DeadDrop extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{9}{B}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Target player sacrifices two creatures
this.getSpellAbility().addEffect(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURES, 2, "Target player"));
this.getSpellAbility().addTarget(new TargetPlayer());

View file

@ -29,7 +29,7 @@ public final class DeathRattle extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{B}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Destroy target nongreen creature. It can't be regenerated.
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));

View file

@ -18,7 +18,7 @@ public final class DigThroughTime extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{6}{U}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Look at the top seven cards of your library. Put two of them into your hand and the rest on the bottom of your library in any order.
this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(7, 2, PutCards.HAND, PutCards.BOTTOM_ANY));

View file

@ -21,7 +21,7 @@ public final class EmptyThePits extends CardImpl {
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// create X 2/2 black Zombie creature tokens tapped.
this.getSpellAbility().addEffect(new CreateTokenEffect(new ZombieToken(), GetXValue.instance, true, false));

View file

@ -37,7 +37,7 @@ public final class EtherealForager extends CardImpl {
this.toughness = new MageInt(3);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(true));
// Flying
this.addAbility(FlyingAbility.getInstance());

View file

@ -23,7 +23,7 @@ public final class GurmagAngler extends CardImpl {
this.toughness = new MageInt(5);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
}
private GurmagAngler(final GurmagAngler card) {

View file

@ -45,7 +45,7 @@ public final class HogaakArisenNecropolis extends CardImpl {
this.addAbility(new ConvokeAbility());
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// You may cast Hogaak, Arisen Necropolis from your graveyard.
this.addAbility(new MayCastFromGraveyardSourceAbility());

View file

@ -24,7 +24,8 @@ public final class HootingMandrills extends CardImpl {
this.toughness = new MageInt(4);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Trample
this.addAbility(TrampleAbility.getInstance());
}

View file

@ -21,7 +21,7 @@ public final class LogicKnot extends CardImpl {
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Counter target spell unless its controller pays {X}.
this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(GetXValue.instance));

View file

@ -18,7 +18,7 @@ public final class MagmaticSinkhole extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{R}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Magmatic Sinkhole deals 5 damage to target creature or planeswalker.
this.getSpellAbility().addEffect(new DamageTargetEffect(5));

View file

@ -20,7 +20,7 @@ public final class MurderousCut extends CardImpl {
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Destroy target creature.
this.getSpellAbility().addEffect(new DestroyTargetEffect());

View file

@ -37,7 +37,7 @@ public final class MurktideRegent extends CardImpl {
this.toughness = new MageInt(3);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(true));
// Flying
this.addAbility(FlyingAbility.getInstance());

View file

@ -48,7 +48,7 @@ public final class NecropolisFiend extends CardImpl {
this.toughness = new MageInt(5);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Flying
this.addAbility(FlyingAbility.getInstance());

View file

@ -29,7 +29,7 @@ public final class RiteOfUndoing extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Return target nonland permanent you control and target nonland permanent you don't control to their owners' hands.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setTargetPointer(new EachTargetPointer()));

View file

@ -20,7 +20,8 @@ public final class SetAdrift extends CardImpl {
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Put target nonland permanent on top of its owner's library
this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
this.getSpellAbility().addTarget(new TargetNonlandPermanent());

View file

@ -24,7 +24,8 @@ public final class ShamblingAttendants extends CardImpl {
this.toughness = new MageInt(5);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
}

View file

@ -28,7 +28,8 @@ public final class SibsigMuckdraggers extends CardImpl {
this.toughness = new MageInt(6);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// When Sibsig Muckdraggers enters the battlefield, return target creature card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));

View file

@ -33,7 +33,7 @@ public final class SorcerousSquall extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{U}{U}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Target opponent mills nine cards, then you may cast an instant or sorcery spell from that player's graveyard without paying its mana cost. If that spell would be put into a graveyard, exile it instead.
this.getSpellAbility().addEffect(new MillCardsTargetEffect(9));

View file

@ -31,7 +31,7 @@ public final class Soulflayer extends CardImpl {
this.toughness = new MageInt(4);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(true));
// If a creature card with flying was exiled with Soulflayer's delve ability, Soulflayer has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, reach, trample, and vigilance.
this.addAbility(new SimpleStaticAbility(new SoulflayerEffect()));

View file

@ -25,7 +25,8 @@ public final class SultaiScavenger extends CardImpl {
this.toughness = new MageInt(3);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Flying
this.addAbility(FlyingAbility.getInstance());
}

View file

@ -35,7 +35,7 @@ public final class TasigurTheGoldenFang extends CardImpl {
this.toughness = new MageInt(5);
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// {2}{G/U}{G/U}: Put the top two cards of your library into your graveyard, then return a nonland card of an opponent's choice from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(new MillCardsControllerEffect(2), new ManaCostsImpl<>("{2}{G/U}{G/U}"));

View file

@ -20,7 +20,7 @@ public final class TasigursCruelty extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{B}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Each opponent discards two cards.
this.getSpellAbility().addEffect(new DiscardEachPlayerEffect(StaticValue.get(2), false, TargetController.OPPONENT));

View file

@ -19,7 +19,8 @@ public final class TemporalTrespass extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{8}{U}{U}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Take an extra turn after this one. Exile Temporal Trespass.
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect());
this.getSpellAbility().addEffect(new ExileSpellEffect());

View file

@ -26,10 +26,9 @@ public final class Tombstalker extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Delve
Ability ability = new DelveAbility();
ability.setRuleAtTheTop(false);
this.addAbility(ability);
this.addAbility(new DelveAbility(false));
}
private Tombstalker(final Tombstalker card) {

View file

@ -1,4 +1,3 @@
package mage.cards.t;
import java.util.UUID;
@ -17,9 +16,9 @@ public final class TreasureCruise extends CardImpl {
public TreasureCruise(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{7}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Draw 3 Cards
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3));
}

View file

@ -1,4 +1,3 @@
package mage.cards.w;
import java.util.UUID;
@ -20,7 +19,8 @@ public final class WillOfTheNaga extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{U}{U}");
// Delve
this.addAbility(new DelveAbility());
this.addAbility(new DelveAbility(false));
// Tap up to two target creatures. Those creatures don't untap during their controller's next untap step.
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));

View file

@ -18,7 +18,6 @@ import mage.util.CardUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author nantuko
@ -27,6 +26,7 @@ public class ExileFromGraveCost extends CostImpl {
private final List<Card> exiledCards = new ArrayList<>();
private boolean setTargetPointer = false;
private boolean useSourceExileZone = true;
public ExileFromGraveCost(TargetCardInYourGraveyard target) {
target.withNotTarget(true);
@ -73,6 +73,7 @@ public class ExileFromGraveCost extends CostImpl {
super(cost);
this.exiledCards.addAll(cost.getExiledCards());
this.setTargetPointer = cost.setTargetPointer;
this.useSourceExileZone = cost.useSourceExileZone;
}
@Override
@ -90,11 +91,23 @@ public class ExileFromGraveCost extends CostImpl {
}
Cards cardsToExile = new CardsImpl();
cardsToExile.addAllCards(exiledCards);
UUID exileZoneId = null;
String exileZoneName = "";
if (useSourceExileZone) {
exileZoneId = CardUtil.getExileZoneId(game, source);
exileZoneName = CardUtil.getSourceName(game, source);
}
controller.moveCardsToExile(
cardsToExile.getCards(game), source, game, true,
CardUtil.getExileZoneId(game, source),
CardUtil.getSourceName(game, source)
cardsToExile.getCards(game),
source,
game,
true,
exileZoneId,
exileZoneName
);
if (setTargetPointer) {
source.getEffects().setTargetPointer(new FixedTargets(cardsToExile.getCards(game), game));
}
@ -118,4 +131,12 @@ public class ExileFromGraveCost extends CostImpl {
public List<Card> getExiledCards() {
return exiledCards;
}
/**
* Put exiled cards to source zone, so next linked ability can find it
*/
public ExileFromGraveCost withSourceExileZone(boolean useSourceExileZone) {
this.useSourceExileZone = useSourceExileZone;
return this;
}
}

View file

@ -63,10 +63,16 @@ public class DelveAbility extends SimpleStaticAbility implements AlternateManaPa
private static final DynamicValue cardsInGraveyard = new CardsInControllerGraveyardCount();
public DelveAbility() {
private boolean useSourceExileZone;
/**
* @param useSourceExileZone - keep exiled cards in linked source zone, so next ability can find it
*/
public DelveAbility(boolean useSourceExileZone) {
super(Zone.ALL, null);
this.setRuleAtTheTop(true);
this.addHint(new ValueHint("Cards in your graveyard", cardsInGraveyard));
this.useSourceExileZone = useSourceExileZone;
}
protected DelveAbility(final DelveAbility ability) {
@ -101,8 +107,11 @@ public class DelveAbility extends SimpleStaticAbility implements AlternateManaPa
unpaidAmount = 1;
}
specialAction.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(
0, Math.min(controller.getGraveyard().size(), unpaidAmount),
new FilterCard("cards from your graveyard"), true)));
0,
Math.min(controller.getGraveyard().size(), unpaidAmount),
new FilterCard("cards from your graveyard"),
true
)).withSourceExileZone(this.useSourceExileZone));
if (specialAction.canActivate(source.getControllerId(), game).canActivate()) {
game.getState().getSpecialActions().add(specialAction);
}