refactored more zone changes, letters C and D (#7572)

Decaying Soil has been heavily reworked
This commit is contained in:
Evan Kranzler 2021-02-24 14:37:22 -05:00
parent 47dc1d8d61
commit 746d5eef3b
12 changed files with 234 additions and 357 deletions

View file

@ -1,43 +1,28 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import mage.util.RandomUtil;
import mage.target.TargetCard;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
*
* @author North
*/
public final class CharmbreakerDevils extends CardImpl {
private static final FilterSpell filter = new FilterSpell("instant or sorcery card");
static {
filter.add(Predicates.or(
CardType.INSTANT.getPredicate(),
CardType.SORCERY.getPredicate()));
}
public CharmbreakerDevils(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.subtype.add(SubType.DEVIL);
@ -46,9 +31,15 @@ public final class CharmbreakerDevils extends CardImpl {
this.toughness = new MageInt(4);
// At the beginning of your upkeep, return an instant or sorcery card at random from your graveyard to your hand.
this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new CharmbreakerDevilsEffect(), false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new CharmbreakerDevilsEffect(), TargetController.YOU, false
));
// Whenever you cast an instant or sorcery spell, Charmbreaker Devils gets +4/+0 until end of turn.
this.addAbility(new SpellCastControllerTriggeredAbility(new BoostSourceEffect(4, 0, Duration.EndOfTurn), filter, false));
this.addAbility(new SpellCastControllerTriggeredAbility(
new BoostSourceEffect(4, 0, Duration.EndOfTurn),
StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false
));
}
private CharmbreakerDevils(final CharmbreakerDevils card) {
@ -63,12 +54,12 @@ public final class CharmbreakerDevils extends CardImpl {
class CharmbreakerDevilsEffect extends OneShotEffect {
public CharmbreakerDevilsEffect() {
CharmbreakerDevilsEffect() {
super(Outcome.ReturnToHand);
this.staticText = "return an instant or sorcery card at random from your graveyard to your hand";
}
public CharmbreakerDevilsEffect(final CharmbreakerDevilsEffect effect) {
private CharmbreakerDevilsEffect(final CharmbreakerDevilsEffect effect) {
super(effect);
}
@ -80,19 +71,14 @@ class CharmbreakerDevilsEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
FilterCard filter = new FilterCard("instant or sorcery card");
filter.add(Predicates.or(
CardType.INSTANT.getPredicate(),
CardType.SORCERY.getPredicate()));
Card[] cards = player.getGraveyard().getCards(filter, game).toArray(new Card[0]);
if (cards.length > 0) {
Card card = cards[RandomUtil.nextInt(cards.length)];
card.moveToZone(Zone.HAND, source, game, true);
game.informPlayers("Charmbreaker Devils: " + card.getName() + " returned to the hand of " + player.getLogName());
return true;
}
}
if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD_INSTANT_AND_SORCERY, game) < 1) {
return false;
}
TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_AND_SORCERY);
target.setRandom(true);
target.setNotTarget(true);
player.choose(outcome, target, source.getSourceId(), game);
Card card = game.getCard(target.getFirstTarget());
return card != null && player.moveCards(card, Zone.HAND, source, game);
}
}

View file

@ -1,25 +1,28 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
*
* @author Backfir3
*/
public final class CitanulFlute extends CardImpl {
@ -29,7 +32,7 @@ public final class CitanulFlute extends CardImpl {
// {X}, {T}: Search your library for a creature card with converted mana cost X or less, reveal it,
// and put it into your hand. Then shuffle your library.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CitanulFluteSearchEffect(), new ManaCostsImpl("{X}"));
Ability ability = new SimpleActivatedAbility(new CitanulFluteSearchEffect(), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
@ -46,12 +49,13 @@ public final class CitanulFlute extends CardImpl {
class CitanulFluteSearchEffect extends OneShotEffect {
public CitanulFluteSearchEffect() {
CitanulFluteSearchEffect() {
super(Outcome.DrawCard);
staticText = "Search your library for a creature card with converted mana cost X or less, reveal it, and put it into your hand. Then shuffle your library";
staticText = "Search your library for a creature card with converted mana cost X or less, " +
"reveal it, and put it into your hand. Then shuffle your library";
}
public CitanulFluteSearchEffect(final CitanulFluteSearchEffect effect) {
private CitanulFluteSearchEffect(final CitanulFluteSearchEffect effect) {
super(effect);
}
@ -67,31 +71,18 @@ class CitanulFluteSearchEffect extends OneShotEffect {
return false;
}
FilterCard filter = new FilterCard("creature card with converted mana cost X or less");
filter.add(CardType.CREATURE.getPredicate());
FilterCard filter = new FilterCreatureCard("creature card with converted mana cost X or less");
//Set the mana cost one higher to 'emulate' a less than or equal to comparison.
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, source.getManaCostsToPay().getX() + 1));
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, source, game)) {
if (!target.getTargets().isEmpty()) {
player.searchLibrary(target, source, game);
Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
Cards cards = new CardsImpl();
if (card != null) {
card.moveToZone(Zone.HAND, source, game, false);
cards.add(card);
}
String name = "Reveal";
Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard != null) {
name = sourceCard.getName();
}
player.revealCards(name, cards, game);
player.revealCards(source, new CardsImpl(card), game);
player.moveCards(card, Zone.HAND, source, game);
}
player.shuffleLibrary(source, game);
return true;
}
player.shuffleLibrary(source, game);
return false;
}
}

View file

