Improve DiscardCardYouChooseTargetEffect and use it for many cards that were using custom effects

This commit is contained in:
Alex W. Jackson 2022-01-28 13:43:46 -05:00
parent 1b98b9fde3
commit 2941487219
26 changed files with 168 additions and 766 deletions

View file

@ -30,7 +30,7 @@ public final class AcquisitionsExpert extends CardImpl {
// When Acquisitions Expert enters the battlefield, target opponent reveals a number of cards from their hand equal to the number of creatures in your party. You choose one of those cards. That player discards that card. // When Acquisitions Expert enters the battlefield, target opponent reveals a number of cards from their hand equal to the number of creatures in your party. You choose one of those cards. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility( Ability ability = new EntersBattlefieldTriggeredAbility(
new DiscardCardYouChooseTargetEffect(TargetController.ANY, PartyCount.instance) new DiscardCardYouChooseTargetEffect(TargetController.OPPONENT, PartyCount.instance)
.setText("target opponent reveals a number of cards from their hand " + .setText("target opponent reveals a number of cards from their hand " +
"equal to the number of creatures in your party. You choose one of those cards. " + "equal to the number of creatures in your party. You choose one of those cards. " +
"That player discards that card. " + PartyCount.getReminder()) "That player discards that card. " + PartyCount.getReminder())

View file

@ -1,22 +1,19 @@
package mage.cards.b; package mage.cards.b;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AllyEntersBattlefieldTriggeredAbility; import mage.abilities.common.AllyEntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.dynamicvalue.DynamicValue;
import mage.cards.*; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
/** /**
@ -25,6 +22,8 @@ import mage.target.TargetPlayer;
*/ */
public final class BalaGedThief extends CardImpl { public final class BalaGedThief extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.ALLY, "Allies you control"), null);
public BalaGedThief(UUID ownerId, CardSetInfo setInfo) { public BalaGedThief(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
this.subtype.add(SubType.HUMAN, SubType.ROGUE, SubType.ALLY); this.subtype.add(SubType.HUMAN, SubType.ROGUE, SubType.ALLY);
@ -32,8 +31,10 @@ public final class BalaGedThief extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Whenever Bala Ged Thief or another Ally enters the battlefield under your control, target player reveals a number of cards from their hand equal to the number of Allies you control. You choose one of them. That player discards that card. // Whenever Bala Ged Thief or another Ally enters the battlefield under your control,
Ability ability = new AllyEntersBattlefieldTriggeredAbility(new BalaGedThiefEffect(), false); // target player reveals a number of cards from their hand equal to the number of Allies you control.
// You choose one of them. That player discards that card.
Ability ability = new AllyEntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, xValue), false);
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
} }
@ -47,67 +48,3 @@ public final class BalaGedThief extends CardImpl {
return new BalaGedThief(this); return new BalaGedThief(this);
} }
} }
class BalaGedThiefEffect extends OneShotEffect {
public BalaGedThiefEffect() {
super(Outcome.Discard);
this.staticText = "target player reveals a number of cards from their hand equal to the number of Allies you control. You choose one of them. That player discards that card";
}
public BalaGedThiefEffect(final BalaGedThiefEffect effect) {
super(effect);
}
@Override
public BalaGedThiefEffect copy() {
return new BalaGedThiefEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer == null) {
return false;
}
Player you = game.getPlayer(source.getControllerId());
FilterControlledPermanent filter = new FilterControlledPermanent();
filter.add(SubType.ALLY.getPredicate());
int numberOfAllies = game.getBattlefield().countAll(filter, you.getId(), game);
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
int count = Math.min(cardsInHand.size(), numberOfAllies);
TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard());
Cards revealedCards = new CardsImpl();
if (targetPlayer.choose(Outcome.DrawCard, cardsInHand, target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = game.getCard(targetId);
if (card != null) {
revealedCards.add(card);
}
}
}
TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Bala Ged Thief", revealedCards, game);
you.choose(Outcome.Neutral, revealedCards, targetInHand, game);
Card card = revealedCards.get(targetInHand.getFirstTarget(), game);
if (card != null) {
targetPlayer.discard(card, false, source, game);
game.informPlayers("Bala Ged Thief: " + targetPlayer.getLogName() + " discarded " + card.getName());
}
}
return true;
}
}

View file

@ -21,7 +21,7 @@ public final class Brainbite extends CardImpl {
// Target opponent reveals their hand. You choose a card from it. That player discards that card. // Target opponent reveals their hand. You choose a card from it. That player discards that card.
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect()); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect());
// Draw a card. // Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
} }

View file

@ -1,4 +1,3 @@
package mage.cards.c; package mage.cards.c;
import mage.MageInt; import mage.MageInt;
@ -7,19 +6,14 @@ import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -36,8 +30,10 @@ public final class CabalInterrogator extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// {X}{B}, {tap}: Target player reveals X cards from their hand and you choose one of them. That player discards that card. // {X}{B}, {tap}: Target player reveals X cards from their hand and you choose one of them. That player discards that card.
// Activate this ability only any time you could cast a sorcery. // Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new CabalInterrogatorEffect(), new ManaCostsImpl("{X}{B}")); Ability ability = new ActivateAsSorceryActivatedAbility(
new DiscardCardYouChooseTargetEffect(TargetController.ANY, ManacostVariableValue.REGULAR),
new ManaCostsImpl("{X}{B}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
@ -52,71 +48,3 @@ public final class CabalInterrogator extends CardImpl {
return new CabalInterrogator(this); return new CabalInterrogator(this);
} }
} }
class CabalInterrogatorEffect extends OneShotEffect {
public CabalInterrogatorEffect() {
super(Outcome.Discard);
this.staticText = "Target player reveals X cards from their hand and you choose one of them. That player discards that card";
}
public CabalInterrogatorEffect(final CabalInterrogatorEffect effect) {
super(effect);
}
@Override
public CabalInterrogatorEffect copy() {
return new CabalInterrogatorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
if (targetPlayer == null || controller == null) {
return false;
}
int amountToReveal = (ManacostVariableValue.REGULAR).calculate(game, source, this);
if (amountToReveal < 1) {
return true;
}
Cards revealedCards = new CardsImpl();
if (targetPlayer.getHand().size() > amountToReveal) {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
TargetCard target = new TargetCard(amountToReveal, Zone.HAND, new FilterCard());
if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = game.getCard(targetId);
if (card != null) {
revealedCards.add(card);
}
}
}
} else {
revealedCards.addAll(targetPlayer.getHand());
}
TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Cabal Interrogator", revealedCards, game);
Card card = null;
if (revealedCards.size() > 1) {
controller.choose(Outcome.Discard, revealedCards, targetInHand, game);
card = revealedCards.get(targetInHand.getFirstTarget(), game);
} else {
card = revealedCards.getRandom(game);
}
targetPlayer.discard(card, false, source, game);
}
return true;
}
}

View file

@ -4,19 +4,14 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.DevotionCount; import mage.abilities.dynamicvalue.common.DevotionCount;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -34,7 +29,7 @@ public final class DiscipleOfPhenax extends CardImpl {
// When Disciple of Phenax enters the battlefield, target player reveals a number of cards // When Disciple of Phenax enters the battlefield, target player reveals a number of cards
// from their hand equal to your devotion to black. You choose one of them. That player discards that card. // from their hand equal to your devotion to black. You choose one of them. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscipleOfPhenaxEffect(), false); Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, DevotionCount.B));
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
ability.addHint(DevotionCount.B.getHint()); ability.addHint(DevotionCount.B.getHint());
this.addAbility(ability); this.addAbility(ability);
@ -50,68 +45,3 @@ public final class DiscipleOfPhenax extends CardImpl {
return new DiscipleOfPhenax(this); return new DiscipleOfPhenax(this);
} }
} }
class DiscipleOfPhenaxEffect extends OneShotEffect {
DiscipleOfPhenaxEffect() {
super(Outcome.Discard);
staticText = "target player reveals a number of cards from their hand "
+ "equal to your devotion to black. You choose one of "
+ "them. That player discards that card";
}
private DiscipleOfPhenaxEffect(final DiscipleOfPhenaxEffect effect) {
super(effect);
}
@Override
public DiscipleOfPhenaxEffect copy() {
return new DiscipleOfPhenaxEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int devotion = DevotionCount.B.calculate(game, source, this);
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if (devotion <= 0 || targetPlayer == null) {
return false;
}
Cards revealedCards = new CardsImpl();
int amount = Math.min(targetPlayer.getHand().size(), devotion);
if (targetPlayer.getHand().size() > amount) {
FilterCard filter = new FilterCard("card in target player's hand");
TargetCard chosenCards = new TargetCard(amount, amount, Zone.HAND, filter);
chosenCards.setNotTarget(true);
if (chosenCards.canChoose(source.getSourceId(), targetPlayer.getId(), game)
&& targetPlayer.choose(Outcome.Discard, targetPlayer.getHand(), chosenCards, game)) {
if (!chosenCards.getTargets().isEmpty()) {
List<UUID> targets = chosenCards.getTargets();
for (UUID targetid : targets) {
Card card = game.getCard(targetid);
if (card != null) {
revealedCards.add(card);
}
}
}
}
} else {
revealedCards.addAll(targetPlayer.getHand());
}
if (revealedCards.isEmpty()) {
return true;
}
targetPlayer.revealCards("Disciple of Phenax", revealedCards, game);
Player you = game.getPlayer(source.getControllerId());
if (you == null) {
return false;
}
TargetCard yourChoice = new TargetCard(Zone.HAND, new FilterCard());
yourChoice.setNotTarget(true);
if (you.choose(Outcome.Benefit, revealedCards, yourChoice, game)) {
Card card = targetPlayer.getHand().get(yourChoice.getFirstTarget(), game);
return targetPlayer.discard(card, false, source, game);
}
return true;
}
}

View file

