diff --git a/Mage.Sets/src/mage/cards/c/CharmbreakerDevils.java b/Mage.Sets/src/mage/cards/c/CharmbreakerDevils.java index 1a9932fc4b5..82b1407e919 100644 --- a/Mage.Sets/src/mage/cards/c/CharmbreakerDevils.java +++ b/Mage.Sets/src/mage/cards/c/CharmbreakerDevils.java @@ -1,20 +1,14 @@ package mage.cards.c; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -32,7 +26,8 @@ public final class CharmbreakerDevils extends CardImpl { // At the beginning of your upkeep, return an instant or sorcery card at random from your graveyard to your hand. this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new CharmbreakerDevilsEffect(), TargetController.YOU, false + new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, Zone.HAND), + TargetController.YOU, false )); // Whenever you cast an instant or sorcery spell, Charmbreaker Devils gets +4/+0 until end of turn. @@ -51,34 +46,3 @@ public final class CharmbreakerDevils extends CardImpl { return new CharmbreakerDevils(this); } } - -class CharmbreakerDevilsEffect extends OneShotEffect { - - CharmbreakerDevilsEffect() { - super(Outcome.ReturnToHand); - this.staticText = "return an instant or sorcery card at random from your graveyard to your hand"; - } - - private CharmbreakerDevilsEffect(final CharmbreakerDevilsEffect effect) { - super(effect); - } - - @Override - public CharmbreakerDevilsEffect copy() { - return new CharmbreakerDevilsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - 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.withNotTarget(true); - target.chooseTarget(outcome, player.getId(), source, game); - Card card = game.getCard(target.getFirstTarget()); - return card != null && player.moveCards(card, Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/e/ExaltedFlamerOfTzeentch.java b/Mage.Sets/src/mage/cards/e/ExaltedFlamerOfTzeentch.java index a97ada539f9..0a6f5455d3b 100644 --- a/Mage.Sets/src/mage/cards/e/ExaltedFlamerOfTzeentch.java +++ b/Mage.Sets/src/mage/cards/e/ExaltedFlamerOfTzeentch.java @@ -1,16 +1,14 @@ package mage.cards.e; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamagePlayersEffect; -import mage.cards.*; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; import java.util.UUID; @@ -28,7 +26,7 @@ public final class ExaltedFlamerOfTzeentch extends CardImpl { // Sorcerous Inspiration -- At the beginning of your upkeep, return an instant or sorcery card at random from your graveyard to your hand. this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new ExaltedFlamerOfTzeentchEffect(), TargetController.YOU, false + new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, Zone.HAND), TargetController.YOU, false ).withFlavorWord("Sorcerous Inspiration")); // Fire of Tzeentch -- Whenever you cast an instant or sorcery spell, Exalted Flamer of Tzeentch deals 1 damage to each opponent. @@ -47,31 +45,3 @@ public final class ExaltedFlamerOfTzeentch extends CardImpl { return new ExaltedFlamerOfTzeentch(this); } } - -class ExaltedFlamerOfTzeentchEffect extends OneShotEffect { - - ExaltedFlamerOfTzeentchEffect() { - super(Outcome.Benefit); - staticText = "return an instant or sorcery card at random from your graveyard to your hand"; - } - - private ExaltedFlamerOfTzeentchEffect(final ExaltedFlamerOfTzeentchEffect effect) { - super(effect); - } - - @Override - public ExaltedFlamerOfTzeentchEffect copy() { - return new ExaltedFlamerOfTzeentchEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Cards cards = new CardsImpl(player.getGraveyard().getCards(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY, game)); - Card card = cards.getRandom(game); - return card != null && player.moveCards(card, Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/g/Ghoulraiser.java b/Mage.Sets/src/mage/cards/g/Ghoulraiser.java index a94a16552cd..c831fc09eab 100644 --- a/Mage.Sets/src/mage/cards/g/Ghoulraiser.java +++ b/Mage.Sets/src/mage/cards/g/Ghoulraiser.java @@ -1,20 +1,14 @@ package mage.cards.g; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -23,6 +17,11 @@ import java.util.UUID; */ public final class Ghoulraiser extends CardImpl { + private static final FilterCard filter = new FilterCard("a Zombie card"); + static { + filter.add(SubType.ZOMBIE.getPredicate()); + } + public Ghoulraiser(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); this.subtype.add(SubType.ZOMBIE); @@ -31,7 +30,8 @@ public final class Ghoulraiser extends CardImpl { this.toughness = new MageInt(2); // When Ghoulraiser enters the battlefield, return a Zombie card at random from your graveyard to your hand. - this.addAbility(new EntersBattlefieldTriggeredAbility(new GhoulraiserEffect(), false)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardAtRandomEffect( + filter, Zone.HAND), false)); } private Ghoulraiser(final Ghoulraiser card) { @@ -43,39 +43,3 @@ public final class Ghoulraiser extends CardImpl { return new Ghoulraiser(this); } } - -class GhoulraiserEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCard(); - - static { - filter.add(SubType.ZOMBIE.getPredicate()); - } - - GhoulraiserEffect() { - super(Outcome.ReturnToHand); - this.staticText = "return a Zombie card at random from your graveyard to your hand"; - } - - private GhoulraiserEffect(final GhoulraiserEffect effect) { - super(effect); - } - - @Override - public GhoulraiserEffect copy() { - return new GhoulraiserEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getGraveyard().count(filter, game) < 1) { - return false; - } - TargetCard target = new TargetCardInYourGraveyard(filter); - target.withNotTarget(true); - target.setRandom(true); - target.chooseTarget(outcome, player.getId(), source, game); - return player.moveCards(game.getCard(target.getFirstTarget()), Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HauntedFengraf.java b/Mage.Sets/src/mage/cards/h/HauntedFengraf.java index dc84d9b0418..7cf4cddd8fd 100644 --- a/Mage.Sets/src/mage/cards/h/HauntedFengraf.java +++ b/Mage.Sets/src/mage/cards/h/HauntedFengraf.java @@ -5,18 +5,13 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -32,7 +27,8 @@ public final class HauntedFengraf extends CardImpl { this.addAbility(new ColorlessManaAbility()); // {3}, {tap}, Sacrifice Haunted Fengraf: Return a creature card at random from your graveyard to your hand. - Ability ability = new SimpleActivatedAbility(new HauntedFengrafEffect(), new GenericManaCost(3)); + Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardAtRandomEffect( + StaticFilters.FILTER_CARD_CREATURE, Zone.HAND), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); @@ -47,33 +43,3 @@ public final class HauntedFengraf extends CardImpl { return new HauntedFengraf(this); } } - -class HauntedFengrafEffect extends OneShotEffect { - - HauntedFengrafEffect() { - super(Outcome.ReturnToHand); - this.staticText = "Return a creature card at random from your graveyard to your hand"; - } - - private HauntedFengrafEffect(final HauntedFengrafEffect effect) { - super(effect); - } - - @Override - public HauntedFengrafEffect copy() { - return new HauntedFengrafEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) { - return false; - } - TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE); - target.withNotTarget(true); - target.setRandom(true); - target.chooseTarget(outcome, player.getId(), source, game); - return player.moveCards(game.getCard(target.getFirstTarget()), Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MakeAWish.java b/Mage.Sets/src/mage/cards/m/MakeAWish.java index e14d7a4f0a8..79a510cbf18 100644 --- a/Mage.Sets/src/mage/cards/m/MakeAWish.java +++ b/Mage.Sets/src/mage/cards/m/MakeAWish.java @@ -1,18 +1,11 @@ package mage.cards.m; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -25,7 +18,7 @@ public final class MakeAWish extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); // Return two cards at random from your graveyard to your hand. - this.getSpellAbility().addEffect(new MakeAWishEffect()); + this.getSpellAbility().addEffect(new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_CARDS, Zone.HAND, 2)); } private MakeAWish(final MakeAWish card) { @@ -37,33 +30,3 @@ public final class MakeAWish extends CardImpl { return new MakeAWish(this); } } - -class MakeAWishEffect extends OneShotEffect { - - MakeAWishEffect() { - super(Outcome.ReturnToHand); - this.staticText = "Return two cards at random from your graveyard to your hand"; - } - - private MakeAWishEffect(final MakeAWishEffect effect) { - super(effect); - } - - @Override - public MakeAWishEffect copy() { - return new MakeAWishEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getGraveyard().isEmpty()) { - return false; - } - TargetCard target = new TargetCardInYourGraveyard(Math.min(player.getGraveyard().size(), 2), StaticFilters.FILTER_CARD); - target.withNotTarget(true); - target.setRandom(true); - target.chooseTarget(outcome, player.getId(), source, game); - return player.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java b/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java index df95f362f15..e504e77652e 100644 --- a/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java +++ b/Mage.Sets/src/mage/cards/m/MoldgrafMonstrosity.java @@ -1,26 +1,19 @@ - package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSourceEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.keyword.TrampleAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; + +import java.util.UUID; /** * @@ -36,11 +29,11 @@ public final class MoldgrafMonstrosity extends CardImpl { this.toughness = new MageInt(8); this.addAbility(TrampleAbility.getInstance()); + // When Moldgraf Monstrosity dies, exile it, then return two creature cards at random from your graveyard to the battlefield. - Effect effect = new ExileSourceEffect(); - effect.setText(""); - DiesSourceTriggeredAbility ability = new DiesSourceTriggeredAbility(effect); - ability.addEffect(new MoldgrafMonstrosityEffect()); + Ability ability = new DiesSourceTriggeredAbility(new ExileSourceEffect().setText("exile it")); + ability.addEffect(new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_CREATURES, Zone.BATTLEFIELD, 2) + .concatBy(", then")); this.addAbility(ability); } @@ -53,40 +46,3 @@ public final class MoldgrafMonstrosity extends CardImpl { return new MoldgrafMonstrosity(this); } } - -class MoldgrafMonstrosityEffect extends OneShotEffect { - - public MoldgrafMonstrosityEffect() { - super(Outcome.ReturnToHand); - this.staticText = "exile it, then return two creature cards at random from your graveyard to the battlefield"; - } - - private MoldgrafMonstrosityEffect(final MoldgrafMonstrosityEffect effect) { - super(effect); - } - - @Override - public MoldgrafMonstrosityEffect copy() { - return new MoldgrafMonstrosityEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Cards possibleCards = new CardsImpl(controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game)); - // Set cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game); - Cards toBattlefield = new CardsImpl(); - for (int i = 0; i < 2; i++) { - Card card = possibleCards.getRandom(game); - if (card != null) { - toBattlefield.add(card); - possibleCards.remove(card); - } - } - controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SurrealMemoir.java b/Mage.Sets/src/mage/cards/s/SurrealMemoir.java index b9ecc0c4d4d..42f63d3b96e 100644 --- a/Mage.Sets/src/mage/cards/s/SurrealMemoir.java +++ b/Mage.Sets/src/mage/cards/s/SurrealMemoir.java @@ -1,19 +1,14 @@ package mage.cards.s; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.keyword.ReboundAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; 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.util.RandomUtil; + +import java.util.UUID; /** * @@ -21,11 +16,16 @@ import mage.util.RandomUtil; */ public final class SurrealMemoir extends CardImpl { + private static final FilterCard filter = new FilterCard("an instant card"); + static { + filter.add(CardType.INSTANT.getPredicate()); + } + public SurrealMemoir(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Return an instant card at random from your graveyard to your hand. - this.getSpellAbility().addEffect(new SurrealMemoirEffect()); + this.getSpellAbility().addEffect(new ReturnFromGraveyardAtRandomEffect(filter, Zone.HAND)); this.addAbility(new ReboundAbility()); } @@ -38,39 +38,3 @@ public final class SurrealMemoir extends CardImpl { return new SurrealMemoir(this); } } - -class SurrealMemoirEffect extends OneShotEffect { - - public SurrealMemoirEffect() { - super(Outcome.ReturnToHand); - this.staticText = "Return an instant card at random from your graveyard to your hand"; - } - - private SurrealMemoirEffect(final SurrealMemoirEffect effect) { - super(effect); - } - - @Override - public SurrealMemoirEffect copy() { - return new SurrealMemoirEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - FilterCard filter = new FilterCard("instant card"); - filter.add(CardType.INSTANT.getPredicate()); - Card[] cards = controller.getGraveyard().getCards(filter, game).toArray(new Card[0]); - if (cards.length > 0) { - Card card = cards[RandomUtil.nextInt(cards.length)]; - if (card != null - && controller.moveCards(card, Zone.HAND, source, game)) { - game.informPlayers(card.getName() + "returned to the hand of" + controller.getLogName()); - return true; - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java b/Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java index 8095367489a..f07f860e66b 100644 --- a/Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java +++ b/Mage.Sets/src/mage/cards/t/TheDeckOfManyThings.java @@ -9,6 +9,7 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.LoseGameTargetPlayerEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.effects.common.RollDieWithResultTableEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -20,9 +21,7 @@ import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetCard; import mage.target.common.TargetCardInGraveyard; -import mage.target.common.TargetCardInYourGraveyard; import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -60,7 +59,7 @@ class TheDeckOfManyThingsEffect extends RollDieWithResultTableEffect { TheDeckOfManyThingsEffect() { super(20, "roll a d20 and subtract the number of cards in your hand. If the result is 0 or less, discard your hand"); - this.addTableEntry(1, 9, new TheDeckOfManyThingsRandomEffect()); + this.addTableEntry(1, 9, new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD, Zone.HAND)); this.addTableEntry(10, 19, new DrawCardSourceControllerEffect(2)); this.addTableEntry(20, 20, new TheDeckOfManyThingsReturnEffect()); } @@ -89,38 +88,6 @@ class TheDeckOfManyThingsEffect extends RollDieWithResultTableEffect { } } -class TheDeckOfManyThingsRandomEffect extends OneShotEffect { - - TheDeckOfManyThingsRandomEffect() { - super(Outcome.ReturnToHand); - staticText = "return a card at random from your graveyard to your hand"; - } - - private TheDeckOfManyThingsRandomEffect(final TheDeckOfManyThingsRandomEffect effect) { - super(effect); - } - - @Override - public TheDeckOfManyThingsRandomEffect copy() { - return new TheDeckOfManyThingsRandomEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD, game) < 1) { - return false; - } - TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD); - target.setRandom(true); - target.withNotTarget(true); - target.chooseTarget(outcome, player.getId(), source, game); - - Card card = game.getCard(target.getFirstTarget()); - return card != null && player.moveCards(card, Zone.HAND, source, game); - } -} - class TheDeckOfManyThingsReturnEffect extends OneShotEffect { TheDeckOfManyThingsReturnEffect() { diff --git a/Mage.Sets/src/mage/cards/t/TombTyrant.java b/Mage.Sets/src/mage/cards/t/TombTyrant.java index 6e8641b5d07..03942f84180 100644 --- a/Mage.Sets/src/mage/cards/t/TombTyrant.java +++ b/Mage.Sets/src/mage/cards/t/TombTyrant.java @@ -12,12 +12,11 @@ import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.hint.common.MyTurnHint; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -25,9 +24,6 @@ import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.players.Player; -import mage.util.RandomUtil; import java.util.UUID; @@ -37,7 +33,7 @@ import java.util.UUID; public final class TombTyrant extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.ZOMBIE, "Zombies"); - private static final FilterCard filter2 = new FilterCreatureCard(); + private static final FilterCard filter2 = new FilterCreatureCard("a Zombie creature card"); static { filter2.add(SubType.ZOMBIE.getPredicate()); @@ -66,7 +62,7 @@ public final class TombTyrant extends CardImpl { // {2}{B}, {T}, Sacrifice a creature: Return a Zombie creature card at random from your graveyard to the battlefield. Activate only during your turn and only if there are at least three Zombie creature cards in your graveyard. Ability ability = new ActivateIfConditionActivatedAbility( - Zone.BATTLEFIELD, new TombTyrantEffect(), + Zone.BATTLEFIELD, new ReturnFromGraveyardAtRandomEffect(filter2, Zone.BATTLEFIELD), new ManaCostsImpl<>("{2}{B}"), condition ); ability.addCost(new TapSourceCost()); @@ -83,36 +79,3 @@ public final class TombTyrant extends CardImpl { return new TombTyrant(this); } } - -class TombTyrantEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCreatureCard(); - - static { - filter.add(SubType.ZOMBIE.getPredicate()); - } - - TombTyrantEffect() { - super(Outcome.Benefit); - staticText = "return a Zombie creature card at random from your graveyard to the battlefield"; - } - - private TombTyrantEffect(final TombTyrantEffect effect) { - super(effect); - } - - @Override - public TombTyrantEffect copy() { - return new TombTyrantEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Card card = RandomUtil.randomFromCollection(player.getGraveyard().getCards(filter, game)); - return card != null && player.moveCards(card, Zone.BATTLEFIELD, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/v/ViconiaDrowApostate.java b/Mage.Sets/src/mage/cards/v/ViconiaDrowApostate.java index e9015bcc08b..647dab378b6 100644 --- a/Mage.Sets/src/mage/cards/v/ViconiaDrowApostate.java +++ b/Mage.Sets/src/mage/cards/v/ViconiaDrowApostate.java @@ -1,24 +1,19 @@ package mage.cards.v; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.ChooseABackgroundAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInControllerGraveyardCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.util.RandomUtil; import java.util.UUID; @@ -46,7 +41,8 @@ public final class ViconiaDrowApostate extends CardImpl { // At the beginning of your upkeep, if there are four or more creature cards in your graveyard, return a creature card at random from your graveyard to your hand. this.addAbility(new ConditionalInterveningIfTriggeredAbility( new BeginningOfUpkeepTriggeredAbility( - new ViconiaDrowApostateEffect(), TargetController.YOU, false + new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.HAND), + TargetController.YOU, false ), condition, "At the beginning of your upkeep, if there are four or more creature cards " + "in your graveyard, return a creature card at random from your graveyard to your hand." ).addHint(hint)); @@ -64,31 +60,3 @@ public final class ViconiaDrowApostate extends CardImpl { return new ViconiaDrowApostate(this); } } - -class ViconiaDrowApostateEffect extends OneShotEffect { - - ViconiaDrowApostateEffect() { - super(Outcome.Benefit); - } - - private ViconiaDrowApostateEffect(final ViconiaDrowApostateEffect effect) { - super(effect); - } - - @Override - public ViconiaDrowApostateEffect copy() { - return new ViconiaDrowApostateEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Card card = RandomUtil.randomFromCollection( - player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game) - ); - return card != null && player.moveCards(card, Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java b/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java index f3cfdde9d64..cfccd0f8ea2 100644 --- a/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java +++ b/Mage.Sets/src/mage/cards/w/WoodlandSleuth.java @@ -1,25 +1,20 @@ package mage.cards.w; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.MorbidCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardAtRandomEffect; import mage.abilities.hint.common.MorbidHint; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.util.RandomUtil; + +import java.util.UUID; /** * @@ -39,7 +34,8 @@ public final class WoodlandSleuth extends CardImpl { this.toughness = new MageInt(3); // Morbid — When Woodland Sleuth enters the battlefield, if a creature died this turn, return a creature card at random from your graveyard to your hand. - TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new WoodlandSleuthEffect()); + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility( + new ReturnFromGraveyardAtRandomEffect(StaticFilters.FILTER_CARD_CREATURE, Zone.HAND)); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MorbidCondition.instance, staticText).addHint(MorbidHint.instance)); } @@ -52,36 +48,3 @@ public final class WoodlandSleuth extends CardImpl { return new WoodlandSleuth(this); } } - -class WoodlandSleuthEffect extends OneShotEffect { - - public WoodlandSleuthEffect() { - super(Outcome.ReturnToHand); - this.staticText = "return a creature card at random from your graveyard to your hand"; - } - - private WoodlandSleuthEffect(final WoodlandSleuthEffect effect) { - super(effect); - } - - @Override - public WoodlandSleuthEffect copy() { - return new WoodlandSleuthEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Card[] cards = player.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game).toArray(new Card[0]); - if (cards.length > 0) { - Card card = cards[RandomUtil.nextInt(cards.length)]; - if (player.moveCards(card, Zone.HAND, source, game)) { - game.informPlayers(card.getName() + " returned to the hand of " + player.getLogName()); - return true; - } - } - } - return false; - } -} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardAtRandomEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardAtRandomEffect.java new file mode 100644 index 00000000000..bad3d64f35a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardAtRandomEffect.java @@ -0,0 +1,72 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardsImpl; +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.TargetCardInYourGraveyard; +import mage.util.CardUtil; + +/** + * @author xenohedron + */ +public class ReturnFromGraveyardAtRandomEffect extends OneShotEffect { + + private final FilterCard filter; + private final Zone zone; + private final int number; + + /** + * Returns one card from graveyard at random to the specified zone + * @param filter card filter (text should NOT include "from your graveyard") + * @param zone only Zone.HAND and Zone.BATTLEFIELD currently supported + */ + public ReturnFromGraveyardAtRandomEffect(FilterCard filter, Zone zone) { + this(filter, zone, 1); + } + + /** + * @param filter card filter (text should NOT include "from your graveyard") + * @param zone only Zone.HAND and Zone.BATTLEFIELD currently supported + * @param number number of cards to return at random + */ + public ReturnFromGraveyardAtRandomEffect(FilterCard filter, Zone zone, int number) { + super(Outcome.ReturnToHand); + this.filter = filter; + this.zone = zone; + this.number = number; + this.staticText = "return " + + (number == 1 ? CardUtil.addArticle(filter.getMessage()) : CardUtil.numberToText(number) + " " + filter.getMessage()) + + " at random from your graveyard to " + (zone == Zone.HAND ? "your hand" : "the battlefield"); + } + + protected ReturnFromGraveyardAtRandomEffect(final ReturnFromGraveyardAtRandomEffect effect) { + super(effect); + this.filter = effect.filter; + this.zone = effect.zone; + this.number = effect.number; + } + + @Override + public ReturnFromGraveyardAtRandomEffect copy() { + return new ReturnFromGraveyardAtRandomEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null || player.getGraveyard().isEmpty()) { + return false; + } + TargetCard target = new TargetCardInYourGraveyard(Math.min(player.getGraveyard().size(), number), filter); + target.withNotTarget(true); + target.setRandom(true); + target.chooseTarget(outcome, player.getId(), source, game); + return player.moveCards(new CardsImpl(target.getTargets()), zone, source, game); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java index 28a3f1d9472..2f867be5bb2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnFromGraveyardToHandTargetEffect.java @@ -9,8 +9,6 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; -import mage.target.Target; -import mage.util.CardUtil; /** * @author jeff