@ -6,10 +6,10 @@ import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
import java.util.UUID;
@ -25,7 +25,6 @@ public final class CruelFate extends CardImpl {
// Look at the top five cards of target opponent's library. Put one of those cards into that player's graveyard and the rest on top of their library in any order.
this.getSpellAbility().addEffect(new CruelFateEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
private CruelFate(final CruelFate card) {
@ -40,12 +39,13 @@ public final class CruelFate extends CardImpl {
class CruelFateEffect extends OneShotEffect {
public CruelFateEffect() {
CruelFateEffect() {
super(Outcome.DrawCard);
this.staticText = "Look at the top five cards of target opponent's library. Put one of those cards into that player's graveyard and the rest on top of their library in any order";
this.staticText = "Look at the top five cards of target opponent's library. " +
"Put one of those cards into that player's graveyard and the rest on top of their library in any order";
}
public CruelFateEffect(final CruelFateEffect effect) {
private CruelFateEffect(final CruelFateEffect effect) {
super(effect);
}
@ -56,35 +56,25 @@ class CruelFateEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard != null) {
Player controller = game.getPlayer(source.getControllerId());
Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetOpponent != null && controller != null) {
Cards cards = new CardsImpl(targetOpponent.getLibrary().getTopCards(game, 5));
controller.lookAtCards(source, null, cards, game);
// card to put into opponent's graveyard
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard"));
if (targetOpponent.canRespond()) {
if (cards.size() > 1) {
controller.choose(Outcome.Detriment, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
controller.moveCards(card, Zone.GRAVEYARD, source, game);
}
} else if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
controller.moveCards(card, Zone.GRAVEYARD, source, game);
card.moveToZone(Zone.GRAVEYARD, source, game, true);
cards.clear();
}
}
controller.putCardsOnTopOfLibrary(cards, game, source, true);
return true;
}
}
Player opponent = game.getPlayer(source.getFirstTarget());
if (controller == null || opponent == null) {
return false;
}
Cards cards = new CardsImpl(opponent.getLibrary().getTopCards(game, 5));
if (cards.isEmpty()) {
return false;
}
if (cards.size() == 1) {
return controller.moveCards(cards, Zone.GRAVEYARD, source, game);
}
TargetCard targetCard = new TargetCardInLibrary();
controller.choose(outcome, cards, targetCard, game);
Card card = game.getCard(targetCard.getFirstTarget());
if (card != null) {
controller.moveCards(card, Zone.GRAVEYARD, source, game);
cards.remove(card);
}
return controller.putCardsOnTopOfLibrary(card, game, source, true);
}
}

View file

@ -14,6 +14,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInYourGraveyard;
@ -36,7 +37,6 @@ public final class CruelRevival extends CardImpl {
public CruelRevival(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}");
// Destroy target non-Zombie creature. It can't be regenerated. Return up to one target Zombie card from your graveyard to your hand.
this.getSpellAbility().addEffect(new CruelRevivalEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
@ -55,12 +55,13 @@ public final class CruelRevival extends CardImpl {
class CruelRevivalEffect extends OneShotEffect {
public CruelRevivalEffect() {
CruelRevivalEffect() {
super(Outcome.DestroyPermanent);
staticText = "Destroy target non-Zombie creature. It can't be regenerated. Return up to one target Zombie card from your graveyard to your hand";
staticText = "Destroy target non-Zombie creature. It can't be regenerated. " +
"Return up to one target Zombie card from your graveyard to your hand";
}
public CruelRevivalEffect(final CruelRevivalEffect effect) {
private CruelRevivalEffect(final CruelRevivalEffect effect) {
super(effect);
}
@ -71,9 +72,10 @@ class CruelRevivalEffect extends OneShotEffect {
targetDestroy.destroy(source, game, true);
}
Player player = game.getPlayer(source.getControllerId());
Card targetRetrieve = game.getCard(source.getTargets().get(1).getFirstTarget());
if (targetRetrieve != null) {
targetRetrieve.moveToZone(Zone.HAND, source, game, true);
if (player != null && targetRetrieve != null) {
player.moveCards(targetRetrieve, Zone.HAND, source, game);
}
return true;
}

View file

@ -5,11 +5,13 @@ import mage.abilities.costs.Cost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -25,7 +27,6 @@ public final class CutTheTethers extends CardImpl {
public CutTheTethers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
// For each Spirit, return it to its owner's hand unless that player pays {3}.
this.getSpellAbility().addEffect(new CutTheTethersEffect());
}
@ -42,18 +43,14 @@ public final class CutTheTethers extends CardImpl {
class CutTheTethersEffect extends OneShotEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Spirit creatures");
private static final FilterPermanent filter = new FilterPermanent(SubType.SPIRIT, "");
static {
filter.add(SubType.SPIRIT.getPredicate());
}
public CutTheTethersEffect() {
CutTheTethersEffect() {
super(Outcome.ReturnToHand);
this.staticText = "For each Spirit, return it to its owner's hand unless that player pays {3}";
}
public CutTheTethersEffect(final CutTheTethersEffect effect) {
private CutTheTethersEffect(final CutTheTethersEffect effect) {
super(effect);
}
@ -64,19 +61,28 @@ class CutTheTethersEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent creature : game.getState().getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
Player player = game.getPlayer(creature.getControllerId());
if (player != null) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
Cards toHand = new CardsImpl();
for (Permanent permanent : game.getBattlefield().getActivePermanents(
filter, source.getControllerId(), source.getSourceId(), game
)) {
Player player = game.getPlayer(permanent.getOwnerId());
if (player == null) {
continue;
}
boolean paid = false;
if (player.chooseUse(Outcome.Benefit, "Pay {3} to keep " + creature.getName() + " on the battlefield?", source, game)) {
if (player.chooseUse(Outcome.Benefit, "Pay {3} to keep " + permanent.getIdName() + " on the battlefield?", source, game)) {
Cost cost = ManaUtil.createManaCost(3, false);
paid = cost.pay(source, game, source, creature.getControllerId(), false, null);
paid = cost.pay(source, game, source, permanent.getControllerId(), false, null);
}
if (!paid) {
creature.moveToZone(Zone.HAND, source, game, true);
}
toHand.add(permanent);
}
}
controller.moveCards(toHand, Zone.HAND, source, game);
return true;
}
}

View file

@ -1,27 +1,32 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public final class DarkTutelage extends CardImpl {
public DarkTutelage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new DarkTutelageEffect(), false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new DarkTutelageEffect(), TargetController.YOU, false
));
}
private DarkTutelage(final DarkTutelage card) {
@ -32,38 +37,39 @@ public final class DarkTutelage extends CardImpl {
public DarkTutelage copy() {
return new DarkTutelage(this);
}
}
class DarkTutelageEffect extends OneShotEffect {
public DarkTutelageEffect() {
DarkTutelageEffect() {
super(Outcome.DrawCard);
staticText = "reveal the top card of your library and put that card into your hand. You lose life equal to its converted mana cost";
}
public DarkTutelageEffect(final DarkTutelageEffect effect) {
private DarkTutelageEffect(final DarkTutelageEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = controller.getLibrary().getFromTop(game);
if (card != null) {
controller.revealCards(source, new CardsImpl(card), game);
card.moveToZone(Zone.HAND, source, game, false);
controller.loseLife(card.getConvertedManaCost(), game, source, false);
return true;
}
}
Player player = game.getPlayer(source.getControllerId());
if (player == null || !player.getLibrary().hasCards()) {
return false;
}
Card card = player.getLibrary().getFromTop(game);
if (card == null) {
return false;
}
player.revealCards(source, new CardsImpl(card), game);
player.moveCards(card, Zone.HAND, source, game);
if (card.getConvertedManaCost() > 0) {
player.loseLife(card.getConvertedManaCost(), game, source, false);
}
return true;
}
@Override
public DarkTutelageEffect copy() {
return new DarkTutelageEffect(this);
}
}

View file

@ -1,32 +1,25 @@
package mage.cards.d;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.CardsInControllerGraveyardCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.ExileFromZoneTargetEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.util.ManaUtil;
import java.util.UUID;
@ -35,30 +28,30 @@ import java.util.UUID;
*/
public final class DecayingSoil extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature");
private static final FilterPermanent filter = new FilterCreaturePermanent("nontoken creature");
static {
filter.add(TargetController.YOU.getOwnerPredicate());
filter.add(Predicates.not(TokenPredicate.instance));
}
private static final Condition condition = new CardsInControllerGraveyardCondition(7);
public DecayingSoil(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}");
// At the beginning of your upkeep, exile a card from your graveyard.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), TargetController.YOU, false);
TargetCardInYourGraveyard target = new TargetCardInYourGraveyard();
ability.addTarget(target);
this.addAbility(ability);
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
Zone.BATTLEFIELD, new ExileFromZoneTargetEffect(Zone.GRAVEYARD, false
).setText("exile a card from your graveyard"), TargetController.YOU, false, true));
// Threshold - As long as seven or more cards are in your graveyard, Decaying Soil has "Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {1}. If you do, return that card to your hand."
ability = new SimpleStaticAbility(Zone.BATTLEFIELD,
new ConditionalContinuousEffect(new GainAbilitySourceEffect(new DecayingSoilTriggeredAbility(new DecayingSoilEffect(), filter)),
new CardsInControllerGraveyardCondition(7),
"As long as seven or more cards are in your graveyard, {this} has \"Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {1}. If you do, return that card to your hand.\""));
ability.setAbilityWord(AbilityWord.THRESHOLD);
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new GainAbilitySourceEffect(new DecayingSoilTriggeredAbility()),
condition, "<i>Threshold</i> &mdash; As long as seven or more cards are in your graveyard, " +
"{this} has \"Whenever a nontoken creature is put into your graveyard from the battlefield, " +
"you may pay {1}. If you do, return that card to your hand.\""
)));
}
private DecayingSoil(final DecayingSoil card) {
@ -71,18 +64,21 @@ public final class DecayingSoil extends CardImpl {
}
}
class DecayingSoilTriggeredAbility extends TriggeredAbilityImpl {
class DecayingSoilTriggeredAbility extends DiesCreatureTriggeredAbility {
protected FilterCreaturePermanent filter;
private static final FilterPermanent filter = new FilterCreaturePermanent();
public DecayingSoilTriggeredAbility(Effect effect, FilterCreaturePermanent filter) {
super(Zone.BATTLEFIELD, effect, false);
this.filter = filter;
static {
filter.add(TargetController.YOU.getOwnerPredicate());
filter.add(Predicates.not(TokenPredicate.instance));
}
public DecayingSoilTriggeredAbility(DecayingSoilTriggeredAbility ability) {
DecayingSoilTriggeredAbility() {
super(new DoIfCostPaid(new ReturnFromGraveyardToHandTargetEffect(), new GenericManaCost(1)), false, filter, true);
}
private DecayingSoilTriggeredAbility(DecayingSoilTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
}
@Override
@ -90,77 +86,9 @@ class DecayingSoilTriggeredAbility extends TriggeredAbilityImpl {
return new DecayingSoilTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.isDiesEvent()) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (permanent != null && filter.match(permanent, this.getSourceId(), this.getControllerId(), game)) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent, game));
return true;
}
}
return false;
}
@Override
public boolean checkInterveningIfClause(Game game) {
Player controller = game.getPlayer(this.getControllerId());
return controller != null && controller.getGraveyard().contains(this.getSourceId());
}
@Override
public String getRule() {
return "Whenever a " + filter.getMessage() + " is put into your graveyard from the battlefield, " + super.getRule();
return "Whenever a nontoken creature is put into your graveyard from the battlefield, " +
"you may pay {1}. If you do, return that card to your hand.";
}
}
class DecayingSoilEffect extends OneShotEffect {
private final Cost cost = ManaUtil.createManaCost(1, false);
public DecayingSoilEffect() {
super(Outcome.Benefit);
staticText = "you may pay {1}. If you do, return that card to your hand";
}
public DecayingSoilEffect(final DecayingSoilEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
if (player.chooseUse(Outcome.Benefit, " - Pay " + cost.getText() + '?', source, game)) {
cost.clearPaid();
if (cost.pay(source, game, source, source.getControllerId(), false, null)) {
UUID target = this.getTargetPointer().getFirst(game, source);
if (target != null) {
Card card = game.getCard(target);
// check if it's still in graveyard
if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) {
card.moveToZone(Zone.HAND, source, game, true);
return true;
}
}
}
}
}
return false;
}
@Override
public DecayingSoilEffect copy() {
return new DecayingSoilEffect(this);
}
}

View file

@ -4,8 +4,11 @@ import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
@ -15,14 +18,12 @@ import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetadjustment.TargetAdjuster;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import mage.abilities.condition.Condition;
import mage.constants.Zone;
/**
* @author TheElk801
@ -88,7 +89,7 @@ class DecoyGambitEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
HashSet<Permanent> permanentToHand = new HashSet();
Cards permanentToHand = new CardsImpl();
int numberOfCardsToDraw = 0;
if (controller == null) {
return false;
@ -102,8 +103,6 @@ class DecoyGambitEffect extends OneShotEffect {
.filter(Objects::nonNull)
.collect(Collectors.toList());
for (Permanent permanent : permanents) {
// If a creature targeted by Decoy Gambit changes controller, its no longer a legal target.
new DecoyGambitCondition(permanent).apply(game, source); // save current controller
Player player = game.getPlayer(permanent.getControllerId());
if (player == null) {
continue;
@ -125,31 +124,7 @@ class DecoyGambitEffect extends OneShotEffect {
cards. After youve drawn, the appropriate creatures are all simultaneously returned to their owners hands.
*/
controller.drawCards(numberOfCardsToDraw, source, game);
for (Permanent creature : permanentToHand) {
if (creature != null
&& new DecoyGambitCondition(creature).apply(game, source)) { // same controller required
creature.moveToZone(Zone.HAND, source, game, false);
}
}
controller.moveCards(permanentToHand, Zone.HAND, source, game);
return true;
}
}
class DecoyGambitCondition implements Condition {
private UUID controllerId;
private final Permanent permanent;
DecoyGambitCondition(Permanent permanent) {
this.permanent = permanent;
}
@Override
public boolean apply(Game game, Ability source) {
if (controllerId == null) { // is the original controller set
controllerId = permanent.getControllerId(); // original controller set
}
return (permanent != null
&& Objects.equals(controllerId, permanent.getControllerId()));
}
}

View file

@ -1,23 +1,19 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
*
* @author North
*/
public final class DiabolicRevelation extends CardImpl {
@ -25,7 +21,6 @@ public final class DiabolicRevelation extends CardImpl {
public DiabolicRevelation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{3}{B}{B}");
// Search your library for up to X cards and put those cards into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new DiabolicRevelationEffect());
}
@ -42,12 +37,12 @@ public final class DiabolicRevelation extends CardImpl {
class DiabolicRevelationEffect extends OneShotEffect {
public DiabolicRevelationEffect() {
DiabolicRevelationEffect() {
super(Outcome.Benefit);
this.staticText = "Search your library for up to X cards and put those cards into your hand. Then shuffle your library";
}
public DiabolicRevelationEffect(final DiabolicRevelationEffect effect) {
private DiabolicRevelationEffect(final DiabolicRevelationEffect effect) {
super(effect);
}
@ -58,23 +53,24 @@ class DiabolicRevelationEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
int amount = ManacostVariableValue.instance.calculate(game, source, this);
TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterCard());
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
if (player.searchLibrary(target, source, game)) {
for (UUID cardId : target.getTargets()) {
Card card = player.getLibrary().remove(cardId, game);
TargetCardInLibrary target = new TargetCardInLibrary(
0, source.getManaCostsToPay().getX(), StaticFilters.FILTER_CARD
);
player.searchLibrary(target, source, game);
Cards cards = new CardsImpl();
for (UUID targetId : target.getTargets()) {
Card card = player.getLibrary().getCard(targetId, game);
if (card != null) {
card.moveToZone(Zone.HAND, source, game, false);
cards.add(card);
}
}
if (!cards.isEmpty()) {
player.moveCards(cards, Zone.HAND, source, game);
}
player.shuffleLibrary(source, game);
return true;
}

View file

@ -1,19 +1,21 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author fireshoes
*/
@ -38,12 +40,12 @@ public final class DisplacementWave extends CardImpl {
class DisplacementWaveEffect extends OneShotEffect {
public DisplacementWaveEffect() {
DisplacementWaveEffect() {
super(Outcome.ReturnToHand);
staticText = "Return all nonland permanents with converted mana cost X or less to their owners' hands";
}
public DisplacementWaveEffect(final DisplacementWaveEffect effect) {
private DisplacementWaveEffect(final DisplacementWaveEffect effect) {
super(effect);
}
@ -54,11 +56,16 @@ class DisplacementWaveEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl();
for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
if (!permanent.isLand() && permanent.getConvertedManaCost() <= source.getManaCostsToPay().getX()) {
permanent.moveToZone(Zone.HAND, source, game, true);
cards.add(permanent);
}
}
return true;
return player.moveCards(cards, Zone.HAND, source, game);
}
}

View file

@ -1,17 +1,15 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
@ -22,7 +20,6 @@ import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public final class DrakeFamiliar extends CardImpl {
@ -52,38 +49,33 @@ public final class DrakeFamiliar extends CardImpl {
class DrakeFamiliarEffect extends OneShotEffect {
private static final String effectText = "sacrifice it unless you return an enchantment to its owner's hand.";
DrakeFamiliarEffect() {
super(Outcome.Sacrifice);
staticText = effectText;
staticText = "sacrifice it unless you return an enchantment to its owner's hand.";
}
DrakeFamiliarEffect (DrakeFamiliarEffect effect) {
private DrakeFamiliarEffect(DrakeFamiliarEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
boolean targetChosen = false;
TargetPermanent target = new TargetPermanent(1, 1, StaticFilters.FILTER_ENCHANTMENT_PERMANENT, true);
if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.chooseUse(outcome, "Return an enchantment to its owner's hand?", source, game)) {
controller.chooseTarget(Outcome.Sacrifice, target, source, game);
if (controller == null) {
return false;
}
TargetPermanent target = new TargetPermanent(StaticFilters.FILTER_ENCHANTMENT_PERMANENT);
target.setNotTarget(true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)
&& controller.chooseUse(outcome, "Return an enchantment to its owner's hand?", source, game)) {
controller.chooseTarget(Outcome.ReturnToHand, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
targetChosen = true;
permanent.moveToZone(Zone.HAND, source, game, false);
return controller.moveCards(permanent, Zone.HAND, source, game);
}
}
if (!targetChosen) {
new SacrificeSourceEffect().apply(game, source);
}
return true;
}
return false;
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
return permanent != null && permanent.sacrifice(source, game);
}
@Override

View file

@ -72,9 +72,7 @@ public class DiesCreatureTriggeredAbility extends TriggeredAbilityImpl {
if (zEvent.isDiesEvent()) {
if (filter.match(zEvent.getTarget(), sourceId, controllerId, game)) {
if (setTargetPointer) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId(), game));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
}
return true;
}