@ -7,8 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.filter.FilterCard; import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
/** /**
@ -16,19 +15,13 @@ import mage.target.TargetPlayer;
*/ */
public final class Distress extends CardImpl { public final class Distress extends CardImpl {
private static final FilterCard filter = new FilterCard("nonland card");
static {
filter.add(Predicates.not(CardType.LAND.getPredicate()));
}
public Distress(UUID ownerId, CardSetInfo setInfo) { public Distress(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}{B}"); super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}{B}");
// Target player reveals their hand. You choose a nonland card from it. That player discards that card. // Target player reveals their hand. You choose a nonland card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY));
} }
private Distress(final Distress card) { private Distress(final Distress card) {

View file

@ -1,4 +1,3 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID; import java.util.UUID;
@ -7,8 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.FilterCard; import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
@ -19,19 +17,12 @@ import mage.target.TargetPlayer;
*/ */
public final class Divest extends CardImpl { public final class Divest extends CardImpl {
private static final FilterCard filter = new FilterCard("an artifact or creature card");
static {
filter.add(Predicates.or(CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate()));
}
public Divest(UUID ownerId, CardSetInfo setInfo) { public Divest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Target player reveals their hand. You choose an artifact or creature card from it. That player discards that card. // Target player reveals their hand. You choose an artifact or creature card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_ARTIFACT_OR_CREATURE, TargetController.ANY));
} }
private Divest(final Divest card) { private Divest(final Divest card) {

View file

@ -3,19 +3,14 @@ package mage.cards.d;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.CleaveAbility; import mage.abilities.keyword.CleaveAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterNonlandCard; import mage.filter.common.FilterNonlandCard;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
/** /**
@ -24,7 +19,7 @@ import mage.target.TargetPlayer;
*/ */
public final class DreadFugue extends CardImpl { public final class DreadFugue extends CardImpl {
private static final FilterNonlandCard filter = new FilterNonlandCard("nonland card [with mana value 2 or less]"); private static final FilterNonlandCard filter = new FilterNonlandCard("nonland card from it [with mana value 2 or less]");
static { static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3)); filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3));
@ -34,13 +29,13 @@ public final class DreadFugue extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
// Cleave {2}{B} // Cleave {2}{B}
Ability ability = new CleaveAbility(this, new DreadFugueEffect(StaticFilters.FILTER_CARD_NON_LAND), "{2}{B}"); Ability ability = new CleaveAbility(this, new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY), "{2}{B}");
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
// Target player reveals their hand. You may choose a nonland card from it [with mana value 2 or less]. That player discards that card. // Target player reveals their hand. Choose a nonland card from it [with mana value 2 or less]. That player discards that card.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DreadFugueEffect(filter)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY));
} }
private DreadFugue(final DreadFugue card) { private DreadFugue(final DreadFugue card) {
@ -52,43 +47,3 @@ public final class DreadFugue extends CardImpl {
return new DreadFugue(this); return new DreadFugue(this);
} }
} }
class DreadFugueEffect extends OneShotEffect {
private final FilterCard filter;
public DreadFugueEffect(FilterCard filter) {
super(Outcome.Discard);
this.filter = filter;
staticText = "Target player reveals their hand. You choose a nonland card from it [with mana value 2 or less]. That player discards that card";
}
private DreadFugueEffect(final DreadFugueEffect effect) {
super(effect);
this.filter = effect.filter;
}
@Override
public DreadFugueEffect copy() {
return new DreadFugueEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
if (targetPlayer == null || controller == null) {
return false;
}
Card sourceCard = game.getCard(source.getSourceId());
targetPlayer.revealCards(sourceCard != null ? sourceCard.getIdName() + " ("
+ sourceCard.getZoneChangeCounter(game) + ')' : "Discard", targetPlayer.getHand(), game);
TargetCard target = new TargetCard(0, 1, Zone.HAND, filter);
controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game);
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
targetPlayer.discard(card, false, source, game);
}
return true;
}
}

View file

