mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 21:29:17 -08:00
refactor: improved targets that find a [type1] card and/or a [type2] card (#11497)
This commit is contained in:
parent
f3e310cfd3
commit
264b73355a
11 changed files with 212 additions and 459 deletions
|
|
@ -6,16 +6,13 @@ import mage.abilities.common.SimpleActivatedAbility;
|
|||
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.dynamicvalue.common.SubTypeAssignment;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.abilities.mana.WhiteManaAbility;
|
||||
import mage.cards.*;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -35,9 +32,7 @@ public final class AxgardArmory extends CardImpl {
|
|||
|
||||
// {1}{R}{R}{W}, {T}: Sacrifice Axgard Armory: Search your library for an Aura card and/or Equipment card, reveal them, put them into your hand, then shuffle your library.
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new SearchLibraryPutInHandEffect(new AxgardArmoryTarget(), true)
|
||||
.setText("search your library for an Aura card and/or an Equipment card, reveal them, " +
|
||||
"put them into your hand, then shuffle"),
|
||||
new SearchLibraryPutInHandEffect(new TargetCardAndOrCardInLibrary(SubType.AURA, SubType.EQUIPMENT), true),
|
||||
new ManaCostsImpl<>("{1}{R}{R}{W}")
|
||||
);
|
||||
ability.addCost(new TapSourceCost());
|
||||
|
|
@ -54,49 +49,3 @@ public final class AxgardArmory extends CardImpl {
|
|||
return new AxgardArmory(this);
|
||||
}
|
||||
}
|
||||
|
||||
class AxgardArmoryTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterCard("an Aura card and/or an Equipment card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
SubType.AURA.getPredicate(),
|
||||
SubType.EQUIPMENT.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
private static final SubTypeAssignment subTypeAssigner
|
||||
= new SubTypeAssignment(SubType.AURA, SubType.EQUIPMENT);
|
||||
|
||||
AxgardArmoryTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private AxgardArmoryTarget(final AxgardArmoryTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxgardArmoryTarget copy() {
|
||||
return new AxgardArmoryTarget(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,11 +1,7 @@
|
|||
|
||||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
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;
|
||||
|
|
@ -13,11 +9,12 @@ import mage.cards.CardsImpl;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.common.FilterEnchantmentCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -44,9 +41,11 @@ public final class BenefactionOfRhonas extends CardImpl {
|
|||
|
||||
class BenefactionOfRhonasEffect extends OneShotEffect {
|
||||
|
||||
public BenefactionOfRhonasEffect() {
|
||||
BenefactionOfRhonasEffect() {
|
||||
super(Outcome.DrawCard);
|
||||
this.staticText = "Reveal the top five cards of your library. You may put a creature card and/or an enchantment card from among them into your hand. Put the rest into your graveyard";
|
||||
this.staticText = "Reveal the top five cards of your library. " +
|
||||
"You may put a creature card and/or an enchantment card from among them into your hand. " +
|
||||
"Put the rest into your graveyard";
|
||||
}
|
||||
|
||||
private BenefactionOfRhonasEffect(final BenefactionOfRhonasEffect effect) {
|
||||
|
|
@ -60,52 +59,19 @@ class BenefactionOfRhonasEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (sourceObject != null && controller != null) {
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
|
||||
boolean creatureCardFound = false;
|
||||
boolean enchantmentCardFound = false;
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
if (card.isCreature(game)) {
|
||||
creatureCardFound = true;
|
||||
}
|
||||
if (card.isEnchantment(game)) {
|
||||
enchantmentCardFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cards.isEmpty()) {
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
if ((creatureCardFound || enchantmentCardFound)
|
||||
&& controller.chooseUse(Outcome.DrawCard,
|
||||
"Put a creature card and/or enchantment card into your hand?", source, game)) {
|
||||
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCreatureCard("creature card to put into your hand"));
|
||||
if (creatureCardFound && controller.chooseTarget(Outcome.DrawCard, cards, target, source, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
}
|
||||
}
|
||||
|
||||
target = new TargetCard(Zone.LIBRARY, new FilterEnchantmentCard("enchantment card to put into your hand"));
|
||||
if (enchantmentCardFound && controller.chooseTarget(Outcome.DrawCard, cards, target, source, game)) {
|
||||
Card card = cards.get(target.getFirstTarget(), game);
|
||||
if (card != null) {
|
||||
cards.remove(card);
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 5));
|
||||
player.revealCards(source, cards, game);
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.ENCHANTMENT);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toHand = new CardsImpl();
|
||||
toHand.addAll(target.getTargets());
|
||||
player.moveCards(toHand, Zone.HAND, source, game);
|
||||
cards.removeAll(toHand);
|
||||
player.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,15 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.CardTypeAssignment;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -63,7 +60,7 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
|
||||
TargetCard target = new GiftOfTheGargantuanTarget();
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toHand = new CardsImpl();
|
||||
toHand.addAll(target.getTargets());
|
||||
|
|
@ -74,49 +71,3 @@ class GiftOfTheGargantuanEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class GiftOfTheGargantuanTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterCard("a creature card and/or a land card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
private static final CardTypeAssignment cardTypeAssigner
|
||||
= new CardTypeAssignment(CardType.CREATURE, CardType.LAND);
|
||||
|
||||
GiftOfTheGargantuanTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private GiftOfTheGargantuanTarget(final GiftOfTheGargantuanTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GiftOfTheGargantuanTarget copy() {
|
||||
return new GiftOfTheGargantuanTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,15 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.CardTypeAssignment;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -66,7 +63,7 @@ class GreenSunsTwilightEffect extends OneShotEffect {
|
|||
int xValue = source.getManaCostsToPay().getX();
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, xValue + 1));
|
||||
player.revealCards(source, cards, game);
|
||||
TargetCard target = new GreenSunsTwilightTarget();
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toMove = new CardsImpl(target.getTargets());
|
||||
if (!toMove.isEmpty()) {
|
||||
|
|
@ -81,49 +78,3 @@ class GreenSunsTwilightEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class GreenSunsTwilightTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterCard("a creature card and/or a land card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
private static final CardTypeAssignment cardTypeAssigner
|
||||
= new CardTypeAssignment(CardType.CREATURE, CardType.LAND);
|
||||
|
||||
GreenSunsTwilightTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private GreenSunsTwilightTarget(final GreenSunsTwilightTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GreenSunsTwilightTarget copy() {
|
||||
return new GreenSunsTwilightTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,15 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.CardTypeAssignment;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -25,7 +22,7 @@ public final class InThePresenceOfAges extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}");
|
||||
|
||||
// Reveal the top four cards of your library. You may put a creature card and/or a land card from among them into your hand. Put the rest into your graveyard.
|
||||
this.getSpellAbility().addEffect(new InThePresenceOfAgeEffect());
|
||||
this.getSpellAbility().addEffect(new InThePresenceOfAgesEffect());
|
||||
}
|
||||
|
||||
private InThePresenceOfAges(final InThePresenceOfAges card) {
|
||||
|
|
@ -38,22 +35,22 @@ public final class InThePresenceOfAges extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class InThePresenceOfAgeEffect extends OneShotEffect {
|
||||
class InThePresenceOfAgesEffect extends OneShotEffect {
|
||||
|
||||
InThePresenceOfAgeEffect() {
|
||||
InThePresenceOfAgesEffect() {
|
||||
super(Outcome.DrawCard);
|
||||
this.staticText = "Reveal the top four cards of your library. "
|
||||
+ "You may put a creature card and/or a land card from among them into your hand. "
|
||||
+ "Put the rest into your graveyard";
|
||||
}
|
||||
|
||||
private InThePresenceOfAgeEffect(final InThePresenceOfAgeEffect effect) {
|
||||
private InThePresenceOfAgesEffect(final InThePresenceOfAgesEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InThePresenceOfAgeEffect copy() {
|
||||
return new InThePresenceOfAgeEffect(this);
|
||||
public InThePresenceOfAgesEffect copy() {
|
||||
return new InThePresenceOfAgesEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -64,7 +61,7 @@ class InThePresenceOfAgeEffect extends OneShotEffect {
|
|||
}
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
|
||||
player.revealCards(source, cards, game);
|
||||
TargetCard target = new InThePresenceOfAgesTarget();
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toHand = new CardsImpl();
|
||||
toHand.addAll(target.getTargets());
|
||||
|
|
@ -74,49 +71,3 @@ class InThePresenceOfAgeEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class InThePresenceOfAgesTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterCard("a creature card and/or a land card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
private static final CardTypeAssignment cardTypeAssigner
|
||||
= new CardTypeAssignment(CardType.CREATURE, CardType.LAND);
|
||||
|
||||
InThePresenceOfAgesTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private InThePresenceOfAgesTarget(final InThePresenceOfAgesTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InThePresenceOfAgesTarget copy() {
|
||||
return new InThePresenceOfAgesTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.CardTypeAssignment;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.continuous.SwitchPowerToughnessTargetEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.cards.*;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterInstantOrSorceryCard;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
|
|
@ -35,7 +33,8 @@ public final class InvertInvent extends SplitCard {
|
|||
|
||||
// Invent
|
||||
// Search your library for an instant card and/or a sorcery card, reveal them, put them into your hand, then shuffle your library.
|
||||
this.getRightHalfCard().getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(new InventTarget(), true).setText("search your library for an instant card and/or a sorcery card, reveal them, put them into your hand, then shuffle"));
|
||||
this.getRightHalfCard().getSpellAbility().addEffect(new SearchLibraryPutInHandEffect(
|
||||
new TargetCardAndOrCardInLibrary(CardType.INSTANT, CardType.SORCERY), true));
|
||||
}
|
||||
|
||||
private InvertInvent(final InvertInvent card) {
|
||||
|
|
@ -75,41 +74,3 @@ class InvertEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class InventTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterInstantOrSorceryCard("an instant card and/or a sorcery card");
|
||||
private static final CardTypeAssignment cardTypeAssigner
|
||||
= new CardTypeAssignment(CardType.INSTANT, CardType.SORCERY);
|
||||
|
||||
InventTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private InventTarget(final InventTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InventTarget copy() {
|
||||
return new InventTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
|
@ -8,10 +7,7 @@ import mage.abilities.effects.common.CreateTokenEffect;
|
|||
import mage.abilities.effects.common.GetEmblemEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.common.FilterLandCard;
|
||||
import mage.game.Game;
|
||||
import mage.game.command.emblems.KioraMasterOfTheDepthsEmblem;
|
||||
import mage.game.permanent.token.OctopusToken;
|
||||
|
|
@ -19,7 +15,7 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
|
@ -94,11 +90,6 @@ class KioraUntapEffect extends OneShotEffect {
|
|||
|
||||
class KioraRevealEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterCard creatureFilter
|
||||
= new FilterCreatureCard("creature card to put into your hand");
|
||||
private static final FilterCard landFilter
|
||||
= new FilterLandCard("land card to put into your hand");
|
||||
|
||||
KioraRevealEffect() {
|
||||
super(Outcome.DrawCard);
|
||||
this.staticText = "Reveal the top four cards of your library. " +
|
||||
|
|
@ -117,46 +108,19 @@ class KioraRevealEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller == null || sourceObject == null) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
|
||||
boolean creatureCardFound = cards.getCards(game).stream().anyMatch(card -> card.isCreature(game));
|
||||
boolean landCardFound = cards.getCards(game).stream().anyMatch(card -> card.isLand(game));
|
||||
|
||||
if (!creatureCardFound && !landCardFound) {
|
||||
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
Cards cardsToHand = new CardsImpl();
|
||||
|
||||
if (creatureCardFound) {
|
||||
TargetCard target = new TargetCardInLibrary(0, 1, creatureFilter);
|
||||
controller.chooseTarget(Outcome.DrawCard, cards, target, source, game);
|
||||
if (target.getFirstTarget() != null) {
|
||||
cards.remove(target.getFirstTarget());
|
||||
cardsToHand.add(target.getFirstTarget());
|
||||
}
|
||||
}
|
||||
if (landCardFound) {
|
||||
TargetCard target = new TargetCardInLibrary(0, 1, landFilter);
|
||||
controller.chooseTarget(Outcome.DrawCard, cards, target, source, game);
|
||||
if (target.getFirstTarget() != null) {
|
||||
cards.remove(target.getFirstTarget());
|
||||
cardsToHand.add(target.getFirstTarget());
|
||||
}
|
||||
}
|
||||
controller.moveCards(cardsToHand, Zone.HAND, source, game);
|
||||
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
|
||||
player.revealCards(source, cards, game);
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toHand = new CardsImpl();
|
||||
toHand.addAll(target.getTargets());
|
||||
player.moveCards(toHand, Zone.HAND, source, game);
|
||||
cards.removeAll(toHand);
|
||||
player.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,18 +5,15 @@ import mage.MageObject;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
|
||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||
import mage.abilities.dynamicvalue.common.CardTypeAssignment;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -118,7 +115,7 @@ class OjerKaslemDeepestGrowthEffect extends OneShotEffect {
|
|||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, xValue));
|
||||
if (!cards.isEmpty()) {
|
||||
controller.revealCards(source, cards, game);
|
||||
TargetCard target = new OjerKaslemDeepestGrowthTarget();
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
controller.choose(Outcome.PutCardInPlay, cards, target, source, game);
|
||||
Cards toBattlefield = new CardsImpl(target.getTargets());
|
||||
cards.removeAll(toBattlefield);
|
||||
|
|
@ -128,49 +125,3 @@ class OjerKaslemDeepestGrowthEffect extends OneShotEffect {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class OjerKaslemDeepestGrowthTarget extends TargetCardInLibrary {
|
||||
|
||||
private static final FilterCard filter
|
||||
= new FilterCard("a creature card and/or a land card");
|
||||
|
||||
static {
|
||||
filter.add(Predicates.or(
|
||||
CardType.CREATURE.getPredicate(),
|
||||
CardType.LAND.getPredicate()
|
||||
));
|
||||
}
|
||||
|
||||
private static final CardTypeAssignment cardTypeAssigner
|
||||
= new CardTypeAssignment(CardType.CREATURE, CardType.LAND);
|
||||
|
||||
OjerKaslemDeepestGrowthTarget() {
|
||||
super(0, 2, filter);
|
||||
}
|
||||
|
||||
private OjerKaslemDeepestGrowthTarget(final OjerKaslemDeepestGrowthTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OjerKaslemDeepestGrowthTarget copy() {
|
||||
return new OjerKaslemDeepestGrowthTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
package mage.cards.r;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterCreatureCard;
|
||||
import mage.filter.common.FilterLandCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardAndOrCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -41,10 +40,6 @@ public final class RelentlessPursuit extends CardImpl {
|
|||
|
||||
class RelentlessPursuitEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterCard creatureFilter
|
||||
= new FilterCreatureCard("creature card to put into your hand");
|
||||
private static final FilterCard landFilter
|
||||
= new FilterLandCard("land card to put into your hand");
|
||||
|
||||
RelentlessPursuitEffect() {
|
||||
super(Outcome.DrawCard);
|
||||
|
|
@ -64,46 +59,19 @@ class RelentlessPursuitEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = game.getObject(source);
|
||||
if (controller == null || sourceObject == null) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4));
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
controller.revealCards(sourceObject.getName(), cards, game);
|
||||
|
||||
boolean creatureCardFound = cards.getCards(game).stream().anyMatch(card -> card.isCreature(game));
|
||||
boolean landCardFound = cards.getCards(game).stream().anyMatch(card -> card.isLand(game));
|
||||
|
||||
if (!creatureCardFound && !landCardFound) {
|
||||
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
|
||||
Cards cardsToHand = new CardsImpl();
|
||||
|
||||
if (creatureCardFound) {
|
||||
TargetCard target = new TargetCardInLibrary(0, 1, creatureFilter);
|
||||
controller.chooseTarget(Outcome.DrawCard, cards, target, source, game);
|
||||
if (target.getFirstTarget() != null) {
|
||||
cards.remove(target.getFirstTarget());
|
||||
cardsToHand.add(target.getFirstTarget());
|
||||
}
|
||||
}
|
||||
if (landCardFound) {
|
||||
TargetCard target = new TargetCardInLibrary(0, 1, landFilter);
|
||||
controller.chooseTarget(Outcome.DrawCard, cards, target, source, game);
|
||||
if (target.getFirstTarget() != null) {
|
||||
cards.remove(target.getFirstTarget());
|
||||
cardsToHand.add(target.getFirstTarget());
|
||||
}
|
||||
}
|
||||
controller.moveCards(cardsToHand, Zone.HAND, source, game);
|
||||
controller.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 4));
|
||||
player.revealCards(source, cards, game);
|
||||
TargetCard target = new TargetCardAndOrCardInLibrary(CardType.CREATURE, CardType.LAND);
|
||||
player.choose(outcome, cards, target, source, game);
|
||||
Cards toHand = new CardsImpl();
|
||||
toHand.addAll(target.getTargets());
|
||||
player.moveCards(toHand, Zone.HAND, source, game);
|
||||
cards.removeAll(toHand);
|
||||
player.moveCards(cards, Zone.GRAVEYARD, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package mage.abilities.dynamicvalue.common;
|
||||
|
||||
import mage.abilities.dynamicvalue.RoleAssignment;
|
||||
import mage.cards.Card;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PredicateCardAssignment extends RoleAssignment<Predicate<? super Card>> {
|
||||
|
||||
public PredicateCardAssignment(Predicate<? super Card>... predicates) {
|
||||
super(predicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Predicate<? super Card>> makeSet(Card card, Game game) {
|
||||
return attributes
|
||||
.stream()
|
||||
.filter(predicate -> predicate.apply(card, game))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
package mage.target.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.PredicateCardAssignment;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.Game;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author xenohedron
|
||||
*/
|
||||
public class TargetCardAndOrCardInLibrary extends TargetCardInLibrary {
|
||||
|
||||
private static FilterCard makeFilter(Predicate<? super Card> firstPredicate,
|
||||
Predicate<? super Card> secondPredicate,
|
||||
String filterText) {
|
||||
FilterCard filter = new FilterCard(filterText);
|
||||
filter.add(Predicates.or(
|
||||
firstPredicate, secondPredicate
|
||||
));
|
||||
return filter;
|
||||
}
|
||||
|
||||
private static String makeFilterText(String first, String second) {
|
||||
return CardUtil.addArticle(first) + " card and/or " + CardUtil.addArticle(second) + " card";
|
||||
}
|
||||
|
||||
private final PredicateCardAssignment assignment;
|
||||
|
||||
/**
|
||||
* a [firstType] card and/or a [secondType] card
|
||||
*/
|
||||
protected TargetCardAndOrCardInLibrary(Predicate<? super Card> firstPredicate, Predicate<? super Card> secondPredicate, String filterText) {
|
||||
super(0, 2, makeFilter(firstPredicate, secondPredicate, filterText));
|
||||
this.assignment = new PredicateCardAssignment(firstPredicate, secondPredicate);
|
||||
}
|
||||
|
||||
public TargetCardAndOrCardInLibrary(CardType firstType, CardType secondType) {
|
||||
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(
|
||||
CardUtil.getTextWithFirstCharLowerCase(firstType.toString()),
|
||||
CardUtil.getTextWithFirstCharLowerCase(secondType.toString())));
|
||||
}
|
||||
|
||||
public TargetCardAndOrCardInLibrary(SubType firstType, SubType secondType) {
|
||||
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(firstType.getDescription(), secondType.getDescription()));
|
||||
}
|
||||
|
||||
protected TargetCardAndOrCardInLibrary(final TargetCardAndOrCardInLibrary target) {
|
||||
super(target);
|
||||
this.assignment = target.assignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetCardAndOrCardInLibrary copy() {
|
||||
return new TargetCardAndOrCardInLibrary(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 assignment.getRoleCount(cards, game) >= cards.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
||||
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
||||
// assuming max targets = 2, need to expand this code if not
|
||||
Card card = game.getCard(this.getFirstTarget());
|
||||
if (card == null) {
|
||||
return possibleTargets; // no further restriction if no target yet chosen
|
||||
}
|
||||
Cards cards = new CardsImpl(card);
|
||||
if (assignment.getRoleCount(cards, game) == 2) {
|
||||
// if the first chosen target is both types, no further restriction
|
||||
return possibleTargets;
|
||||
}
|
||||
Set<UUID> leftPossibleTargets = new HashSet<>();
|
||||
for (UUID possibleId : possibleTargets) {
|
||||
Card possibleCard = game.getCard(possibleId);
|
||||
Cards checkCards = cards.copy();
|
||||
checkCards.add(possibleCard);
|
||||
if (assignment.getRoleCount(checkCards, game) == 2) {
|
||||
// if the possible target and the existing target have both types, it's legal
|
||||
// but this prevents the case of both targets with the same type
|
||||
leftPossibleTargets.add(possibleId);
|
||||
}
|
||||
}
|
||||
return leftPossibleTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return filter.getMessage();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue