refactored more search effects

This commit is contained in:
Evan Kranzler 2020-11-13 18:39:50 -05:00
parent 01a0d23a55
commit f5374c6571
6 changed files with 344 additions and 235 deletions

View file

@ -1,29 +1,27 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.dynamicvalue.common.SubTypeAssignment;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
/**
*
* @author jeffwadsworth
*/
public final class CorpseHarvester extends CardImpl {
@ -37,7 +35,9 @@ public final class CorpseHarvester extends CardImpl {
this.toughness = new MageInt(3);
// {1}{B}, {tap}, Sacrifice a creature: Search your library for a Zombie card and a Swamp card, reveal them, and put them into your hand. Then shuffle your library.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CorpseHarvesterEffect(), new ManaCostsImpl("{1}{B}"));
Ability ability = new SimpleActivatedAbility(new SearchLibraryPutInHandEffect(
new KrosanVergeTarget(), true
), new ManaCostsImpl("{1}{B}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
this.addAbility(ability);
@ -53,46 +53,48 @@ public final class CorpseHarvester extends CardImpl {
}
}
class CorpseHarvesterEffect extends OneShotEffect {
class KrosanVergeTarget extends TargetCardInLibrary {
CorpseHarvesterEffect() {
super(Outcome.DrawCard);
staticText = "Search your library for a Zombie card and a Swamp card, reveal them, and put them into your hand. Then shuffle your library";
private static final FilterCard filter
= new FilterCard("a Zombie card and a Swamp card");
static {
filter.add(Predicates.or(
SubType.ZOMBIE.getPredicate(),
SubType.SWAMP.getPredicate()
));
}
CorpseHarvesterEffect(final CorpseHarvesterEffect effect) {
super(effect);
private static final SubTypeAssignment subTypeAssigner
= new SubTypeAssignment(SubType.ZOMBIE, SubType.SWAMP);
KrosanVergeTarget() {
super(0, 2, filter);
}
private KrosanVergeTarget(final KrosanVergeTarget target) {
super(target);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
if (you == null) {
public KrosanVergeTarget copy() {
return new KrosanVergeTarget(this);
}
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Cards cards = new CardsImpl();
searchCard(you, source, game, cards, "Zombie");
searchCard(you, source, game, cards, "Swamp");
you.revealCards("Corpse Harvester", cards, game);
you.shuffleLibrary(source, game);
return true;
}
private void searchCard(Player player, Ability source, Game game, Cards cards, String subtype) {
FilterCard filter = new FilterCard(subtype);
filter.add(SubType.byDescription(subtype).getPredicate());
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, source, game)) {
Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
cards.add(card);
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
}
@Override
public CorpseHarvesterEffect copy() {
return new CorpseHarvesterEffect(this);
if (this.getTargets().isEmpty()) {
return true;
}
Cards cards = new CardsImpl(this.getTargets());
cards.add(card);
return subTypeAssigner.getRoleCount(cards, game) >= cards.size();
}
}

View file

@ -1,35 +1,37 @@
package mage.cards.g;
import java.util.UUID;
import mage.abilities.Ability;
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.dynamicvalue.common.SubTypeAssignment;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterLandCard;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
*
* @author North
*/
public final class GemOfBecoming extends CardImpl {
public GemOfBecoming(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {3}, {tap}, Sacrifice Gem of Becoming: Search your library for an Island card, a Swamp card, and a Mountain card.
// Reveal those cards and put them into your hand. Then shuffle your library.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GemOfBecomingEffect(), new GenericManaCost(3));
Ability ability = new SimpleActivatedAbility(
new SearchLibraryPutInHandEffect(
new GemOfBecomingTarget(), true
), new GenericManaCost(3)
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
@ -45,51 +47,52 @@ public final class GemOfBecoming extends CardImpl {
}
}
class GemOfBecomingEffect extends OneShotEffect {
class GemOfBecomingTarget extends TargetCardInLibrary {
public GemOfBecomingEffect() {
super(Outcome.DrawCard);
this.staticText = "Search your library for an Island card, a Swamp card, and a Mountain card. Reveal those cards and put them into your hand. Then shuffle your library";
private static final FilterCard filter
= new FilterCard("an Island card, a Swamp card, and a Mountain card");
static {
filter.add(Predicates.or(
SubType.ISLAND.getPredicate(),
SubType.SWAMP.getPredicate(),
SubType.MOUNTAIN.getPredicate()
));
}
public GemOfBecomingEffect(final GemOfBecomingEffect effect) {
super(effect);
private static final SubTypeAssignment subTypeAssigner = new SubTypeAssignment(
SubType.ISLAND,
SubType.SWAMP,
SubType.MOUNTAIN
);
GemOfBecomingTarget() {
super(0, 3, filter);
}
private GemOfBecomingTarget(final GemOfBecomingTarget target) {
super(target);
}
@Override
public GemOfBecomingEffect copy() {
return new GemOfBecomingEffect(this);
public GemOfBecomingTarget copy() {
return new GemOfBecomingTarget(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Cards cards = new CardsImpl();
searchLand(player, source, game, cards, "Island");
searchLand(player, source, game, cards, "Swamp");
searchLand(player, source, game, cards, "Mountain");
player.revealCards("Gem of Becoming", cards, game);
player.shuffleLibrary(source, game);
return false;
}
private void searchLand(Player player, Ability source, Game game, Cards cards, String subtype) {
FilterLandCard filter = new FilterLandCard(subtype);
filter.add(SubType.byDescription(subtype).getPredicate());
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, source, game)) {
Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
cards.add(card);
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
if (this.getTargets().isEmpty()) {
return true;
}
Cards cards = new CardsImpl(this.getTargets());
cards.add(card);
return subTypeAssigner.getRoleCount(cards, game) >= cards.size();
}
}

View file

@ -2,17 +2,24 @@ package mage.cards.j;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
@ -24,7 +31,7 @@ public final class JourneyForTheElixir extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
// Search your library and graveyard for a basic land card and a card named Jiang Yanggu, reveal them, put them into your hand, then shuffle your library.
this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new JourneyForTheElixirTarget()));
this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new JourneyForTheElixirLibraryTarget()));
}
public JourneyForTheElixir(final JourneyForTheElixir card) {
@ -37,7 +44,43 @@ public final class JourneyForTheElixir extends CardImpl {
}
}
class JourneyForTheElixirTarget extends TargetCardInLibrary {
class JourneyForTheElixirEffect extends OneShotEffect {
JourneyForTheElixirEffect() {
super(Outcome.Benefit);
staticText = "Search your library and graveyard for a basic land card and a card named Jiang Yanggu, " +
"reveal them, put them into your hand, then shuffle your library.";
}
private JourneyForTheElixirEffect(final JourneyForTheElixirEffect effect) {
super(effect);
}
@Override
public JourneyForTheElixirEffect copy() {
return new JourneyForTheElixirEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
TargetCardInLibrary targetCardInLibrary = new JourneyForTheElixirLibraryTarget();
player.searchLibrary(targetCardInLibrary, source, game);
Cards cards = new CardsImpl(targetCardInLibrary.getTargets());
TargetCard target = new JourneyForTheElixirGraveyardTarget(cards);
player.choose(outcome, target, source.getSourceId(), game);
cards.addAll(target.getTargets());
player.revealCards(source, cards, game);
player.moveCards(cards, Zone.HAND, source, game);
player.shuffleLibrary(source, game);
return true;
}
}
class JourneyForTheElixirLibraryTarget extends TargetCardInLibrary {
private static final String name = "Jiang Yanggu";
private static final FilterCard filter
@ -53,17 +96,17 @@ class JourneyForTheElixirTarget extends TargetCardInLibrary {
));
}
JourneyForTheElixirTarget() {
JourneyForTheElixirLibraryTarget() {
super(0, 2, filter);
}
private JourneyForTheElixirTarget(final JourneyForTheElixirTarget target) {
private JourneyForTheElixirLibraryTarget(final JourneyForTheElixirLibraryTarget target) {
super(target);
}
@Override
public JourneyForTheElixirTarget copy() {
return new JourneyForTheElixirTarget(this);
public JourneyForTheElixirLibraryTarget copy() {
return new JourneyForTheElixirLibraryTarget(this);
}
@Override
@ -100,3 +143,70 @@ class JourneyForTheElixirTarget extends TargetCardInLibrary {
return true;
}
}
class JourneyForTheElixirGraveyardTarget extends TargetCardInYourGraveyard {
private static final String name = "Jiang Yanggu";
private static final FilterCard filter
= new FilterCard("a basic land card and a card named Jiang Yanggu");
static {
filter.add(Predicates.or(
Predicates.and(
SuperType.BASIC.getPredicate(),
CardType.LAND.getPredicate()
),
new NamePredicate(name)
));
}
private final Cards cards = new CardsImpl();
JourneyForTheElixirGraveyardTarget(Cards cards) {
super(0, Integer.MAX_VALUE, filter, true);
this.cards.addAll(cards);
}
private JourneyForTheElixirGraveyardTarget(final JourneyForTheElixirGraveyardTarget target) {
super(target);
this.cards.addAll(cards);
}
@Override
public JourneyForTheElixirGraveyardTarget copy() {
return new JourneyForTheElixirGraveyardTarget(this);
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID playerId, Game game) {
Set<UUID> possibleTargets = super.possibleTargets(sourceId, playerId, game);
Cards alreadyTargeted = new CardsImpl(this.getTargets());
alreadyTargeted.addAll(cards);
boolean hasBasic = alreadyTargeted
.getCards(game)
.stream()
.filter(Objects::nonNull)
.filter(MageObject::isLand)
.anyMatch(MageObject::isBasic);
possibleTargets.removeIf(uuid -> {
Card card = game.getCard(uuid);
return card != null
&& hasBasic
&& card.isLand()
&& card.isBasic();
});
boolean hasYanggu = alreadyTargeted
.getCards(game)
.stream()
.filter(Objects::nonNull)
.map(MageObject::getName)
.anyMatch(name::equals);
possibleTargets.removeIf(uuid -> {
Card card = game.getCard(uuid);
return card != null
&& hasYanggu
&& name.equals(card.getName());
});
return possibleTargets;
}
}

View file

@ -1,57 +1,46 @@
package mage.cards.k;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTappedAbility;
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.Effect;
import mage.abilities.dynamicvalue.common.SubTypeAssignment;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class KrosanVerge extends CardImpl {
private static final FilterCard filterForest = new FilterCard("a Forest");
private static final FilterCard filterPlains = new FilterCard("a Plains");
static {
filterForest.add(SubType.FOREST.getPredicate());
filterPlains.add(SubType.PLAINS.getPredicate());
}
public KrosanVerge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
// Krosan Verge enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {tap}: Add {C}.
this.addAbility(new ColorlessManaAbility());
// {2}, {T}, Sacrifice Krosan Verge: Search your library for a Forest card and a Plains card and put them onto the battlefield tapped. Then shuffle your library.
Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterForest), true, Outcome.PutLandInPlay);
effect.setText("Search your library for a Forest card and a Plains card and put them onto the battlefield tapped. Then shuffle your library");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterPlains), true, Outcome.PutLandInPlay);
effect.setText(null);
ability.addEffect(effect);
Ability ability = new SimpleActivatedAbility(new SearchLibraryPutInPlayEffect(
new KrosanVergeTarget(), true, Outcome.PutLandInPlay
), new GenericManaCost(2));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
public KrosanVerge(final KrosanVerge card) {
@ -63,3 +52,49 @@ public final class KrosanVerge extends CardImpl {
return new KrosanVerge(this);
}
}
class KrosanVergeTarget extends TargetCardInLibrary {
private static final FilterCard filter
= new FilterCard("a Forest card and a Plains card");
static {
filter.add(Predicates.or(
SubType.FOREST.getPredicate(),
SubType.PLAINS.getPredicate()
));
}
private static final SubTypeAssignment subTypeAssigner
= new SubTypeAssignment(SubType.FOREST, SubType.PLAINS);
KrosanVergeTarget() {
super(0, 2, filter);
}
private KrosanVergeTarget(final KrosanVergeTarget target) {
super(target);
}
@Override
public KrosanVergeTarget copy() {
return new KrosanVergeTarget(this);
}
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
if (this.getTargets().isEmpty()) {
return true;
}
Cards cards = new CardsImpl(this.getTargets());
cards.add(card);
return subTypeAssigner.getRoleCount(cards, game) >= cards.size();
}
}

View file

@ -1,40 +1,35 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.SubType;
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.game.events.GameEvent;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.Objects;
import java.util.UUID;
/**
*
* @author emerald000
*/
public final class ProteanHulk extends CardImpl {
public ProteanHulk(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// When Protean Hulk dies, search your library for any number of creature cards with total converted mana cost 6 or less and put them onto the battlefield. Then shuffle your library.
this.addAbility(new DiesSourceTriggeredAbility(new ProteanHulkEffect()));
this.addAbility(new DiesSourceTriggeredAbility(new SearchLibraryPutInPlayEffect(new ProteanHulkTarget())));
}
public ProteanHulk(final ProteanHulk card) {
@ -47,70 +42,35 @@ public final class ProteanHulk extends CardImpl {
}
}
class ProteanHulkEffect extends OneShotEffect {
class ProteanHulkTarget extends TargetCardInLibrary {
ProteanHulkEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "search your library for any number of creature cards with total converted mana cost 6 or less and put them onto the battlefield. Then shuffle your library";
private static final FilterCard filter
= new FilterCreatureCard("any number of creature cards with total converted mana cost 6 or less");
ProteanHulkTarget() {
super(0, Integer.MAX_VALUE, filter);
}
ProteanHulkEffect(final ProteanHulkEffect effect) {
super(effect);
private ProteanHulkTarget(final ProteanHulkTarget target) {
super(target);
}
@Override
public ProteanHulkEffect copy() {
return new ProteanHulkEffect(this);
public ProteanHulkTarget copy() {
return new ProteanHulkTarget(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Cards cardsPicked = this.ProteanHulkSearch(game, source);
controller.moveCards(cardsPicked.getCards(game), Zone.BATTLEFIELD, source, game);
controller.shuffleLibrary(source, game);
return true;
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
return false;
}
Cards ProteanHulkSearch(Game game, Ability source) {
Cards cardsPicked = new CardsImpl();
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
GameEvent event = GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, source.getControllerId(), source.getControllerId(), source.getControllerId(), Integer.MAX_VALUE);
if (!game.replaceEvent(event)) {
int manaCostLeftToFetch = 6;
int librarySearchLimit = event.getAmount();
FilterCard filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (6 CMC left)");
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, manaCostLeftToFetch + 1));
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter);
target.setCardLimit(librarySearchLimit);
while (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
target.choose(Outcome.PutCreatureInPlay, source.getControllerId(), source.getControllerId(), game);
Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card == null) {
break;
}
cardsPicked.add(card);
game.getState().getLookedAt(source.getControllerId()).add("Protean Hulk", cardsPicked);
librarySearchLimit--;
if (librarySearchLimit == 0) {
break;
}
manaCostLeftToFetch -= card.getConvertedManaCost();
filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (" + manaCostLeftToFetch + " CMC left)");
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, manaCostLeftToFetch + 1));
target = new TargetCardInLibrary(0, 1, filter);
target.setCardLimit(librarySearchLimit);
}
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, source.getControllerId(), source.getControllerId()));
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
return cardsPicked;
Cards cards = new CardsImpl(this.getTargets());
cards.add(id);
return cards.getCards(game).stream().filter(Objects::nonNull).mapToInt(MageObject::getConvertedManaCost).sum() <= 6;
}
}

View file

@ -1,35 +1,31 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.abilities.dynamicvalue.common.SubTypeAssignment;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterLandCard;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
/**
*
* @author Loki
*/
public final class ShardConvergence extends CardImpl {
public ShardConvergence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// Search your library for a Plains card, an Island card, a Swamp card, and a Mountain card. Reveal those cards and put them into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new ShardConvergenceEffect());
this.getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(
new ShardConvergenceTarget(), true
));
}
public ShardConvergence(final ShardConvergence card) {
@ -42,51 +38,54 @@ public final class ShardConvergence extends CardImpl {
}
}
class ShardConvergenceEffect extends OneShotEffect {
ShardConvergenceEffect() {
super(Outcome.DrawCard);
staticText = "Search your library for a Plains card, an Island card, a Swamp card, and a Mountain card. Reveal those cards and put them into your hand. Then shuffle your library";
class ShardConvergenceTarget extends TargetCardInLibrary {
private static final FilterCard filter
= new FilterCard("a Plains card, an Island card, a Swamp card, and a Mountain card");
static {
filter.add(Predicates.or(
SubType.PLAINS.getPredicate(),
SubType.ISLAND.getPredicate(),
SubType.SWAMP.getPredicate(),
SubType.MOUNTAIN.getPredicate()
));
}
ShardConvergenceEffect(final ShardConvergenceEffect effect) {
super(effect);
private static final SubTypeAssignment subTypeAssigner = new SubTypeAssignment(
SubType.PLAINS,
SubType.ISLAND,
SubType.SWAMP,
SubType.MOUNTAIN
);
ShardConvergenceTarget() {
super(0, 4, filter);
}
private ShardConvergenceTarget(final ShardConvergenceTarget target) {
super(target);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
public ShardConvergenceTarget copy() {
return new ShardConvergenceTarget(this);
}
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Cards cards = new CardsImpl();
searchLand(player, source, game, cards, "Plains");
searchLand(player, source, game, cards, "Island");
searchLand(player, source, game, cards, "Swamp");
searchLand(player, source, game, cards, "Mountain");
player.revealCards("Shard Convergence", cards, game);
player.shuffleLibrary(source, game);
return true;
}
private void searchLand(Player player, Ability source, Game game, Cards cards, String subtype) {
FilterLandCard filter = new FilterLandCard(subtype);
filter.add(SubType.byDescription(subtype).getPredicate());
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, source, game)) {
Card card = player.getLibrary().remove(target.getFirstTarget(), game);
if (card != null) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
cards.add(card);
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
if (this.getTargets().isEmpty()) {
return true;
}
Cards cards = new CardsImpl(this.getTargets());
cards.add(card);
return subTypeAssigner.getRoleCount(cards, game) >= cards.size();
}
@Override
public ShardConvergenceEffect copy() {
return new ShardConvergenceEffect(this);
}
}
}