@ -7,9 +7,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.target.common.TargetOpponent; import mage.target.TargetPlayer;
/** /**
* *
@ -28,8 +29,8 @@ public final class Encroach extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}");
// Target player reveals their hand. You choose a nonbasic land card from it. That player discards that card. // Target player reveals their hand. You choose a nonbasic land card from it. That player discards that card.
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetPlayer());
} }
private Encroach(final Encroach card) { private Encroach(final Encroach card) {

View file

@ -1,23 +1,16 @@
package mage.cards.e; package mage.cards.e;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.Card; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
@ -36,11 +29,14 @@ public final class EntomberExarch extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// When Entomber Exarch enters the battlefield, choose one - Return target creature card from your graveyard to your hand; or target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card. // When Entomber Exarch enters the battlefield, choose one
// Return target creature card from your graveyard to your hand
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false); Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), false);
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
// Target opponent reveals their hand. You choose a noncreature card from it. That player discards that card.
Mode mode = new Mode(); Mode mode = new Mode();
mode.addEffect(new EntomberExarchEffect()); mode.addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_CREATURE));
mode.addTarget(new TargetOpponent()); mode.addTarget(new TargetOpponent());
ability.addMode(mode); ability.addMode(mode);
this.addAbility(ability); this.addAbility(ability);
@ -55,38 +51,3 @@ public final class EntomberExarch extends CardImpl {
return new EntomberExarch(this); return new EntomberExarch(this);
} }
} }
class EntomberExarchEffect extends OneShotEffect {
EntomberExarchEffect() {
super(Outcome.Discard);
staticText = "target opponent reveals their hand, you choose a noncreature card from it, then that player discards that card";
}
EntomberExarchEffect(final EntomberExarchEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
player.revealCards("Entomber Exarch", player.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
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, false, source, game);
}
}
}
return false;
}
@Override
public EntomberExarchEffect copy() {
return new EntomberExarchEffect(this);
}
}

View file

@ -3,20 +3,15 @@ package mage.cards.g;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.common.MorbidCondition; import mage.abilities.condition.common.MorbidCondition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.abilities.hint.common.MorbidHint; import mage.abilities.hint.common.MorbidHint;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.TargetController;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand;
import java.util.UUID; import java.util.UUID;
@ -31,7 +26,7 @@ public final class GruesomeDiscovery extends CardImpl {
// Target player discards two cards. // Target player discards two cards.
// <i>Morbid</i> &mdash; If a creature died this turn, instead that player reveals their hand, you choose two cards from it, then that player discards those cards. // <i>Morbid</i> &mdash; If a creature died this turn, instead that player reveals their hand, you choose two cards from it, then that player discards those cards.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new GruesomeDiscoveryEffect(), new DiscardTargetEffect(2), new DiscardCardYouChooseTargetEffect(2, TargetController.ANY), new DiscardTargetEffect(2),
MorbidCondition.instance, "Target player discards two cards. " + MorbidCondition.instance, "Target player discards two cards. " +
"<br><i>Morbid</i> &mdash; If a creature died this turn, instead that player reveals their hand, " + "<br><i>Morbid</i> &mdash; If a creature died this turn, instead that player reveals their hand, " +
"you choose two cards from it, then that player discards those cards" "you choose two cards from it, then that player discards those cards"
@ -49,36 +44,3 @@ public final class GruesomeDiscovery extends CardImpl {
return new GruesomeDiscovery(this); return new GruesomeDiscovery(this);
} }
} }
class GruesomeDiscoveryEffect extends OneShotEffect {
GruesomeDiscoveryEffect() {
super(Outcome.Discard);
}
private GruesomeDiscoveryEffect(final GruesomeDiscoveryEffect effect) {
super(effect);
}
@Override
public GruesomeDiscoveryEffect copy() {
return new GruesomeDiscoveryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (player == null || targetPlayer == null) {
return false;
}
targetPlayer.revealCards(source, targetPlayer.getHand(), game);
if (targetPlayer.getHand().size() <= 2) {
targetPlayer.discard(2, false, false, source, game);
}
TargetCard target = new TargetCardInHand(2, StaticFilters.FILTER_CARD_CARDS);
player.choose(Outcome.Discard, targetPlayer.getHand(), target, game);
targetPlayer.discard(new CardsImpl(target.getTargets()), false, source, game);
return true;
}
}

View file

@ -7,7 +7,7 @@ import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.common.FilterCreatureCard; import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
/** /**
@ -21,7 +21,7 @@ public final class HarshScrutiny extends CardImpl {
// Target opponent reveals their hand. You choose a creature card from it. That player discards that card. Scry 1. // Target opponent reveals their hand. You choose a creature card from it. That player discards that card. Scry 1.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(new FilterCreatureCard("a creature card"))); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_CREATURE));
this.getSpellAbility().addEffect(new ScryEffect(1, false)); this.getSpellAbility().addEffect(new ScryEffect(1, false));
} }

View file

@ -4,16 +4,15 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard;
import mage.util.ManaUtil; import mage.util.ManaUtil;
import java.util.List; import java.util.List;
@ -70,48 +69,11 @@ class HollowSpecterEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (targetPlayer != null && controller != null && controller.chooseUse(Outcome.Benefit, "Do you want to to pay {X}?", source, game)) { if (targetPlayer != null && controller != null && controller.chooseUse(Outcome.Benefit, "Pay {X}?", source, game)) {
int payCount = ManaUtil.playerPaysXGenericMana(true, "Hollow Specter", controller, source, game); int payCount = ManaUtil.playerPaysXGenericMana(true, "Hollow Specter", controller, source, game);
if (payCount > 0) { if (payCount > 0) {
// find to reveal return new DiscardCardYouChooseTargetEffect(TargetController.ANY, payCount).setTargetPointer(targetPointer).apply(game, source);
Cards revealedCards = new CardsImpl();
if (targetPlayer.getHand().size() > payCount) {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
TargetCard target = new TargetCard(payCount, Zone.HAND, new FilterCard());
if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = game.getCard(targetId);
if (card != null) {
revealedCards.add(card);
} }
}
} else {
// take any cards on disconnect
targetPlayer.getHand().stream().limit(payCount).forEach(revealedCards::add);
}
} else {
revealedCards.addAll(targetPlayer.getHand());
}
// select to discard
TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Hollow Specter", revealedCards, game);
Card card;
if (revealedCards.size() > 1) {
controller.choose(Outcome.Discard, revealedCards, targetInHand, game);
card = revealedCards.get(targetInHand.getFirstTarget(), game);
} else {
card = revealedCards.getRandom(game);
}
targetPlayer.discard(card, false, source, game);
}
}
return true; return true;
} }
return false; return false;

View file

@ -1,4 +1,3 @@
package mage.cards.l; package mage.cards.l;
import java.util.UUID; import java.util.UUID;
@ -10,7 +9,7 @@ import mage.constants.SuperType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.target.TargetPlayer; import mage.target.common.TargetOpponent;
/** /**
* *
@ -29,8 +28,8 @@ public final class LayBareTheHeart extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
// Target opponent reveals their hand. You choose a nonlegendary, nonland card from it. That player discards that card. // Target opponent reveals their hand. You choose a nonlegendary, nonland card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.ANY)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter));
} }
private LayBareTheHeart(final LayBareTheHeart card) { private LayBareTheHeart(final LayBareTheHeart card) {

View file

@ -1,17 +1,13 @@
package mage.cards.n; package mage.cards.n;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.ProwlAbility; import mage.abilities.keyword.ProwlAbility;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.List; import java.util.List;
@ -26,13 +22,11 @@ public final class NogginWhack extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{2}{B}{B}"); super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{2}{B}{B}");
this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.ROGUE);
// Prowl {1}{B} // Prowl {1}{B}
this.addAbility(new ProwlAbility(this, "{1}{B}")); this.addAbility(new ProwlAbility(this, "{1}{B}"));
// Target player reveals three cards from their hand. You choose two of them. That player discards those cards. // Target player reveals three cards from their hand. You choose two of them. That player discards those cards.
this.getSpellAbility().addEffect(new NogginWhackEffect()); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(2, TargetController.ANY, 3));
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
} }
private NogginWhack(final NogginWhack card) { private NogginWhack(final NogginWhack card) {
@ -44,57 +38,3 @@ public final class NogginWhack extends CardImpl {
return new NogginWhack(this); return new NogginWhack(this);
} }
} }
class NogginWhackEffect extends OneShotEffect {
NogginWhackEffect() {
super(Outcome.Benefit);
this.staticText = "Target player reveals three cards from their hand. You choose two of them. That player discards those cards";
}
private NogginWhackEffect(final NogginWhackEffect effect) {
super(effect);
}
@Override
public NogginWhackEffect copy() {
return new NogginWhackEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
Card sourceCard = game.getCard(source.getSourceId());
if (controller == null || targetPlayer == null || sourceCard == null) {
return false;
}
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
int count = Math.min(cardsInHand.size(), 3);
TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard());
Cards revealedCards = new CardsImpl();
if (targetPlayer.chooseTarget(Outcome.Discard, cardsInHand, target, source, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = game.getCard(targetId);
if (card != null) {
revealedCards.add(card);
}
}
}
int cardsToDiscard = Math.min(revealedCards.size(), 2);
TargetCard targetInHand = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards(source, revealedCards, game);
controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game);
targetPlayer.discard(new CardsImpl(targetInHand.getTargets()), false, source, game);
}
return true;
}
}

View file

@ -6,7 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.common.FilterCreatureCard; import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
/** /**
@ -21,7 +21,7 @@ public final class Ostracize extends CardImpl {
// Target opponent reveals their hand. You choose a creature card from it. That player discards that card. // Target opponent reveals their hand. You choose a creature card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(new FilterCreatureCard("a creature card"))); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_CREATURE_A));
} }
private Ostracize(final Ostracize card) { private Ostracize(final Ostracize card) {

View file

@ -8,7 +8,6 @@ import mage.cards.ModalDoubleFacesCard;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ComparisonType; import mage.constants.ComparisonType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
@ -36,13 +35,8 @@ public final class PelakkaPredation extends ModalDoubleFacesCard {
// Pelakka Predation // Pelakka Predation
// Sorcery // Sorcery
// Target opponent reveals their hand. You may choose a card from it with converted mana cost 3 or greater. That player discards that card. // Target opponent reveals their hand. You may choose a card from it with mana value 3 or greater. That player discards that card.
this.getLeftHalfCard().getSpellAbility().addEffect( this.getLeftHalfCard().getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter));
new DiscardCardYouChooseTargetEffect(filter, TargetController.OPPONENT).setText(
"Target opponent reveals their hand. " +
"You choose a card from it with converted mana cost 3 or greater. " +
"That player discards that card"
));
this.getLeftHalfCard().getSpellAbility().addTarget(new TargetOpponent()); this.getLeftHalfCard().getSpellAbility().addTarget(new TargetOpponent());
// 2. // 2.

View file

@ -18,7 +18,7 @@ import mage.target.TargetPlayer;
*/ */
public final class PsychicSpear extends CardImpl { public final class PsychicSpear extends CardImpl {
private static final FilterCard filter = new FilterCard("a Spirit or Arcane card to discard"); private static final FilterCard filter = new FilterCard("Spirit or Arcane card");
static { static {
filter.add(Predicates.or(SubType.SPIRIT.getPredicate(),SubType.ARCANE.getPredicate())); filter.add(Predicates.or(SubType.SPIRIT.getPredicate(),SubType.ARCANE.getPredicate()));

View file

@ -1,26 +1,20 @@
package mage.cards.r; package mage.cards.r;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.common.ManaWasSpentCondition; import mage.abilities.condition.common.ManaWasSpentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.Card; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ColoredManaSymbol; import mage.constants.ColoredManaSymbol;
import mage.constants.Outcome; import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID; import java.util.UUID;
@ -33,17 +27,18 @@ public final class RiversGrasp extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U/B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U/B}");
// If {U} was spent to cast River's Grasp, return up to one target creature to its owner's hand. If {B} was spent to cast River's Grasp, target player reveals their hand, you choose a nonland card from it, then that player discards that card. // If {U} was spent to cast River's Grasp, return up to one target creature to its owner's hand. If {B} was spent to cast River's Grasp, target player reveals their hand, you choose a nonland card from it, then that player discards that card.
Target targetCreature = new TargetCreaturePermanent(0, 1);
Target targetPlayer = new TargetPlayer();
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new ReturnToHandTargetEffect(), new ReturnToHandTargetEffect(),
new ManaWasSpentCondition(ColoredManaSymbol.U), "If {U} was spent to cast this spell, return up to one target creature to its owner's hand")); new ManaWasSpentCondition(ColoredManaSymbol.U),
"If {U} was spent to cast this spell, return up to one target creature to its owner's hand"));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect( this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new RiversGraspEffect(), new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY),
new ManaWasSpentCondition(ColoredManaSymbol.B), " If {B} was spent to cast this spell, target player reveals their hand, you choose a nonland card from it, then that player discards that card")); new ManaWasSpentCondition(ColoredManaSymbol.B),
" If {B} was spent to cast this spell, target player reveals their hand, you choose a nonland card from it, then that player discards that card")
.setTargetPointer(new SecondTargetPointer()));
this.getSpellAbility().addTarget(targetCreature); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1));
this.getSpellAbility().addTarget(targetPlayer); this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {U}{B} was spent.)</i>")); this.getSpellAbility().addEffect(new InfoEffect("<i>(Do both if {U}{B} was spent.)</i>"));
} }
@ -57,38 +52,3 @@ public final class RiversGrasp extends CardImpl {
return new RiversGrasp(this); return new RiversGrasp(this);
} }
} }
class RiversGraspEffect extends OneShotEffect {
public RiversGraspEffect() {
super(Outcome.Discard);
this.staticText = "Target player reveals their hand, you choose a card from it, then that player discards that card.";
}
public RiversGraspEffect(final RiversGraspEffect effect) {
super(effect);
}
@Override
public RiversGraspEffect copy() {
return new RiversGraspEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget());
if (player != null) {
player.revealCards("River's Grasp", player.getHand(), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
TargetCard target = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_A_NON_LAND);
if (controller.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
return player.discard(card, false, source, game);
}
}
}
return false;
}
}

View file

@ -6,7 +6,7 @@ import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.FilterCard; import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
/** /**
@ -15,18 +15,13 @@ import mage.target.common.TargetOpponent;
*/ */
public final class ShatteredDreams extends CardImpl { public final class ShatteredDreams extends CardImpl {
private static final FilterCard filter = new FilterCard("an artifact card from it");
static {
filter.add(CardType.ARTIFACT.getPredicate());
}
public ShatteredDreams(UUID ownerId, CardSetInfo setInfo) { public ShatteredDreams(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}"); super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}");
// Target opponent reveals their hand. You choose an artifact card from it. That player discards that card. // Target opponent reveals their hand. You choose an artifact card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN));
} }
private ShatteredDreams(final ShatteredDreams card) { private ShatteredDreams(final ShatteredDreams card) {

View file

@ -1,20 +1,12 @@
package mage.cards.s; package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.UUID; import java.util.UUID;
@ -28,14 +20,16 @@ public final class SplittingHeadache extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Choose one - Target player discards two cards; or target player reveals their hand, you choose a card from it, then that player discards that card. // Choose one
// Target player discards two cards.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DiscardTargetEffect(2)); this.getSpellAbility().addEffect(new DiscardTargetEffect(2));
// Target player reveals their hand. You choose a card from it. That player discards that card.
Mode mode = new Mode(); Mode mode = new Mode();
mode.addEffect(new SplittingHeadacheEffect()); mode.addEffect(new DiscardCardYouChooseTargetEffect(TargetController.ANY));
mode.addTarget(new TargetPlayer()); mode.addTarget(new TargetPlayer());
this.getSpellAbility().addMode(mode); this.getSpellAbility().addMode(mode);
} }
private SplittingHeadache(final SplittingHeadache card) { private SplittingHeadache(final SplittingHeadache card) {
@ -47,38 +41,3 @@ public final class SplittingHeadache extends CardImpl {
return new SplittingHeadache(this); return new SplittingHeadache(this);
} }
} }
class SplittingHeadacheEffect extends OneShotEffect {
public SplittingHeadacheEffect() {
super(Outcome.Discard);
this.staticText = "Target player reveals their hand, you choose a card from it, then that player discards that card.";
}
public SplittingHeadacheEffect(final SplittingHeadacheEffect effect) {
super(effect);
}
@Override
public SplittingHeadacheEffect copy() {
return new SplittingHeadacheEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getFirstTarget());
if (player != null) {
player.revealCards("Splitting Headache", player.getHand(), game);
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
TargetCard target = new TargetCard(Zone.HAND, new FilterCard());
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
return player.discard(card, false, source, game);
}
}
}
return false;
}
}

