mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
refactored more search effects
This commit is contained in:
parent
01a0d23a55
commit
f5374c6571
6 changed files with 344 additions and 235 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue