Merge origin/master

This commit is contained in:
LevelX2 2019-12-27 23:23:09 +01:00
commit 1f82e7a4ae
34 changed files with 398 additions and 242 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.a;
import java.util.Set;
@ -34,10 +33,15 @@ public final class AetherworksMarvel extends CardImpl {
addSuperType(SuperType.LEGENDARY);
// Whenever a permanent you control is put into a graveyard, you get {E}.
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new GetEnergyCountersControllerEffect(1), false, new FilterControlledPermanent("a permanent you control"), false));
this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(
new GetEnergyCountersControllerEffect(1), false,
new FilterControlledPermanent("a permanent you control"), false));
// {T}, Pay {E}{E}{E}{E}{E}{E}: Look at the top six cards of your library. You may cast a card from among them without paying its mana cost. Put the rest on the bottom of your library in a random order.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AetherworksMarvelEffect(), new TapSourceCost());
// {T}, Pay {E}{E}{E}{E}{E}{E}: Look at the top six cards of your library.
// You may cast a card from among them without paying its mana cost.
// Put the rest on the bottom of your library in a random order.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new AetherworksMarvelEffect(), new TapSourceCost());
ability.addCost(new PayEnergyCost(6));
this.addAbility(ability);
}
@ -56,7 +60,10 @@ class AetherworksMarvelEffect extends OneShotEffect {
AetherworksMarvelEffect() {
super(Outcome.PlayForFree);
this.staticText = "Look at the top six cards of your library. You may cast a card from among them without paying its mana cost. Put the rest on the bottom of your library in a random order";
this.staticText = "Look at the top six cards of your library. "
+ "You may cast a card from among them without paying "
+ "its mana cost. Put the rest on the bottom of your "
+ "library in a random order";
}
AetherworksMarvelEffect(final AetherworksMarvelEffect effect) {
@ -74,11 +81,18 @@ class AetherworksMarvelEffect extends OneShotEffect {
if (controller != null) {
Set<Card> cardsSet = controller.getLibrary().getTopCards(game, 6);
Cards cards = new CardsImpl(cardsSet);
TargetCard target = new TargetCardInLibrary(0, 1, new FilterNonlandCard("card to cast without paying its mana cost"));
TargetCard target = new TargetCardInLibrary(0, 1,
new FilterNonlandCard("card to cast without paying its mana cost"));
if (controller.choose(Outcome.PlayForFree, cards, target, game)) {
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
if (card != null && controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
cards.remove(card);
if (card != null) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cards.remove(card);
}
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, false);

View file

@ -118,9 +118,7 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller == null
|| sourceObject == null) {
if (controller == null) {
return false;
}
TargetCardInExile target = new TargetCardInExile(0, 3, filter, null);
@ -135,10 +133,10 @@ class AshiokNightmareMuseCastEffect extends OneShotEffect {
&& game.getState().getZone(chosenCard.getId()) == Zone.EXILED // must be exiled
&& game.getOpponents(controller.getId()).contains(chosenCard.getOwnerId()) // must be owned by an opponent
&& controller.chooseUse(outcome, "Cast " + chosenCard.getName() + " without paying its mana cost?", source, game)) {
game.getState().setValue("CastFromExileEnabled" + chosenCard.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone
game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(chosenCard, game, true),
game, true, new MageObjectReference(sourceObject, game));
game.getState().setValue("CastFromExileEnabled" + chosenCard.getId(), null); // reset to null
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + chosenCard.getId(), null);
}
}
}

View file

@ -90,19 +90,19 @@ class ChandraTorchOfDefianceEffect extends OneShotEffect {
Library library = controller.getLibrary();
Card card = library.getFromTop(game);
if (card != null) {
boolean exiledCardWasCast = false;
boolean cardWasCast = false;
controller.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName());
if (!card.getManaCost().isEmpty()
|| !card.isLand()) {
if (controller.chooseUse(Outcome.Benefit, "Cast " + card.getName() + "? (You still pay the costs)", source, game)
&& (game.getState().getZone(card.getId()) == Zone.EXILED)) { // card must be in the exile zone
game.getState().setValue("CastFromExileEnabled" + card.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone
exiledCardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, false),
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE); // enable the card to be cast from the exile zone
cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, false),
game, false, new MageObjectReference(sourceObject, game));
game.getState().setValue("CastFromExileEnabled" + card.getId(), null); // reset to null
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null); // reset to null
}
}
if (!exiledCardWasCast) {
if (!cardWasCast) {
new DamagePlayersEffect(Outcome.Damage, new StaticValue(2), TargetController.OPPONENT).apply(game, source);
}
}

View file