View file

@ -1,24 +1,20 @@
package mage.cards.t; package mage.cards.t;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -26,6 +22,11 @@ import java.util.UUID;
*/ */
public final class ThievingSprite extends CardImpl { public final class ThievingSprite extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.FAERIE, "Faeries you control"), null);
private static final String rule = "target player reveals X cards from their hand, where X is " +
xValue.getMessage() + ". You choose one of those cards. That player discards that card";
public ThievingSprite(UUID ownerId, CardSetInfo setInfo) { public ThievingSprite(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.FAERIE); this.subtype.add(SubType.FAERIE);
@ -37,11 +38,11 @@ public final class ThievingSprite extends CardImpl {
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// When Thieving Sprite enters the battlefield, target player reveals X cards from their hand, where X is the number of Faeries you control. // When Thieving Sprite enters the battlefield, target player reveals X cards from their hand,
// You choose one of those cards. That player discards that card. // where X is the number of Faeries you control. You choose one of those cards.
Ability ability = new EntersBattlefieldTriggeredAbility(new ThievingSpriteEffect(), false); // That player discards that card.
TargetPlayer target = new TargetPlayer(); Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect(TargetController.ANY, xValue).setText(rule));
ability.addTarget(target); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
} }
@ -55,72 +56,3 @@ public final class ThievingSprite extends CardImpl {
return new ThievingSprite(this); return new ThievingSprite(this);
} }
} }
class ThievingSpriteEffect extends OneShotEffect {
public ThievingSpriteEffect() {
super(Outcome.Discard);
this.staticText = "target player reveals X cards from their hand, where X is the number of Faeries you control. You choose one of those cards. "
+ "That player discards that card";
}
public ThievingSpriteEffect(final ThievingSpriteEffect effect) {
super(effect);
}
@Override
public ThievingSpriteEffect copy() {
return new ThievingSpriteEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId());
if (targetPlayer == null || controller == null) {
return false;
}
FilterControlledPermanent filter = new FilterControlledPermanent();
filter.add(SubType.FAERIE.getPredicate());
int numberOfFaeries = game.getBattlefield().countAll(filter, controller.getId(), game);
if (numberOfFaeries < 1) {
return true;
}
Cards revealedCards = new CardsImpl();
if (targetPlayer.getHand().size() > numberOfFaeries) {
Cards cardsInHand = new CardsImpl();
cardsInHand.addAll(targetPlayer.getHand());
TargetCard target = new TargetCard(numberOfFaeries, Zone.HAND, new FilterCard());
if (targetPlayer.choose(Outcome.Discard, cardsInHand, target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = game.getCard(targetId);
if (card != null) {
revealedCards.add(card);
}
}
}
} else {
revealedCards.addAll(targetPlayer.getHand());
}
TargetCard targetInHand = new TargetCard(Zone.HAND, new FilterCard("card to discard"));
if (!revealedCards.isEmpty()) {
targetPlayer.revealCards("Thieving Sprite", revealedCards, game);
Card card = null;
if (revealedCards.size() > 1) {
controller.choose(Outcome.Discard, revealedCards, targetInHand, game);
card = revealedCards.get(targetInHand.getFirstTarget(), game);
} else {
card = revealedCards.getRandom(game);
}
targetPlayer.discard(card, false, source, game);
}
return true;
}
}

