diff --git a/Mage.Sets/src/mage/cards/a/AxgardArmory.java b/Mage.Sets/src/mage/cards/a/AxgardArmory.java index ea84ad41b0b..fb5628f23b2 100644 --- a/Mage.Sets/src/mage/cards/a/AxgardArmory.java +++ b/Mage.Sets/src/mage/cards/a/AxgardArmory.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java b/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java index df0a489a239..6a049609220 100644 --- a/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java +++ b/Mage.Sets/src/mage/cards/b/BenefactionOfRhonas.java @@ -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; } } diff --git a/Mage.Sets/src/mage/cards/g/GiftOfTheGargantuan.java b/Mage.Sets/src/mage/cards/g/GiftOfTheGargantuan.java index b2c3f564c49..06856891a08 100644 --- a/Mage.Sets/src/mage/cards/g/GiftOfTheGargantuan.java +++ b/Mage.Sets/src/mage/cards/g/GiftOfTheGargantuan.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GreenSunsTwilight.java b/Mage.Sets/src/mage/cards/g/GreenSunsTwilight.java index a2fd1869131..d1f1cc7da87 100644 --- a/Mage.Sets/src/mage/cards/g/GreenSunsTwilight.java +++ b/Mage.Sets/src/mage/cards/g/GreenSunsTwilight.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/i/InThePresenceOfAges.java b/Mage.Sets/src/mage/cards/i/InThePresenceOfAges.java index 303b7018bc3..be1204d56c6 100644 --- a/Mage.Sets/src/mage/cards/i/InThePresenceOfAges.java +++ b/Mage.Sets/src/mage/cards/i/InThePresenceOfAges.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/i/InvertInvent.java b/Mage.Sets/src/mage/cards/i/InvertInvent.java index 7b6c644dd38..3fe1e6e40e0 100644 --- a/Mage.Sets/src/mage/cards/i/InvertInvent.java +++ b/Mage.Sets/src/mage/cards/i/InvertInvent.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KioraMasterOfTheDepths.java b/Mage.Sets/src/mage/cards/k/KioraMasterOfTheDepths.java index 43c60b94115..460f12eb0b9 100644 --- a/Mage.Sets/src/mage/cards/k/KioraMasterOfTheDepths.java +++ b/Mage.Sets/src/mage/cards/k/KioraMasterOfTheDepths.java @@ -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; } } diff --git a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java index 025eecbc3f7..e405ca69b25 100644 --- a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java +++ b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java @@ -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(); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RelentlessPursuit.java b/Mage.Sets/src/mage/cards/r/RelentlessPursuit.java index 1d156693a96..997062f1b00 100644 --- a/Mage.Sets/src/mage/cards/r/RelentlessPursuit.java +++ b/Mage.Sets/src/mage/cards/r/RelentlessPursuit.java @@ -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; } } diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PredicateCardAssignment.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PredicateCardAssignment.java new file mode 100644 index 00000000000..af55119b3f1 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PredicateCardAssignment.java @@ -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> { + + public PredicateCardAssignment(Predicate... predicates) { + super(predicates); + } + + @Override + protected Set> makeSet(Card card, Game game) { + return attributes + .stream() + .filter(predicate -> predicate.apply(card, game)) + .collect(Collectors.toSet()); + } +} diff --git a/Mage/src/main/java/mage/target/common/TargetCardAndOrCardInLibrary.java b/Mage/src/main/java/mage/target/common/TargetCardAndOrCardInLibrary.java new file mode 100644 index 00000000000..58b1338e1ba --- /dev/null +++ b/Mage/src/main/java/mage/target/common/TargetCardAndOrCardInLibrary.java @@ -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 firstPredicate, + Predicate 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 firstPredicate, Predicate 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 possibleTargets(UUID sourceControllerId, Ability source, Game game) { + Set 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 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(); + } +}