@ -10,9 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInHand;
/**
@ -22,12 +20,6 @@ import mage.target.common.TargetCardInHand;
*/
public final class Drekavac extends CardImpl {
private static final FilterCard filter = new FilterCard("noncreature card");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public Drekavac(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
this.subtype.add(SubType.BEAST);
@ -35,7 +27,7 @@ public final class Drekavac extends CardImpl {
this.toughness = new MageInt(3);
// When Drekavac enters the battlefield, sacrifice it unless you discard a noncreature card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new DiscardTargetCost(new TargetCardInHand(filter)))));
this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_A_NON_CREATURE)))));
}
public Drekavac(final Drekavac card) {

View file

@ -14,10 +14,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@ -60,12 +57,6 @@ public final class EntomberExarch extends CardImpl {
class EntomberExarchEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("noncreature card");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
EntomberExarchEffect() {
super(Outcome.Discard);
staticText = "target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card";
@ -82,7 +73,7 @@ class EntomberExarchEffect extends OneShotEffect {
player.revealCards("Entomber Exarch", player.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
TargetCard target = new TargetCard(Zone.HAND, filter);
TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_A_NON_CREATURE);
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
return player.discard(card, source, game);

View file

@ -42,7 +42,7 @@ public final class FaeOfWishes extends AdventureCard {
// Granted
// You may choose a noncreature card you own from outside the game, reveal it, and put it into your hand.
this.getSpellCard().getSpellAbility().addEffect(new WishEffect(StaticFilters.FILTER_CARD_A_NON_LAND));
this.getSpellCard().getSpellAbility().addEffect(new WishEffect(StaticFilters.FILTER_CARD_A_NON_CREATURE));
}
private FaeOfWishes(final FaeOfWishes card) {

View file

@ -1,4 +1,3 @@
package mage.cards.h;
import java.util.UUID;
@ -32,9 +31,11 @@ public final class HarnessTheStorm extends CardImpl {
public HarnessTheStorm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
// Whenever you cast an instant or sorcery spell from your hand, you may cast target card with the same name as that spell from your graveyard.
// Whenever you cast an instant or sorcery spell from your hand, you may cast
// target card with the same name as that spell from your graveyard.
this.addAbility(new HarnessTheStormTriggeredAbility(new HarnessTheStormEffect(),
new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"), false), new CastFromHandWatcher());
new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"),
false), new CastFromHandWatcher());
}
public HarnessTheStorm(final HarnessTheStorm card) {
@ -87,7 +88,8 @@ class HarnessTheStormEffect extends OneShotEffect {
public HarnessTheStormEffect() {
super(Outcome.Benefit);
this.staticText = "you may cast target card with the same name as that spell from your graveyard. <i>(you still pay its costs.)</i>";
this.staticText = "you may cast target card with the same name as that "
+ "spell from your graveyard. <i>(you still pay its costs.)</i>";
}
public HarnessTheStormEffect(final HarnessTheStormEffect effect) {
@ -106,8 +108,11 @@ class HarnessTheStormEffect extends OneShotEffect {
if (controller != null) {
Card card = controller.getGraveyard().get(getTargetPointer().getFirst(game, source), game);
if (card != null) {
if (controller.chooseUse(outcome, "Cast " + card.getIdName() + " from your graveyard?", source, game)) {
controller.cast(card.getSpellAbility(), game, false, new MageObjectReference(source.getSourceObject(game), game));
if (controller.chooseUse(outcome.Benefit, "Cast " + card.getIdName() + " from your graveyard?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, false),
game, false, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;

View file

@ -1,4 +1,3 @@
package mage.cards.h;
import java.util.HashSet;
@ -20,7 +19,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -41,7 +40,9 @@ public final class HellcarverDemon extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Hellcarver Demon deals combat damage to a player, sacrifice all other permanents you control and discard your hand. Exile the top six cards of your library. You may cast any number of nonland cards exiled this way without paying their mana costs.
// Whenever Hellcarver Demon deals combat damage to a player, sacrifice all other permanents you
// control and discard your hand. Exile the top six cards of your library. You may cast any number
// of nonland cards exiled this way without paying their mana costs.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new HellcarverDemonEffect(), false));
}
@ -59,7 +60,9 @@ class HellcarverDemonEffect extends OneShotEffect {
public HellcarverDemonEffect() {
super(Outcome.PlayForFree);
staticText = "sacrifice all other permanents you control and discard your hand. Exile the top six cards of your library. You may cast any number of nonland cards exiled this way without paying their mana costs.";
staticText = "sacrifice all other permanents you control and discard your hand. "
+ "Exile the top six cards of your library. You may cast any number of "
+ "nonland cards exiled this way without paying their mana costs.";
}
public HellcarverDemonEffect(final HellcarverDemonEffect effect) {
@ -83,7 +86,8 @@ class HellcarverDemonEffect extends OneShotEffect {
// move cards from library to exile
Set<Card> currentExiledCards = new HashSet<>();
currentExiledCards.addAll(controller.getLibrary().getTopCards(game, 6));
controller.moveCardsToExile(currentExiledCards, source, game, true, source.getSourceId(), sourceObject.getIdName());
controller.moveCardsToExile(currentExiledCards, source, game, true,
source.getSourceId(), sourceObject.getIdName());
// cast the possible cards without paying the mana
Cards cardsToCast = new CardsImpl();
@ -91,18 +95,26 @@ class HellcarverDemonEffect extends OneShotEffect {
boolean alreadyCast = false;
while (!cardsToCast.isEmpty()
&& controller.canRespond()) {
if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "nother" : "") + " card exiled with " + sourceObject.getLogName() + " without paying its mana cost?", source, game)) {
if (!controller.chooseUse(outcome, "Cast a" + (alreadyCast ? "another" : "")
+ " card exiled with " + sourceObject.getLogName()
+ " without paying its mana cost?", source, game)) {
break;
}
TargetCard targetCard = new TargetCard(1, Zone.EXILED, new FilterCard("nonland card to cast for free"));
TargetCard targetCard = new TargetCard(1, Zone.EXILED,
new FilterNonlandCard("nonland card to cast for free"));
if (controller.choose(Outcome.PlayForFree, cardsToCast, targetCard, game)) {
alreadyCast = true;
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cardsToCast.remove(card);
} else {
game.informPlayer(controller, "You're not able to cast " + card.getIdName() + " or you canceled the casting.");
game.informPlayer(controller, "You're not able to cast "
+ card.getIdName() + " or you canceled the casting.");
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.i;
import java.util.UUID;
@ -35,11 +34,15 @@ public final class IsochronScepter extends CardImpl {
public IsochronScepter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Imprint - When Isochron Scepter enters the battlefield, you may exile an instant card with converted mana cost 2 or less from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(), true, "<i>Imprint &mdash; </i>"));
// Imprint - When Isochron Scepter enters the battlefield, you may exile an
// instant card with converted mana cost 2 or less from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new IsochronScepterImprintEffect(),
true, "<i>Imprint &mdash; </i>"));
// {2}, {tap}: You may copy the exiled card. If you do, you may cast the copy without paying its mana cost.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new IsochronScepterCopyEffect(), new GenericManaCost(2));
// {2}, {tap}: You may copy the exiled card. If you do, you may cast the
// copy without paying its mana cost.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new IsochronScepterCopyEffect(), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
@ -57,7 +60,8 @@ public final class IsochronScepter extends CardImpl {
class IsochronScepterImprintEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("instant card with converted mana cost 2 or less from your hand");
private static final FilterCard filter = new FilterCard("instant card with "
+ "converted mana cost 2 or less from your hand");
static {
filter.add(new CardTypePredicate(CardType.INSTANT));
@ -66,7 +70,8 @@ class IsochronScepterImprintEffect extends OneShotEffect {
public IsochronScepterImprintEffect() {
super(Outcome.Benefit);
staticText = "you may exile an instant card with converted mana cost 2 or less from your hand";
staticText = "you may exile an instant card with converted mana "
+ "cost 2 or less from your hand";
}
public IsochronScepterImprintEffect(IsochronScepterImprintEffect effect) {
@ -84,11 +89,13 @@ class IsochronScepterImprintEffect extends OneShotEffect {
&& controller.choose(Outcome.Benefit, controller.getHand(), target, game)) {
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
controller.moveCardToExileWithInfo(card, source.getSourceId(), sourcePermanent.getIdName() + " (Imprint)", source.getSourceId(), game, Zone.HAND, true);
controller.moveCardsToExile(card, source, game, true, source.getSourceId(),
sourcePermanent.getIdName() + " (Imprint)");
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.imprint(card.getId(), game);
permanent.addInfo("imprint", CardUtil.addToolTipMarkTags("[Imprinted card - " + card.getLogName() + ']'), game);
permanent.addInfo("imprint", CardUtil.addToolTipMarkTags(
"[Imprinted card - " + card.getLogName() + ']'), game);
}
}
}
@ -110,7 +117,8 @@ class IsochronScepterCopyEffect extends OneShotEffect {
public IsochronScepterCopyEffect() {
super(Outcome.Copy);
this.staticText = "You may copy the exiled card. If you do, you may cast the copy without paying its mana cost";
this.staticText = "You may copy the exiled card. If you do, "
+ "you may cast the copy without paying its mana cost";
}
public IsochronScepterCopyEffect(final IsochronScepterCopyEffect effect) {
@ -127,9 +135,12 @@ class IsochronScepterCopyEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent scepter = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (scepter != null && scepter.getImprinted() != null && !scepter.getImprinted().isEmpty()) {
if (scepter != null
&& scepter.getImprinted() != null
&& !scepter.getImprinted().isEmpty()) {
Card imprintedInstant = game.getCard(scepter.getImprinted().get(0));
if (imprintedInstant != null && game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
if (imprintedInstant != null
&& game.getState().getZone(imprintedInstant.getId()) == Zone.EXILED) {
if (controller.chooseUse(outcome, "Create a copy of " + imprintedInstant.getName() + '?', source, game)) {
Card copiedCard = game.copyCard(imprintedInstant, source, source.getControllerId());
if (copiedCard != null) {
@ -137,9 +148,13 @@ class IsochronScepterCopyEffect extends OneShotEffect {
game.getState().setZone(copiedCard.getId(), Zone.EXILED);
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
if (copiedCard.getSpellAbility() != null) {
controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(copiedCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
} else {
Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: spell ability == null " + copiedCard.getName());
Logger.getLogger(IsochronScepterCopyEffect.class).error("Isochron Scepter: "
+ "spell ability == null " + copiedCard.getName());
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.i;
import java.util.UUID;
@ -83,7 +82,7 @@ public final class IzzetChemister extends CardImpl {
class IzzetChemisterCastFromExileEffect extends OneShotEffect {
private UUID exileId;
private final UUID exileId;
public IzzetChemisterCastFromExileEffect(UUID exileId, String description) {
super(Outcome.PlayForFree);
@ -106,7 +105,8 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
ExileZone exile = game.getExile().getExileZone(exileId);
Player controller = game.getPlayer(source.getControllerId());
FilterCard filter = new FilterCard();
if (controller != null && exile != null) {
if (controller != null
&& exile != null) {
Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(exile.getCards(game));
OuterLoop:
@ -116,11 +116,17 @@ class IzzetChemisterCastFromExileEffect extends OneShotEffect {
}
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
target.setNotTarget(true);
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
while (cardsToExile.count(filter, game) > 0
&& controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
cardsToExile.remove(card);
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true), game, true,
new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cardsToExile.remove(card);
}
} else {
break OuterLoop;
}

View file

@ -59,10 +59,12 @@ public final class JaceArchitectOfThought extends CardImpl {
// +1: Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtStartEffect1(), 1));
// -2: Reveal the top three cards of your library. An opponent separates those cards into two piles. Put one pile into your hand and the other on the bottom of your library in any order.
// -2: Reveal the top three cards of your library. An opponent separates those cards into two piles.
// Put one pile into your hand and the other on the bottom of your library in any order.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtEffect2(), -2));
// -8: For each player, search that player's library for a nonland card and exile it, then that player shuffles their library. You may cast those cards without paying their mana costs.
// -8: For each player, search that player's library for a nonland card and exile it,
// then that player shuffles their library. You may cast those cards without paying their mana costs.
this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtEffect3(), -8));
}
@ -81,7 +83,8 @@ class JaceArchitectOfThoughtStartEffect1 extends OneShotEffect {
public JaceArchitectOfThoughtStartEffect1() {
super(Outcome.UnboostCreature);
this.staticText = "Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn";
this.staticText = "Until your next turn, whenever a creature an opponent "
+ "controls attacks, it gets -1/-0 until end of turn";
}
public JaceArchitectOfThoughtStartEffect1(final JaceArchitectOfThoughtStartEffect1 effect) {
@ -138,7 +141,8 @@ class JaceArchitectOfThoughtDelayedTriggeredAbility extends DelayedTriggeredAbil
@Override
public boolean isInactive(Game game) {
return game.isActivePlayer(getControllerId()) && game.getTurnNum() != startingTurn;
return game.isActivePlayer(getControllerId())
&& game.getTurnNum() != startingTurn;
}
@Override
@ -151,7 +155,8 @@ class JaceArchitectOfThoughtEffect2 extends OneShotEffect {
public JaceArchitectOfThoughtEffect2() {
super(Outcome.DrawCard);
this.staticText = "Reveal the top three cards of your library. An opponent separates those cards into two piles. Put one pile into your hand and the other on the bottom of your library in any order";
this.staticText = "Reveal the top three cards of your library. An opponent separates those cards "
+ "into two piles. Put one pile into your hand and the other on the bottom of your library in any order";
}
public JaceArchitectOfThoughtEffect2(final JaceArchitectOfThoughtEffect2 effect) {
@ -223,7 +228,8 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
public JaceArchitectOfThoughtEffect3() {
super(Outcome.PlayForFree);
this.staticText = "For each player, search that player's library for a nonland card and exile it, then that player shuffles their library. You may cast those cards without paying their mana costs";
this.staticText = "For each player, search that player's library for a nonland card and exile it, "
+ "then that player shuffles their library. You may cast those cards without paying their mana costs";
}
public JaceArchitectOfThoughtEffect3(final JaceArchitectOfThoughtEffect3 effect) {
@ -303,7 +309,11 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect {
controller.choose(Outcome.PlayForFree, jaceExileZone, target, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
if (controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
game.getExile().removeCard(card, game);
}
}

View file

@ -44,7 +44,7 @@ public final class KlothysGodOfDestiny extends CardImpl {
// As long as your devotion to red and green is less than seven, Klothys isn't a creature.
Effect effect = new LoseCreatureTypeSourceEffect(xValue, 7);
effect.setText("As long as your devotion to red and green is less than seven, {this} isn't a creature");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect).addHint(new ValueHint("Devotion to red and green", xValue)));
this.addAbility(new SimpleStaticAbility(effect).addHint(new ValueHint("Devotion to red and green", xValue)));
// At the beginning of your precombat main phase, exile target card from a graveyard. If it was a land card, add {R} or {G}. Otherwise, you gain 2 life and Klothys deals 2 damage to each opponent.
Ability ability = new BeginningOfPreCombatMainTriggeredAbility(
@ -88,7 +88,9 @@ class KlothysGodOfDestinyEffect extends OneShotEffect {
if (player == null || card == null) {
return false;
}
if (card.isLand()) {
boolean isLand = card.isLand();
player.moveCards(card, Zone.EXILED, source, game);
if (isLand) {
Mana mana = new Mana();
if (player.chooseUse(
Outcome.PutManaInPool, "Choose a color of mana to add",
@ -99,14 +101,14 @@ class KlothysGodOfDestinyEffect extends OneShotEffect {
mana.increaseGreen();
}
player.getManaPool().addMana(mana, game, source);
} else {
player.gainLife(2, game, source);
game.getOpponents(player.getId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.forEach(opponent -> opponent.damage(2, source.getSourceId(), game));
return true;
}
return player.moveCards(card, Zone.EXILED, source, game);
player.gainLife(2, game, source);
game.getOpponents(player.getId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.forEach(opponent -> opponent.damage(2, source.getSourceId(), game));
return true;
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.k;
import java.util.UUID;
@ -31,7 +30,9 @@ public final class KnowledgeExploitation extends CardImpl {
// Prowl {3}{U}
this.addAbility(new ProwlAbility(this, "{3}{U}"));
// Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library.
// Search target opponent's library for an instant or sorcery card.
// You may cast that card without paying its mana cost.
// Then that player shuffles their library.
this.getSpellAbility().addEffect(new KnowledgeExploitationEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
@ -49,8 +50,11 @@ public final class KnowledgeExploitation extends CardImpl {
class KnowledgeExploitationEffect extends OneShotEffect {
KnowledgeExploitationEffect() {
super(Outcome.Benefit);
this.staticText = "Search target opponent's library for an instant or sorcery card. You may cast that card without paying its mana cost. Then that player shuffles their library";
super(Outcome.PlayForFree);
this.staticText = "Search target opponent's library for an "
+ "instant or sorcery card. You may cast that card "
+ "without paying its mana cost. Then that "
+ "player shuffles their library";
}
KnowledgeExploitationEffect(final KnowledgeExploitationEffect effect) {
@ -71,7 +75,10 @@ class KnowledgeExploitationEffect extends OneShotEffect {
if (controller.searchLibrary(target, source, game, opponent.getId())) {
Card card = opponent.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
opponent.shuffleLibrary(source, game);

View file

@ -1,4 +1,3 @@
package mage.cards.m;
import java.util.UUID;
@ -90,7 +89,10 @@ class MaelstromArchangelCastEffect extends OneShotEffect {
}
}
if (cardToCast != null) {
controller.cast(cardToCast.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(cardToCast, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + cardToCast.getId(), null);
}
}
return true;

View file

@ -1,4 +1,3 @@
package mage.cards.m;
import java.util.UUID;
@ -38,7 +37,8 @@ public final class MindleechMass extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Mindleech Mass deals combat damage to a player, you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost.
// Whenever Mindleech Mass deals combat damage to a player, you may look at that
// player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new MindleechMassEffect(), true, true));
}
@ -56,7 +56,8 @@ class MindleechMassEffect extends OneShotEffect {
public MindleechMassEffect() {
super(Outcome.PlayForFree);
this.staticText = "you may look at that player's hand. If you do, you may cast a nonland card in it without paying that card's mana cost";
this.staticText = "you may look at that player's hand. If you do, "
+ "you may cast a nonland card in it without paying that card's mana cost";
}
public MindleechMassEffect(final MindleechMassEffect effect) {
@ -82,7 +83,10 @@ class MindleechMassEffect extends OneShotEffect {
if (controller.chooseTarget(Outcome.PlayForFree, cardsInHand, target, source, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
}

View file

@ -4,15 +4,14 @@ import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.AdventureCard;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
import mage.abilities.effects.common.PutOnLibrarySourceEffect;
/**
* @author TheElk801
@ -31,7 +30,7 @@ public final class MurderousRider extends AdventureCard {
this.addAbility(LifelinkAbility.getInstance());
// When Murderous Rider dies, put it on the bottom of its owner's library.
this.addAbility(new DiesTriggeredAbility(new PutOnLibraryTargetEffect(
this.addAbility(new DiesTriggeredAbility(new PutOnLibrarySourceEffect(
false, "put it on the bottom of its owner's library"
), false));

View file

@ -1,4 +1,3 @@
package mage.cards.p;
import java.util.UUID;
@ -84,7 +83,7 @@ class PanopticMirrorExileEffect extends OneShotEffect {
}
TargetCardInHand target = new TargetCardInHand(filter);
if (player.choose(this.outcome, target, source.getSourceId(), game)) {
if (player.choose(outcome.PlayForFree, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Panoptic Mirror", source.getSourceId(), game);
@ -103,7 +102,7 @@ class PanopticMirrorCastEffect extends OneShotEffect {
public PanopticMirrorCastEffect() {
super(Outcome.ReturnToHand);
this.staticText = "you may copy a card exiled with Panoptic Mirror. If you do, you may cast the copy without paying its mana cost";
this.staticText = "you may copy a card exiled with {this}. If you do, you may cast the copy without paying its mana cost";
}
public PanopticMirrorCastEffect(final PanopticMirrorCastEffect effect) {
@ -122,7 +121,10 @@ class PanopticMirrorCastEffect extends OneShotEffect {
if (PanopticMirror == null) {
PanopticMirror = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (PanopticMirror != null && PanopticMirror.getImprinted() != null && !PanopticMirror.getImprinted().isEmpty() && controller != null) {
if (PanopticMirror != null
&& PanopticMirror.getImprinted() != null
&& !PanopticMirror.getImprinted().isEmpty()
&& controller != null) {
CardsImpl cards = new CardsImpl();
for (UUID uuid : PanopticMirror.getImprinted()) {
Card card = game.getCard(uuid);
@ -145,8 +147,11 @@ class PanopticMirrorCastEffect extends OneShotEffect {
}
if (cardToCopy != null) {
Card copy = game.copyCard(cardToCopy, source, source.getControllerId());
if (controller.chooseUse(outcome, "Cast the copied card without paying mana cost?", source, game)) {
return controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
if (controller.chooseUse(outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(copy, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), null);
}
}
return true;

View file

@ -1,16 +1,11 @@
package mage.cards.q;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.SpellAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -18,7 +13,6 @@ import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.players.Player;
/**
*
@ -36,7 +30,9 @@ public final class QasaliAmbusher extends CardImpl {
// Reach
this.addAbility(ReachAbility.getInstance());
// If a creature is attacking you and you control a Forest and a Plains, you may casbt Qasali Ambusher without paying its mana cost and as though it had flash.
// If a creature is attacking you and you control a Forest and a Plains,
// you may cast Qasali Ambusher without paying its mana cost and as though it had flash.
this.addAbility(new QasaliAmbusherAbility());
}
@ -62,7 +58,7 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
}
public QasaliAmbusherAbility() {
super(Zone.HAND, new QasaliAmbusherEffect(), new ManaCostsImpl());
super(Zone.HAND, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame), new ManaCostsImpl());
this.timing = TimingRule.INSTANT;
this.usesStack = false;
}
@ -78,8 +74,10 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
@Override
public ActivationStatus canActivate(UUID playerId, Game game) {
if (!game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).isEmpty()
&& !game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).isEmpty()) {
if (!game.getBattlefield().getActivePermanents(filterPlains,
this.getControllerId(), this.getSourceId(), game).isEmpty()
&& !game.getBattlefield().getActivePermanents(filterForest,
this.getControllerId(), this.getSourceId(), game).isEmpty()) {
for (CombatGroup group : game.getCombat().getGroups()) {
if (isControlledBy(group.getDefenderId())) {
return super.canActivate(playerId, game);
@ -96,37 +94,8 @@ class QasaliAmbusherAbility extends ActivatedAbilityImpl {
@Override
public String getRule() {
return "If a creature is attacking you and you control a Forest and a Plains, you may cast {this} without paying its mana cost and as though it had flash.";
}
}
class QasaliAmbusherEffect extends OneShotEffect {
public QasaliAmbusherEffect() {
super(Outcome.Benefit);
staticText = "";
}
public QasaliAmbusherEffect(final QasaliAmbusherEffect effect) {
super(effect);
}
@Override
public QasaliAmbusherEffect copy() {
return new QasaliAmbusherEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = (Card) game.getObject(source.getSourceId());
if (card != null) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
SpellAbility spellAbility = card.getSpellAbility();
spellAbility.clear();
return controller.cast(spellAbility, game, true, new MageObjectReference(source.getSourceObject(game), game));
}
}
return false;
return "If a creature is attacking you and you control a Forest and "
+ "a Plains, you may cast {this} without paying its mana "
+ "cost and as though it had flash.";
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.r;
import java.util.List;
@ -38,7 +37,9 @@ public final class RashmiEternitiesCrafter extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever you cast your first spell each turn, reveal the top card of your library. If it's a nonland card with converted mana cost less than that spell's, you may cast it without paying its mana cost. If you don't cast the revealed card, put it into your hand.
// Whenever you cast your first spell each turn, reveal the top card of your library.
// If it's a nonland card with converted mana cost less than that spell's, you may cast it
// without paying its mana cost. If you don't cast the revealed card, put it into your hand.
this.addAbility(new RashmiEternitiesCrafterTriggeredAbility(), new SpellsCastWatcher());
}
@ -120,9 +121,14 @@ class RashmiEternitiesCrafterEffect extends OneShotEffect {
if (cmcObject == null
|| card.isLand()
|| card.getConvertedManaCost() >= (int) cmcObject
|| !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)
|| !controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game))) {
controller.moveCards(card, Zone.HAND, source, game);
|| !controller.chooseUse(Outcome.PlayForFree, "Cast " + card.getName() + " without paying its mana cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (!cardWasCast) {
controller.moveCards(card, Zone.HAND, source, game);
}
}
}
return true;

View file

@ -1,4 +1,3 @@
package mage.cards.s;
import java.util.UUID;
@ -38,11 +37,13 @@ import mage.util.CardUtil;
*/
public final class ShellOfTheLastKappa extends CardImpl {
private static final FilterSpell filter = new FilterSpell("instant or sorcery spell that targets you");
private static final FilterSpell filter
= new FilterSpell("instant or sorcery spell that targets you");
static {
filter.add(new TargetYouPredicate());
filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY)));
filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT),
new CardTypePredicate(CardType.SORCERY)));
}
public ShellOfTheLastKappa(UUID ownerId, CardSetInfo setInfo) {
@ -50,13 +51,16 @@ public final class ShellOfTheLastKappa extends CardImpl {
addSuperType(SuperType.LEGENDARY);
// {3}, {tap}: Exile target instant or sorcery spell that targets you.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShellOfTheLastKappaEffect(), new ManaCostsImpl("{3}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new ShellOfTheLastKappaEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
Target target = new TargetSpell(filter);
ability.addTarget(target);
this.addAbility(ability);
// {3}, {tap}, Sacrifice Shell of the Last Kappa: You may cast a card exiled with Shell of the Last Kappa without paying its mana cost.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShellOfTheLastKappaCastEffect(), new ManaCostsImpl("{3}"));
// {3}, {tap}, Sacrifice Shell of the Last Kappa: You may cast a card
// exiled with Shell of the Last Kappa without paying its mana cost.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new ShellOfTheLastKappaCastEffect(), new ManaCostsImpl("{3}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@ -100,7 +104,11 @@ class ShellOfTheLastKappaEffect extends OneShotEffect {
if (sourcePermanent != null) {
game.getStack().counter(spell.getId(), source.getSourceId(), game);
Card card = spell.getCard();
card.moveToExile(CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game);
if (card != null) {
return card.moveToExile(CardUtil.getExileZoneId(game, source.getSourceId(),
sourcePermanent.getZoneChangeCounter(game)),
sourcePermanent.getName(), source.getSourceId(), game);
}
}
}
return false;
@ -126,13 +134,23 @@ class ShellOfTheLastKappaCastEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
TargetCardInExile target = new TargetCardInExile(new FilterCard(), CardUtil.getCardExileZoneId(game, source));
if (controller.choose(Outcome.PlayForFree, game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)), target, game)) {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null
&& sourcePermanent != null) {
TargetCardInExile target = new TargetCardInExile(new FilterCard(),
CardUtil.getExileZoneId(game, source.getSourceId(), sourcePermanent.getZoneChangeCounter(game)));
if (controller.choose(Outcome.PlayForFree, game.getExile()
.getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(),
sourcePermanent.getZoneChangeCounter(game))), target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
game.getExile().removeCard(card, game);
return controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
if (card != null
&& controller.chooseUse(outcome, "Do you wish to cast card exiled with "
+ sourcePermanent.getLogName() + "?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return cardWasCast;
}
}
}

View file

@ -18,6 +18,7 @@ import mage.players.Player;
import mage.target.TargetCard;
import java.util.UUID;
import mage.MageObject;
/**
* @author LevelX2
@ -35,7 +36,8 @@ public final class SilentBladeOni extends CardImpl {
// Ninjutsu {4}{U}{B}
this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{4}{U}{B}")));
// Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand. You may cast a nonland card in it without paying that card's mana cost.
// Whenever Silent-Blade Oni deals combat damage to a player, look at that player's hand.
// You may cast a nonland card in it without paying that card's mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new SilentBladeOniEffect(), false, true
));
@ -55,8 +57,8 @@ class SilentBladeOniEffect extends OneShotEffect {
SilentBladeOniEffect() {
super(Outcome.PlayForFree);
this.staticText = "look at that player's hand. " +
"You may cast a nonland card in it without paying that card's mana cost";
this.staticText = "look at that player's hand. "
+ "You may cast a nonland card in it without paying that card's mana cost";
}
private SilentBladeOniEffect(final SilentBladeOniEffect effect) {
@ -72,7 +74,8 @@ class SilentBladeOniEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (opponent == null || controller == null) {
if (opponent == null
|| controller == null) {
return false;
}
Cards cardsInHand = new CardsImpl();
@ -88,8 +91,13 @@ class SilentBladeOniEffect extends OneShotEffect {
return true;
}
Card card = game.getCard(target.getFirstTarget());
return card != null && controller.cast(
card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game)
);
if (card == null) {
return false;
}
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
return cardWasCast;
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.s;
import java.util.UUID;
@ -30,7 +29,7 @@ import mage.util.CardUtil;
* @author emerald000
*/
public final class SpellweaverHelix extends CardImpl {
private static final FilterCard filter = new FilterCard("sorcery cards from a single graveyard");
static {
@ -191,7 +190,10 @@ class SpellweaverHelixCastEffect extends OneShotEffect {
if (controller.chooseUse(Outcome.Copy, "Copy " + card.getIdName(), source, game)) {
Card copy = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + copy.getIdName() + " without paying its mana cost?", source, game)) {
controller.cast(copy.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(copy, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), null);
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.t;
import java.util.UUID;
@ -32,10 +31,13 @@ public final class ThunderbladeCharge extends CardImpl {
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addTarget(new TargetAnyTarget());
// Whenever one or more creatures you control deal combat damage to a player, if Thunderblade Charge is in your graveyard, you may pay {2}{R}{R}{R}. If you do, you may cast it without paying its mana cost.
// Whenever one or more creatures you control deal combat damage to a player,
// if Thunderblade Charge is in your graveyard, you may pay {2}{R}{R}{R}.
// If you do, you may cast it without paying its mana cost.
this.addAbility(new ControlledCreaturesDealCombatDamagePlayerTriggeredAbility(Zone.GRAVEYARD,
new DoIfCostPaid(new ThunderbladeChargeCastEffect(), new ManaCostsImpl("{2}{R}{R}{R}"))
.setText("if {this} is in your graveyard, you may pay {2}{R}{R}{R}. If you do, you may cast it without paying its mana cost")));
.setText("if {this} is in your graveyard, you may pay {2}{R}{R}{R}. "
+ "If you do, you may cast it without paying its mana cost")));
}
public ThunderbladeCharge(final ThunderbladeCharge card) {
@ -71,8 +73,11 @@ class ThunderbladeChargeCastEffect extends OneShotEffect {
if (controller != null
&& sourceCard != null
&& Zone.GRAVEYARD == game.getState().getZone(sourceCard.getId())) {
controller.cast(sourceCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
return true;
game.getState().setValue("PlayFromNotOwnHandZone" + sourceCard.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(sourceCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + sourceCard.getId(), null);
return cardWasCast;
}
return false;
}

View file

@ -37,7 +37,7 @@ public final class TrappedInTheTower extends CardImpl {
// Enchant creature without flying
TargetPermanent auraTarget = new TargetPermanent(filter);
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);

View file

@ -16,6 +16,7 @@ import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
import mage.MageObject;
/**
* @author fireshoes
@ -48,8 +49,10 @@ class TreasureKeeperEffect extends OneShotEffect {
public TreasureKeeperEffect() {
super(Outcome.PlayForFree);
this.staticText = "reveal cards from the top of your library until you reveal a nonland card with converted mana cost 3 or less. "
+ "You may cast that card without paying its mana cost. Put all revealed cards not cast this way on the bottom of your library in a random order";
this.staticText = "reveal cards from the top of your library until you reveal a "
+ "nonland card with converted mana cost 3 or less. "
+ "You may cast that card without paying its mana cost. Put all revealed "
+ "cards not cast this way on the bottom of your library in a random order";
}
public TreasureKeeperEffect(TreasureKeeperEffect effect) {
@ -58,8 +61,10 @@ class TreasureKeeperEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Boolean cardWasCast = false;
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (controller != null
&& !controller.getLibrary().isEmptyDraw()) {
CardsImpl toReveal = new CardsImpl();
Card nonLandCard = null;
for (Card card : controller.getLibrary().getCards(game)) {
@ -70,14 +75,19 @@ class TreasureKeeperEffect extends OneShotEffect {
}
}
controller.revealCards(source, toReveal, game);
if (nonLandCard != null && controller.chooseUse(outcome, "Cast " + nonLandCard.getLogName() + " without paying its mana cost?", source, game)) {
controller.cast(nonLandCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
toReveal.remove(nonLandCard);
if (nonLandCard != null
&& controller.chooseUse(Outcome.PlayForFree, "Cast " + nonLandCard.getLogName() + " without paying its mana cost?", source, game)) {
game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), Boolean.TRUE);
cardWasCast = controller.cast(controller.chooseAbilityForCast(nonLandCard, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + nonLandCard.getId(), null);
if (cardWasCast) {
toReveal.remove(nonLandCard);
}
}
controller.putCardsOnBottomOfLibrary(toReveal, game, source, false);
return true;
}
return false;
return cardWasCast;
}
@Override

View file

@ -1,4 +1,3 @@
package mage.cards.v;
import java.util.UUID;
@ -29,7 +28,8 @@ public final class VillainousWealth extends CardImpl {
public VillainousWealth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{G}{U}");
// Target opponent exiles the top X cards of their library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost.
// Target opponent exiles the top X cards of their library. You may cast any number of nonland cards
// with converted mana cost X or less from among them without paying their mana cost.
this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new VillainousWealthEffect());
@ -49,7 +49,9 @@ class VillainousWealthEffect extends OneShotEffect {
public VillainousWealthEffect() {
super(Outcome.PlayForFree);
this.staticText = "Target opponent exiles the top X cards of their library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost";
this.staticText = "Target opponent exiles the top X cards of their library. "
+ "You may cast any number of nonland cards with converted mana cost X "
+ "or less from among them without paying their mana cost";
}
public VillainousWealthEffect(final VillainousWealthEffect effect) {
@ -74,7 +76,8 @@ class VillainousWealthEffect extends OneShotEffect {
Cards cardsToExile = new CardsImpl();
cardsToExile.addAll(player.getLibrary().getTopCards(game, source.getManaCostsToPay().getX()));
controller.moveCards(cardsToExile, Zone.EXILED, source, game);
if (controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() + " without paying its mana cost?", source, game)) {
if (controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName()
+ " without paying its mana cost?", source, game)) {
OuterLoop:
while (cardsToExile.count(filter, game) > 0) {
if (!controller.canRespond()) {
@ -82,11 +85,17 @@ class VillainousWealthEffect extends OneShotEffect {
}
TargetCardInExile target = new TargetCardInExile(0, 1, filter, exileId, false);
target.setNotTarget(true);
while (cardsToExile.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
while (cardsToExile.count(filter, game) > 0
&& controller.choose(Outcome.PlayForFree, cardsToExile, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
cardsToExile.remove(card);
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
if (cardWasCast) {
cardsToExile.remove(card);
}
} else {
break OuterLoop;
}

View file

@ -14,12 +14,10 @@ import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInGraveyard;
import org.apache.log4j.Logger;
import java.util.UUID;
import mage.players.PlayerList;
import mage.target.common.TargetCardInGraveyard;
import mage.util.RandomUtil;
/**
* @author TheElk801
@ -55,9 +53,9 @@ public final class WildfireDevils extends CardImpl {
class WildfireDevilsEffect extends OneShotEffect {
WildfireDevilsEffect() {
super(Outcome.Benefit);
staticText = "choose a player at random. That player exiles an instant or sorcery card from their graveyard. " +
"Copy that card. You may cast the copy without paying its mana cost.";
super(Outcome.Neutral);
staticText = "choose a player at random. That player exiles an instant or sorcery card from their graveyard. "
+ "Copy that card. You may cast the copy without paying its mana cost.";
}
private WildfireDevilsEffect(final WildfireDevilsEffect effect) {
@ -75,23 +73,28 @@ class WildfireDevilsEffect extends OneShotEffect {
if (controller == null) {
return false;
}
TargetPlayer targetPlayer = new TargetPlayer();
targetPlayer.setRandom(true);
targetPlayer.setNotTarget(true);
if (!controller.choose(outcome, targetPlayer, source.getSourceId(), game)) {
PlayerList players = game.getState().getPlayersInRange(controller.getId(), game);
if (players == null) {
return false;
}
Player player = game.getPlayer(targetPlayer.getFirstTarget());
if (player == null || player.getGraveyard().getCards(game).stream().noneMatch(Card::isInstantOrSorcery)) {
Player randomPlayer = game.getPlayer(players.get(RandomUtil.nextInt(players.size())));
if (randomPlayer == null) {
return false;
}
TargetCard targetCard = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY);
game.informPlayers("The chosen random player is " + randomPlayer.getLogName());
if (randomPlayer.getGraveyard().getCards(game).stream().noneMatch(Card::isInstantOrSorcery)) {
return false;
}
TargetCardInGraveyard targetCard = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY);
targetCard.setNotTarget(true);
if (!player.choose(outcome, player.getGraveyard(), targetCard, game)) {
if (!randomPlayer.choose(Outcome.Discard, randomPlayer.getGraveyard(), targetCard, game)) {
return false;
}
Card card = game.getCard(targetCard.getFirstTarget());
player.moveCards(card, Zone.EXILED, source, game);
if (card == null) {
return false;
}
randomPlayer.moveCards(card, Zone.EXILED, source, game);
if (game.getState().getZone(card.getId()) != Zone.EXILED) {
return false;
}
@ -99,15 +102,14 @@ class WildfireDevilsEffect extends OneShotEffect {
if (copiedCard == null) {
return false;
}
game.getExile().add(source.getSourceId(), "", card);
game.setZone(copiedCard.getId(), Zone.EXILED);
if (!controller.chooseUse(outcome, "Cast the exiled card?", source, game)) {
return true;
randomPlayer.moveCards(copiedCard, Zone.EXILED, source, game);
if (!controller.chooseUse(outcome, "Cast the copy of the exiled card?", source, game)) {
return false;
}
if (copiedCard.getSpellAbility() == null) {
Logger.getLogger(WildfireDevilsEffect.class).error("Wildfire Devils: spell ability == null " + copiedCard.getName());
return true;
}
return controller.cast(copiedCard.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), Boolean.TRUE);
Boolean cardWasCast = controller.cast(controller.chooseAbilityForCast(copiedCard, game, true), game, true,
new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + copiedCard.getId(), null);
return cardWasCast;
}
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.w;
import java.util.UUID;
@ -56,7 +55,8 @@ class WildfireEternalCastEffect extends OneShotEffect {
public WildfireEternalCastEffect() {
super(Outcome.Benefit);
this.staticText = "you may cast an instant or sorcery card from your hand without paying its mana cost";
this.staticText = "you may cast an instant or sorcery card "
+ "from your hand without paying its mana cost";
}
public WildfireEternalCastEffect(final WildfireEternalCastEffect effect) {
@ -74,12 +74,17 @@ class WildfireEternalCastEffect extends OneShotEffect {
if (controller != null) {
FilterCard filter = new FilterInstantOrSorceryCard();
int cardsToCast = controller.getHand().count(filter, source.getControllerId(), source.getSourceId(), game);
if (cardsToCast > 0 && controller.chooseUse(outcome, "Cast an instant or sorcery card from your hand without paying its mana cost?", source, game)) {
if (cardsToCast > 0
&& controller.chooseUse(outcome, "Cast an instant or sorcery card from your "
+ "hand without paying its mana cost?", source, game)) {
TargetCardInHand target = new TargetCardInHand(filter);
controller.chooseTarget(outcome, target, source, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
}
}
return true;

View file

@ -46,7 +46,10 @@ public final class WrexialTheRisenDeep extends CardImpl {
// Swampwalk
this.addAbility(new SwampwalkAbility());
// Whenever Wrexial, the Risen Deep deals combat damage to a player, you may cast target instant or sorcery card from that player's graveyard without paying its mana cost. If that card would be put into a graveyard this turn, exile it instead.
// Whenever Wrexial, the Risen Deep deals combat damage to a player,
// you may cast target instant or sorcery card from that player's graveyard
// without paying its mana cost. If that card would be put into a graveyard
// this turn, exile it instead.
this.addAbility(new WrexialTheRisenDeepTriggeredAbility());
}
@ -89,7 +92,8 @@ class WrexialTheRisenDeepTriggeredAbility extends TriggeredAbilityImpl {
if (damagedPlayer == null) {
return false;
}
FilterCard filter = new FilterCard("target instant or sorcery card from " + damagedPlayer.getName() + "'s graveyard");
FilterCard filter = new FilterCard("target instant or sorcery card from "
+ damagedPlayer.getName() + "'s graveyard");
filter.add(new OwnerIdPredicate(damagedPlayer.getId()));
filter.add(Predicates.or(
new CardTypePredicate(CardType.INSTANT),
@ -132,10 +136,14 @@ class WrexialTheRisenDeepEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card card = game.getCard(source.getFirstTarget());
if (controller == null || card == null) {
if (controller == null
|| card == null) {
return false;
}
controller.cast(card.getSpellAbility(), game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
controller.cast(controller.chooseAbilityForCast(card, game, true),
game, true, new MageObjectReference(source.getSourceObject(game), game));
game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
game.addEffect(new WrexialReplacementEffect(card.getId()), source);
return true;
}

View file

@ -38,6 +38,7 @@ public final class TherosBeyondDeath extends ExpansionSet {
cards.add(new SetCardInfo("Elspeth, Undaunted Hero", 270, Rarity.MYTHIC, mage.cards.e.ElspethUndauntedHero.class));
cards.add(new SetCardInfo("Forest", 254, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Grasping Giant", 288, Rarity.RARE, mage.cards.g.GraspingGiant.class));
cards.add(new SetCardInfo("Gray Merchant of Asphodel", 99, Rarity.UNCOMMON, mage.cards.g.GrayMerchantOfAsphodel.class));
cards.add(new SetCardInfo("Hero of the Winds", 23, Rarity.UNCOMMON, mage.cards.h.HeroOfTheWinds.class));
cards.add(new SetCardInfo("Indomitable Will", 25, Rarity.COMMON, mage.cards.i.IndomitableWill.class));
cards.add(new SetCardInfo("Inevitable End", 102, Rarity.UNCOMMON, mage.cards.i.InevitableEnd.class));

View file

@ -65,8 +65,8 @@ public class SpellAbility extends ActivatedAbilityImpl {
if (object == null) {
return false;
}
if (game.getState().getValue("CastFromExileEnabled" + object.getId()) != null) {
return (Boolean) game.getState().getValue("CastFromExileEnabled" + object.getId()); // card like Chandra, Torch of Defiance +1 loyal ability)
if (game.getState().getValue("PlayFromNotOwnHandZone" + object.getId()) != null) {
return (Boolean) game.getState().getValue("PlayFromNotOwnHandZone" + object.getId()); // card like Chandra, Torch of Defiance +1 loyal ability)
}
return null != game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST_AS_INSTANT, this, playerId, game) // check this first to allow Offering in main phase
|| timing == TimingRule.INSTANT

View file

@ -110,6 +110,24 @@ public final class StaticFilters {
FILTER_CARD_FROM_YOUR_GRAVEYARD.setLockedFilter(true);
}
public static final FilterNoncreatureCard FILTER_CARD_NON_CREATURE = new FilterNoncreatureCard();
static {
FILTER_CARD_NON_CREATURE.setLockedFilter(true);
}
public static final FilterNoncreatureCard FILTER_CARD_A_NON_CREATURE = new FilterNoncreatureCard("a noncreature card");
static {
FILTER_CARD_A_NON_CREATURE.setLockedFilter(true);
}
public static final FilterNoncreatureCard FILTER_CARDS_NON_CREATURE = new FilterNoncreatureCard("noncreature cards");
static {
FILTER_CARDS_NON_CREATURE.setLockedFilter(true);
}
public static final FilterLandCard FILTER_CARD_LAND = new FilterLandCard();
static {

View file

@ -0,0 +1,30 @@
package mage.filter.common;
import mage.constants.CardType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
/**
* @author ssouders412
*/
public class FilterNoncreatureCard extends FilterCard {
public FilterNoncreatureCard() {
this("noncreature card");
}
public FilterNoncreatureCard(String name) {
super(name);
this.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public FilterNoncreatureCard(final FilterNoncreatureCard filter) {
super(filter);
}
@Override
public FilterNoncreatureCard copy() {
return new FilterNoncreatureCard(this);
}
}

View file

@ -36444,13 +36444,16 @@ Nyxborn Courser|Theros Beyond Death|29|C|{1}{W}{W}|Enchantment Creature - Centau
Revoke Existence|Theros Beyond Death|34|C|{1}{W}|Sorcery|||Exile target artifact or enchantment.|
Eidolon of Philosophy|Theros Beyond Death|48|C|{U}|Enchantment Creature - Spirit|1|2|{6}{U}, Sacrifice Eidolon of Philosophy: Draw three cards.|
Memory Drain|Theros Beyond Death|54|C|{2}{U}{U}|Instant|||Counter target spell. Scry 2.|
Gray Merchant of Asphodel|Theros Beyond Death|99|U|{3}{B}{B}|Creature - Zombie|2|4|When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.|
Inevitable End|Theros Beyond Death|102|U|{2}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature has "At the beginning of your upkeep, sacrifice a creature."|
Mire's Grasp|Theros Beyond Death|106|C|{1}{B}|Enchantment - Aura|||Enchant creature$Enchanted creature gets -3/-3.|
The Akroan War|Theros Beyond Death|124|R|{3}{R}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Gain control of target creature for as long as The Akroan War remains on the battlefield.$II — Until your next turn, creatures your opponents control attack each combat if able.$III — Each tapped creature deals damage to itself equal to its power.|
Underworld Rage-Hound|Theros Beyond Death|163|C|{1}{R}|Creature - Elemental Hound|3|1|Underworld Rage-Hound attacks each combat if able.$Escape—{3}{R}, Exile three other cards from your graveyard.$Underworld Rage-Hound escapes with a +1/+1 counter on it.|
The Binding of the Titans|Theros Beyond Death|166|U|{1}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I — Each player puts the top three cards of their library into their graveyard.$II — Exile up to two target cards from graveyards. For each creature card exiled this way, you gain 1 life.$III — Return target creature or land card from your graveyard to your hand.|
Klothys's Design|Theros Beyond Death|176|U|{5}{G}|Sorcery|||Creatures you control get +X/+X until end of turn, where X is your devotion to green.|
Nyxborn Colossus|Theros Beyond Death|191|C|{3}{G}{G}{G}|Enchantment Creature - Giant|6|7||
Setessan Champion|Theros Beyond Death|198|R|{2}{G}|Creature - Human Warrior|1|3|Constellation — Whenever an enchantment enters the battlefield under your control, put a +1/+1 counter on Setessan Champion and draw a card.|
Allure of the Unknown|Theros Beyond Death|207|R|{3}{B}{R}|Sorcery|||Reveal the top six cards of your library. An opponent exiles a nonland card from among them, then you put the rest into your hand. That opponent may cast the exiled card without paying its mana cost.|
Ashiok, Nightmare Muse|Theros Beyond Death|208|M|{3}{U}{B}|Legendary Planeswalker - Ashiok|5|+1: Create a 2/3 blue and black Nightmare creature token with "Whenever this creature attacks or blocks, each opponent exiles the top two cards of their library."$3: Return target nonland permanent to its owner's hand, then that player exiles a card from their hand.$7: You may cast up to three face-up cards your opponents own from exile without paying their mana costs.|
Klothys, God of Destiny|Theros Beyond Death|220|M|{1}{R}{G}|Legendary Enchantment Creature - God|4|5|Indestructible$As long as your devotion to red and green is less than seven, Klothys isn't a creature.$At the beginning of your precombat main phase, exile target card from a graveyard. If it was a land card, add {R} or {G}. Otherwise, you gain 2 life and Klothys deals 2 damage to each opponent.|
Staggering Insight|Theros Beyond Death|228|U|{W}{U}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 and has lifelink and "Whenever this creature deals combat damage to a player, draw a card."|