View file

@ -5,9 +5,7 @@ import mage.abilities.effects.keyword.SurveilEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.TargetController; import mage.filter.StaticFilters;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import java.util.UUID; import java.util.UUID;
@ -17,13 +15,11 @@ import java.util.UUID;
*/ */
public final class ThoughtErasure extends CardImpl { public final class ThoughtErasure extends CardImpl {
private static final FilterCard filter = new FilterNonlandCard();
public ThoughtErasure(UUID ownerId, CardSetInfo setInfo) { public ThoughtErasure(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{B}");
// Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. // Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filter, TargetController.OPPONENT)); this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
// Surveil 1. // Surveil 1.

View file

@ -5,7 +5,6 @@ import mage.abilities.effects.keyword.AmassEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
@ -20,13 +19,11 @@ public final class TollOfTheInvasion extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
// Target opponent reveals their hand. You choose a nonland card from it. That player discards that card. // Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect( this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND));
StaticFilters.FILTER_CARD_NON_LAND, TargetController.OPPONENT
));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());
// Amass 1. // Amass 1.
this.getSpellAbility().addEffect(new AmassEffect(1)); this.getSpellAbility().addEffect(new AmassEffect(1).concatBy("<br>"));
} }
private TollOfTheInvasion(final TollOfTheInvasion card) { private TollOfTheInvasion(final TollOfTheInvasion card) {

View file

@ -20,9 +20,7 @@ public final class TourachsCanticle extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random. // Target opponent reveals their hand. You choose a card from it. That player discards that card, then discards a card at random.
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect( this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect());
StaticFilters.FILTER_CARD, TargetController.OPPONENT
));
this.getSpellAbility().addEffect(new DiscardTargetEffect(1, true) this.getSpellAbility().addEffect(new DiscardTargetEffect(1, true)
.setText(", then discards a card at random")); .setText(", then discards a card at random"));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponent());

View file

@ -31,8 +31,6 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect {
private final DynamicValue numberCardsToDiscard; private final DynamicValue numberCardsToDiscard;
private boolean revealAllCards; private boolean revealAllCards;
private static final FilterCard filterOneCard = new FilterCard("one card");
public DiscardCardYouChooseTargetEffect() { public DiscardCardYouChooseTargetEffect() {
this(StaticFilters.FILTER_CARD_A); this(StaticFilters.FILTER_CARD_A);
} }
@ -41,38 +39,22 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect {
this(StaticFilters.FILTER_CARD_A, targetController); this(StaticFilters.FILTER_CARD_A, targetController);
} }
public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, TargetController targetController) {
this(numberCardsToDiscard, StaticFilters.FILTER_CARD_CARDS, targetController);
}
public DiscardCardYouChooseTargetEffect(FilterCard filter) { public DiscardCardYouChooseTargetEffect(FilterCard filter) {
this(filter, TargetController.OPPONENT); this(filter, TargetController.OPPONENT);
} }
public DiscardCardYouChooseTargetEffect(TargetController targetController, int numberCardsToReveal) {
this(filterOneCard, targetController, StaticValue.get(numberCardsToReveal));
}
public DiscardCardYouChooseTargetEffect(TargetController targetController, DynamicValue numberCardsToReveal) {
this(filterOneCard, targetController, numberCardsToReveal);
}
public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController, DynamicValue numberCardsToReveal) {
super(Outcome.Discard);
this.targetController = targetController;
this.filter = filter;
this.revealAllCards = false;
this.numberCardsToReveal = numberCardsToReveal;
this.numberCardsToDiscard = StaticValue.get(1);
staticText = this.setText();
}
public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController) { public DiscardCardYouChooseTargetEffect(FilterCard filter, TargetController targetController) {
this(StaticValue.get(1), filter, targetController); this(StaticValue.get(1), filter, targetController);
} }
public DiscardCardYouChooseTargetEffect(int numberCardsToDiscard, TargetController targetController) {
this(StaticValue.get(numberCardsToDiscard), targetController);
}
public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, TargetController targetController) {
this(numberCardsToDiscard, StaticFilters.FILTER_CARD_CARDS, targetController);
}
public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard,
FilterCard filter, TargetController targetController) { FilterCard filter, TargetController targetController) {
super(Outcome.Discard); super(Outcome.Discard);
@ -86,6 +68,30 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect {
staticText = this.setText(); staticText = this.setText();
} }
public DiscardCardYouChooseTargetEffect(TargetController targetController, int numberCardsToReveal) {
this(targetController, StaticValue.get(numberCardsToReveal));
}
public DiscardCardYouChooseTargetEffect(TargetController targetController, DynamicValue numberCardsToReveal) {
this(StaticValue.get(1), StaticFilters.FILTER_CARD_A, targetController, numberCardsToReveal);
}
public DiscardCardYouChooseTargetEffect(int numberCardsToDiscard, TargetController targetController, int numberCardsToReveal) {
this(StaticValue.get(numberCardsToDiscard), StaticFilters.FILTER_CARD_CARDS, targetController, StaticValue.get(numberCardsToReveal));
}
public DiscardCardYouChooseTargetEffect(DynamicValue numberCardsToDiscard, FilterCard filter, TargetController targetController, DynamicValue numberCardsToReveal) {
super(Outcome.Discard);
this.targetController = targetController;
this.filter = filter;
this.revealAllCards = false;
this.numberCardsToReveal = numberCardsToReveal;
this.numberCardsToDiscard = numberCardsToDiscard;
staticText = this.setText();
}
public DiscardCardYouChooseTargetEffect(final DiscardCardYouChooseTargetEffect effect) { public DiscardCardYouChooseTargetEffect(final DiscardCardYouChooseTargetEffect effect) {
super(effect); super(effect);
this.filter = effect.filter; this.filter = effect.filter;
@ -155,6 +161,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect {
} }
private String setText() { private String setText() {
boolean discardMultipleCards = !numberCardsToDiscard.toString().equals("1");
StringBuilder sb = new StringBuilder("target "); StringBuilder sb = new StringBuilder("target ");
switch (targetController) { switch (targetController) {
case OPPONENT: case OPPONENT:
@ -166,32 +173,37 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect {
default: default:
throw new UnsupportedOperationException("target controller not supported"); throw new UnsupportedOperationException("target controller not supported");
} }
if (revealAllCards) {
sb.append(" reveals their hand");
} else {
if (numberCardsToReveal instanceof StaticValue) {
sb.append(" reveals "); sb.append(" reveals ");
sb.append(CardUtil.numberToText(((StaticValue) numberCardsToReveal).getValue())).append(" cards"); if (revealAllCards) {
sb.append(" from their hand"); sb.append("their hand. You choose ");
} else {
sb.append(" reveals a number of cards from their hand equal to ");
sb.append(numberCardsToReveal.getMessage());
}
}
sb.append(". You choose ");
boolean discardMultipleCards = !numberCardsToDiscard.toString().equals("1");
if (discardMultipleCards) { if (discardMultipleCards) {
sb.append(numberCardsToDiscard).append(' ').append(filter.getMessage()); sb.append(numberCardsToDiscard).append(' ').append(filter.getMessage());
} else { } else {
sb.append(CardUtil.addArticle(filter.getMessage())); sb.append(CardUtil.addArticle(filter.getMessage()));
} }
if (revealAllCards) { if (!filter.getMessage().contains("from it")) {
sb.append(filter.getMessage().contains("from it") ? "." : " from it."); sb.append(" from it");
}
} else { } else {
sb.append(" of them."); if (numberCardsToReveal instanceof StaticValue) {
sb.append(CardUtil.numberToText(((StaticValue) numberCardsToReveal).getValue()));
sb.append(" cards from their hand");
} else if (numberCardsToReveal.getMessage().isEmpty()) {
sb.append("X cards from their hand");
} else {
sb.append("a number of cards from their hand equal to ");
sb.append(numberCardsToReveal.getMessage());
}
sb.append(". You choose ");
if (numberCardsToDiscard instanceof StaticValue) {
sb.append(CardUtil.numberToText(((StaticValue) numberCardsToDiscard).getValue()));
} else {
sb.append(numberCardsToDiscard);
}
sb.append(" of them");
} }
sb.append(" That player discards ").append(discardMultipleCards ? "those cards" : "that card"); sb.append(". That player discards ").append(discardMultipleCards ? "those cards" : "that card");
return sb.toString(); return sb.toString();
} }
} }