diff --git a/Mage.Sets/src/mage/cards/a/AssemblyHall.java b/Mage.Sets/src/mage/cards/a/AssemblyHall.java index 8cdd37df5b8..f63ed694fa4 100644 --- a/Mage.Sets/src/mage/cards/a/AssemblyHall.java +++ b/Mage.Sets/src/mage/cards/a/AssemblyHall.java @@ -15,13 +15,12 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; import mage.filter.StaticFilters; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; -import mage.util.CardUtil; import java.util.UUID; @@ -74,19 +73,16 @@ class AssemblyHallEffect extends OneShotEffect { if (controller == null || controller.getHand().isEmpty() || sourceObject == null) { return false; } - Card cardToReveal = null; Target target = new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE); target.withNotTarget(true); - if (controller.chooseTarget(outcome, target, source, game)) { - cardToReveal = game.getCard(target.getFirstTarget()); - } + controller.chooseTarget(outcome, target, source, game); + Card cardToReveal = game.getCard(target.getFirstTarget()); if (cardToReveal == null) { return false; } controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game); - String nameToSearch = CardUtil.getCardNameForSameNameSearch(cardToReveal); - FilterCard filterCard = new FilterCard("card named " + nameToSearch); - filterCard.add(new NamePredicate(nameToSearch)); + FilterCard filterCard = new FilterCard("card with the same name as " + cardToReveal.getName()); + filterCard.add(new SharesNamePredicate(cardToReveal)); return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true).apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/a/AvenShrine.java b/Mage.Sets/src/mage/cards/a/AvenShrine.java index 91f75013814..1a38f94b0a5 100644 --- a/Mage.Sets/src/mage/cards/a/AvenShrine.java +++ b/Mage.Sets/src/mage/cards/a/AvenShrine.java @@ -1,27 +1,24 @@ - package mage.cards.a; -import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.constants.SetTargetPointer; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; import mage.players.Player; +import java.util.Collection; +import java.util.Objects; +import java.util.UUID; + /** - * - * @author jeffwadsworth + * @author TheElk801 */ public final class AvenShrine extends CardImpl { @@ -29,8 +26,10 @@ public final class AvenShrine extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); // Whenever a player casts a spell, that player gains X life, where X is the number of cards in all graveyards with the same name as that spell. - this.addAbility(new AvenShrineTriggeredAbility()); - + this.addAbility(new SpellCastAllTriggeredAbility( + new AvenShrineEffect(), StaticFilters.FILTER_SPELL_A, + false, SetTargetPointer.PLAYER + )); } private AvenShrine(final AvenShrine card) { @@ -43,78 +42,42 @@ public final class AvenShrine extends CardImpl { } } -class AvenShrineTriggeredAbility extends TriggeredAbilityImpl { - - public AvenShrineTriggeredAbility() { - super(Zone.BATTLEFIELD, new AvenShrineEffect(), false); - } - - private AvenShrineTriggeredAbility(final AvenShrineTriggeredAbility ability) { - super(ability); - } - - @Override - public AvenShrineTriggeredAbility copy() { - return new AvenShrineTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Spell spell = game.getStack().getSpell(event.getTargetId()); - MageObject mageObject = game.getObject(sourceId); - if (spell != null && mageObject != null) { - game.getState().setValue("avenShrine" + mageObject, spell); - return true; - } - return false; - } - -} - class AvenShrineEffect extends OneShotEffect { AvenShrineEffect() { - super(Outcome.GainLife); - staticText = "Whenever a player casts a spell, that player gains X life, where X is the number of cards in all graveyards with the same name as that spell"; + super(Outcome.Benefit); + staticText = "that player gains X life, where X is the number " + + "of cards in all graveyards with the same name as that spell"; } private AvenShrineEffect(final AvenShrineEffect effect) { super(effect); } - @Override - public boolean apply(Game game, Ability source) { - int count = 0; - MageObject mageObject = game.getObject(source); - if(mageObject != null) { - Spell spell = (Spell) game.getState().getValue("avenShrine" + mageObject); - if (spell != null) { - Player controller = game.getPlayer(spell.getControllerId()); - if (controller != null) { - String name = spell.getName(); - FilterCard filterCardName = new FilterCard(); - filterCardName.add(new NamePredicate(name)); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - count += player.getGraveyard().count(filterCardName, game); - } - } - controller.gainLife(count, game, source); - return true; - } - } - } - return false; - } - @Override public AvenShrineEffect copy() { return new AvenShrineEffect(this); } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + Spell spell = (Spell) getValue("spellCast"); + if (player == null || spell == null) { + return false; + } + int count = game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getGraveyard) + .map(g -> g.getCards(game)) + .flatMap(Collection::stream) + .filter(c -> c.sharesName(spell, game)) + .mapToInt(x -> 1) + .sum(); + return player.gainLife(count, game, source) > 0; + } } diff --git a/Mage.Sets/src/mage/cards/b/Banishment.java b/Mage.Sets/src/mage/cards/b/Banishment.java index 9e0695d1dd5..75b2ab6909e 100644 --- a/Mage.Sets/src/mage/cards/b/Banishment.java +++ b/Mage.Sets/src/mage/cards/b/Banishment.java @@ -13,7 +13,7 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -26,7 +26,6 @@ import java.util.UUID; import java.util.stream.Collectors; /** - * * @author freaisdead */ public final class Banishment extends CardImpl { @@ -39,7 +38,7 @@ public final class Banishment extends CardImpl { public Banishment(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); - + // Flash this.addAbility(FlashAbility.getInstance()); @@ -85,10 +84,10 @@ class BanishmentEffect extends OneShotEffect { } FilterPermanent filter = new FilterNonlandPermanent(); - filter.add(new NamePredicate(targeted.getName())); + filter.add(new SharesNamePredicate(targeted)); Set toExile = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game) - .stream().filter(p -> controller.hasOpponent(p.getControllerId(),game)) + .stream().filter(p -> controller.hasOpponent(p.getControllerId(), game)) .collect(Collectors.toCollection(LinkedHashSet::new)); if (!toExile.isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/b/BazaarOfWonders.java b/Mage.Sets/src/mage/cards/b/BazaarOfWonders.java index 21b4231ef81..86d85fc748e 100644 --- a/Mage.Sets/src/mage/cards/b/BazaarOfWonders.java +++ b/Mage.Sets/src/mage/cards/b/BazaarOfWonders.java @@ -1,28 +1,26 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.SetTargetPointer; +import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class BazaarOfWonders extends CardImpl { @@ -37,8 +35,7 @@ public final class BazaarOfWonders extends CardImpl { // Whenever a player casts a spell, counter it if a card with the same name is in // a graveyard or a nontoken permanent with the same name is on the battlefield. - this.addAbility(new SpellCastAllTriggeredAbility(new BazaarOfWondersEffect(), - StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.SPELL)); + this.addAbility(new SpellCastAllTriggeredAbility(new BazaarOfWondersEffect(), false)); } private BazaarOfWonders(final BazaarOfWonders card) { @@ -70,27 +67,21 @@ class BazaarOfWondersEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getSpell(getTargetPointer().getFirst(game, source)); + Spell spell = (Spell) getValue("spellCast"); if (spell == null) { return false; } - String spellName = spell.getName(); FilterPermanent filter1 = new FilterPermanent(); - filter1.add(new NamePredicate(spellName)); + filter1.add(new SharesNamePredicate(spell)); filter1.add(TokenPredicate.FALSE); - if (!game.getBattlefield().getActivePermanents(filter1, - source.getControllerId(), game).isEmpty()) { - game.getStack().counter(spell.getId(), source, game); - return true; + if (!game.getBattlefield().contains(filter1, source, game, 1)) { + return game.getStack().counter(spell.getId(), source, game); } FilterCard filter2 = new FilterCard(); - filter2.add(new NamePredicate(spellName)); + filter2.add(new SharesNamePredicate(spell)); for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - if (player == null) { - continue; - } - if (player.getGraveyard().count(filter2, game) > 0) { + if (player != null && player.getGraveyard().count(filter2, game) > 0) { return game.getStack().counter(spell.getId(), source, game); } } diff --git a/Mage.Sets/src/mage/cards/b/Bifurcate.java b/Mage.Sets/src/mage/cards/b/Bifurcate.java index da513140c6e..98ba0b4a247 100644 --- a/Mage.Sets/src/mage/cards/b/Bifurcate.java +++ b/Mage.Sets/src/mage/cards/b/Bifurcate.java @@ -1,4 +1,3 @@ - package mage.cards.b; import mage.abilities.Ability; @@ -11,7 +10,7 @@ import mage.constants.Outcome; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterPermanentCard; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.permanent.Permanent; @@ -21,10 +20,10 @@ import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** - * * @author ciaccona007 */ public final class Bifurcate extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creatures"); static { @@ -67,9 +66,12 @@ class BifurcateEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } FilterCard filter = new FilterPermanentCard(); - filter.add(new NamePredicate(permanent.getName())); + filter.add(new SharesNamePredicate(permanent)); return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)).apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/b/BloodbondMarch.java b/Mage.Sets/src/mage/cards/b/BloodbondMarch.java index 1acfeca7b43..ce791d4dff6 100644 --- a/Mage.Sets/src/mage/cards/b/BloodbondMarch.java +++ b/Mage.Sets/src/mage/cards/b/BloodbondMarch.java @@ -1,6 +1,5 @@ package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -12,13 +11,14 @@ import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureSpell; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; +import java.util.UUID; + /** - * * @author JRHerlehy */ public final class BloodbondMarch extends CardImpl { @@ -66,7 +66,7 @@ class BloodbondMarchEffect extends OneShotEffect { } FilterCard filter = new FilterCard(); - filter.add(new NamePredicate(spell.getName())); + filter.add(new SharesNamePredicate(spell)); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); diff --git a/Mage.Sets/src/mage/cards/c/CabalShrine.java b/Mage.Sets/src/mage/cards/c/CabalShrine.java index ec4d9f8fdc3..ba2ccaed5cb 100644 --- a/Mage.Sets/src/mage/cards/c/CabalShrine.java +++ b/Mage.Sets/src/mage/cards/c/CabalShrine.java @@ -1,36 +1,34 @@ - package mage.cards.c; -import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.constants.SetTargetPointer; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; import mage.players.Player; +import java.util.Collection; +import java.util.Objects; +import java.util.UUID; + /** - * - * @author jeffwadsworth + * @author TheElk801 */ public final class CabalShrine extends CardImpl { public CabalShrine(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}"); - // Whenever a player casts a spell, that player discards X cards, where X is the number of cards in all graveyards with the same name as that spell. - this.addAbility(new CabalShrineTriggeredAbility()); + this.addAbility(new SpellCastAllTriggeredAbility( + new CabalShrineEffect(), StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.PLAYER + )); } private CabalShrine(final CabalShrine card) { @@ -43,78 +41,42 @@ public final class CabalShrine extends CardImpl { } } -class CabalShrineTriggeredAbility extends TriggeredAbilityImpl { - - public CabalShrineTriggeredAbility() { - super(Zone.BATTLEFIELD, new CabalShrineEffect(), false); - } - - private CabalShrineTriggeredAbility(final CabalShrineTriggeredAbility ability) { - super(ability); - } - - @Override - public CabalShrineTriggeredAbility copy() { - return new CabalShrineTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Spell spell = game.getStack().getSpell(event.getTargetId()); - MageObject mageObject = game.getObject(sourceId); - if (spell != null && mageObject != null) { - game.getState().setValue("cabalShrine" + mageObject, spell); - return true; - } - return false; - } - -} - class CabalShrineEffect extends OneShotEffect { CabalShrineEffect() { - super(Outcome.Discard); - staticText = "Whenever a player casts a spell, that player discards X cards, where X is the number of cards in all graveyards with the same name as that spell"; + super(Outcome.Benefit); + staticText = "that player discards X cards, where X is the number " + + "of cards in all graveyards with the same name as that spell"; } private CabalShrineEffect(final CabalShrineEffect effect) { super(effect); } - @Override - public boolean apply(Game game, Ability source) { - int count = 0; - MageObject mageObject = game.getObject(source); - if(mageObject != null) { - Spell spell = (Spell) game.getState().getValue("cabalShrine" + mageObject); - if (spell != null) { - Player controller = game.getPlayer(spell.getControllerId()); - if (controller != null) { - String name = spell.getName(); - FilterCard filterCardName = new FilterCard(); - filterCardName.add(new NamePredicate(name)); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - count += player.getGraveyard().count(filterCardName, game); - } - } - controller.discard(count, false, false, source, game); - return true; - } - } - } - return false; - } - @Override public CabalShrineEffect copy() { return new CabalShrineEffect(this); } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + Spell spell = (Spell) getValue("spellCast"); + if (player == null || spell == null) { + return false; + } + int amount = game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getGraveyard) + .map(g -> g.getCards(game)) + .flatMap(Collection::stream) + .filter(c -> c.sharesName(spell, game)) + .mapToInt(x -> 1) + .sum(); + return amount > 0 && !player.discard(amount, false, false, source, game).isEmpty(); + } } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfMisfortunes.java b/Mage.Sets/src/mage/cards/c/CurseOfMisfortunes.java index a47226e30e8..c1148648b05 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfMisfortunes.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfMisfortunes.java @@ -15,7 +15,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -27,13 +27,12 @@ import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** - * * @author BetaSteward */ public final class CurseOfMisfortunes extends CardImpl { public CurseOfMisfortunes(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); this.subtype.add(SubType.AURA, SubType.CURSE); @@ -72,35 +71,35 @@ class CurseOfMisfortunesEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent enchantment = game.getPermanent(source.getSourceId()); - if (controller != null && enchantment != null && enchantment.getAttachedTo() != null) { - Player targetPlayer = game.getPlayer(enchantment.getAttachedTo()); - Player player = game.getPlayer(source.getControllerId()); - if (player != null && targetPlayer != null) { - FilterCard filter = new FilterCard("Curse card that doesn't have the same name as a Curse attached to enchanted player"); - filter.add(SubType.CURSE.getPredicate()); - // get the names of attached Curses - for (UUID attachmentId: targetPlayer.getAttachments()) { - Permanent attachment = game.getPermanent(attachmentId); - if (attachment != null && attachment.hasSubtype(SubType.CURSE, game)) { - filter.add(Predicates.not(new NamePredicate(attachment.getName()))); - } - } - TargetCardInLibrary targetCard = new TargetCardInLibrary(filter); - if (player.searchLibrary(targetCard, source, game)) { - Card card = game.getCard(targetCard.getFirstTarget()); - if (card != null) { - this.setTargetPointer(new FixedTarget(targetPlayer.getId())); - game.getState().setValue("attachTo:" + card.getId(), targetPlayer.getId()); - if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { - targetPlayer.addAttachment(card.getId(), source, game); - } - } - } - player.shuffleLibrary(source, game); - } + if (controller == null || enchantment == null || enchantment.getAttachedTo() == null) { + return false; + } + Player targetPlayer = game.getPlayer(enchantment.getAttachedTo()); + Player player = game.getPlayer(source.getControllerId()); + if (player == null || targetPlayer == null) { return true; } - return false; + FilterCard filter = new FilterCard("Curse card that doesn't have the same name as a Curse attached to enchanted player"); + filter.add(SubType.CURSE.getPredicate()); + // get the names of attached Curses + for (UUID attachmentId : targetPlayer.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.hasSubtype(SubType.CURSE, game)) { + filter.add(Predicates.not(new SharesNamePredicate(attachment))); + } + } + TargetCardInLibrary targetCard = new TargetCardInLibrary(filter); + player.searchLibrary(targetCard, source, game); + Card card = player.getLibrary().getCard(targetCard.getFirstTarget(), game); + if (card != null) { + this.setTargetPointer(new FixedTarget(targetPlayer.getId())); + game.getState().setValue("attachTo:" + card.getId(), targetPlayer.getId()); + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + targetPlayer.addAttachment(card.getId(), source, game); + } + } + player.shuffleLibrary(source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/e/EchoingCourage.java b/Mage.Sets/src/mage/cards/e/EchoingCourage.java index 819a311b6fd..cd1f9775869 100644 --- a/Mage.Sets/src/mage/cards/e/EchoingCourage.java +++ b/Mage.Sets/src/mage/cards/e/EchoingCourage.java @@ -1,23 +1,22 @@ package mage.cards.e; import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; +import mage.target.targetpointer.FixedTargets; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author LevelX2 @@ -27,7 +26,6 @@ public final class EchoingCourage extends CardImpl { public EchoingCourage(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); - // Target creature and all other creatures with the same name as that creature get +2/+2 until end of turn. this.getSpellAbility().addEffect(new EchoingCourageEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -47,7 +45,8 @@ class EchoingCourageEffect extends OneShotEffect { EchoingCourageEffect() { super(Outcome.Benefit); - this.staticText = "Target creature and all other creatures with the same name as that creature get +2/+2 until end of turn"; + this.staticText = "target creature and all other creatures with the " + + "same name as that creature get +2/+2 until end of turn"; } private EchoingCourageEffect(final EchoingCourageEffect effect) { @@ -62,17 +61,21 @@ class EchoingCourageEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (targetPermanent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - if (CardUtil.haveEmptyName(targetPermanent)) { - filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(targetPermanent.getName())); - } - ContinuousEffect effect = new BoostAllEffect(2, 2, Duration.EndOfTurn, filter, false); - game.addEffect(effect, source); - return true; + if (targetPermanent == null) { + return false; } - return false; + Set set = game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, + source.getControllerId(), source, game + ) + .stream() + .filter(permanent -> permanent.sharesName(targetPermanent, game)) + .collect(Collectors.toSet()); + set.add(targetPermanent); + game.addEffect(new BoostTargetEffect(2, 2) + .setTargetPointer(new FixedTargets(set, game)), source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EchoingDecay.java b/Mage.Sets/src/mage/cards/e/EchoingDecay.java index 74dc1b019af..fdbeed09f90 100644 --- a/Mage.Sets/src/mage/cards/e/EchoingDecay.java +++ b/Mage.Sets/src/mage/cards/e/EchoingDecay.java @@ -1,23 +1,22 @@ package mage.cards.e; import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; +import mage.target.targetpointer.FixedTargets; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author fireshoes @@ -46,7 +45,8 @@ class EchoingDecayEffect extends OneShotEffect { EchoingDecayEffect() { super(Outcome.Benefit); - this.staticText = "Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn"; + this.staticText = "target creature and all other creatures with the " + + "same name as that creature get -2/-2 until end of turn"; } private EchoingDecayEffect(final EchoingDecayEffect effect) { @@ -61,17 +61,21 @@ class EchoingDecayEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (targetPermanent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - if (CardUtil.haveEmptyName(targetPermanent)) { - filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(targetPermanent.getName())); - } - ContinuousEffect effect = new BoostAllEffect(-2, -2, Duration.EndOfTurn, filter, false); - game.addEffect(effect, source); - return true; + if (targetPermanent == null) { + return false; } - return false; + Set set = game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, + source.getControllerId(), source, game + ) + .stream() + .filter(permanent -> permanent.sharesName(targetPermanent, game)) + .collect(Collectors.toSet()); + set.add(targetPermanent); + game.addEffect(new BoostTargetEffect(-2, -2) + .setTargetPointer(new FixedTargets(set, game)), source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/e/EchoingTruth.java b/Mage.Sets/src/mage/cards/e/EchoingTruth.java index f7b9362a757..fc46b3bb1c3 100644 --- a/Mage.Sets/src/mage/cards/e/EchoingTruth.java +++ b/Mage.Sets/src/mage/cards/e/EchoingTruth.java @@ -1,26 +1,22 @@ package mage.cards.e; import mage.abilities.Ability; -import mage.abilities.Mode; 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.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; import mage.target.common.TargetNonlandPermanent; -import mage.util.CardUtil; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author LevelX2 @@ -31,9 +27,8 @@ public final class EchoingTruth extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return target nonland permanent and all other permanents with the same name as that permanent to their owners' hands. - Target target = new TargetNonlandPermanent(); - this.getSpellAbility().addTarget(target); this.getSpellAbility().addEffect(new ReturnToHandAllNamedPermanentsEffect()); + this.getSpellAbility().addTarget(new TargetNonlandPermanent()); } private EchoingTruth(final EchoingTruth card) { @@ -50,7 +45,8 @@ class ReturnToHandAllNamedPermanentsEffect extends OneShotEffect { ReturnToHandAllNamedPermanentsEffect() { super(Outcome.ReturnToHand); - this.staticText = "Return target nonland permanent and all other permanents with the same name as that permanent to their owners' hands"; + this.staticText = "return target nonland permanent and all other permanents " + + "with the same name as that permanent to their owners' hands"; } private ReturnToHandAllNamedPermanentsEffect(final ReturnToHandAllNamedPermanentsEffect effect) { @@ -64,22 +60,21 @@ class ReturnToHandAllNamedPermanentsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (controller != null && permanent != null) { - FilterPermanent filter = new FilterPermanent(); - if (CardUtil.haveEmptyName(permanent)) { - filter.add(new PermanentIdPredicate(permanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(permanent.getName())); - } - Cards cardsToHand = new CardsImpl(); - for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { - cardsToHand.add(perm); - } - controller.moveCards(cardsToHand, Zone.HAND, source, game); - return true; + Player player = game.getPlayer(source.getControllerId()); + Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (player == null || targetPermanent == null) { + return false; } - return true; + Set set = game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT, + source.getControllerId(), source, game + ) + .stream() + .filter(permanent -> permanent.sharesName(targetPermanent, game)) + .collect(Collectors.toSet()); + set.add(targetPermanent); + return player.moveCards(set, Zone.HAND, source, game); } } diff --git a/Mage.Sets/src/mage/cards/g/GuardianProject.java b/Mage.Sets/src/mage/cards/g/GuardianProject.java index a8c016fda54..5f56b3d8a5d 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianProject.java +++ b/Mage.Sets/src/mage/cards/g/GuardianProject.java @@ -8,15 +8,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.FilterCard; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.filter.predicate.mageobject.CardIdPredicate; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; @@ -87,22 +79,18 @@ class GuardianProjectTriggeredAbility extends EntersBattlefieldAllTriggeredAbili // This is needed as checkInterveningIfClause can't access trigger event information static boolean checkCondition(Permanent permanent, UUID controllerId, Game game) { Player player = game.getPlayer(controllerId); - if (player == null) { - return false; - } - if (!permanent.getName().isEmpty()) { - FilterCard filterCard = new FilterCard(); - filterCard.add(new NamePredicate(permanent.getName())); - filterCard.add(new OwnerIdPredicate(controllerId)); - if (player.getGraveyard().count(filterCard, game) > 0) { - return false; - } - } - FilterPermanent filterPermanent = new FilterCreaturePermanent(); - filterPermanent.add(new NamePredicate(permanent.getName())); - filterPermanent.add(Predicates.not(new CardIdPredicate(permanent.getId()))); - filterPermanent.add(new ControllerIdPredicate(controllerId)); - return game.getBattlefield().getActivePermanents(filterPermanent, controllerId, game).isEmpty(); + return player != null + && player + .getGraveyard() + .getCards(game) + .stream() + .noneMatch(card -> card.sharesName(permanent, game)) + && game + .getBattlefield() + .getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, controllerId, game) + .stream() + .filter(p -> !p.getId().equals(permanent.getId())) + .noneMatch(p -> p.sharesName(permanent, game)); } } diff --git a/Mage.Sets/src/mage/cards/h/HomingLightning.java b/Mage.Sets/src/mage/cards/h/HomingLightning.java index 8fa98cfcfb8..9b920eb5728 100644 --- a/Mage.Sets/src/mage/cards/h/HomingLightning.java +++ b/Mage.Sets/src/mage/cards/h/HomingLightning.java @@ -6,15 +6,14 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author jeffwadsworth @@ -24,7 +23,6 @@ public final class HomingLightning extends CardImpl { public HomingLightning(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}{R}"); - // Homing Lightning deals 4 damage to target creature and each other creature with the same name as that creature. this.getSpellAbility().addEffect(new HomingLightningEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -53,20 +51,22 @@ class HomingLightningEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (targetPermanent == null) { return false; } - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - if (CardUtil.haveEmptyName(targetPermanent)) { - filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(targetPermanent.getName())); - } - for (Permanent creature : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { - if (creature != null) { - creature.damage(4, source.getSourceId(), source, game, false, true); - } + Set set = game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, + source.getControllerId(), source, game + ) + .stream() + .filter(permanent -> permanent.sharesName(targetPermanent, game)) + .collect(Collectors.toSet()); + set.add(targetPermanent); + for (Permanent creature : set) { + creature.damage(4, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/i/InfernalTutor.java b/Mage.Sets/src/mage/cards/i/InfernalTutor.java index ffa1e548b5a..bcafbcb509d 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalTutor.java +++ b/Mage.Sets/src/mage/cards/i/InfernalTutor.java @@ -4,7 +4,6 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.condition.common.HellbentCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.cards.Card; @@ -15,13 +14,12 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; import mage.filter.StaticFilters; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; -import mage.util.CardUtil; import java.util.UUID; @@ -34,14 +32,14 @@ public final class InfernalTutor extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Reveal a card from your hand. Search your library for a card with the same name as that card, reveal it, put it into your hand, then shuffle your library. - this.getSpellAbility().addEffect(new InfernalTutorEffect()); // Hellbent - If you have no cards in hand, instead search your library for a card, put it into your hand, then shuffle your library. - Effect effect = new ConditionalOneShotEffect( + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD), false), - HellbentCondition.instance, - "

Hellbent — If you have no cards in hand, instead search your library for a card, put it into your hand, then shuffle"); - this.getSpellAbility().addEffect(effect); - + new InfernalTutorEffect(), HellbentCondition.instance, "Reveal a card from your hand. " + + "Search your library for a card with the same name as that card, reveal it, put it into your hand, " + + "then shuffle.
Hellbent — If you have no cards in hand, " + + "instead search your library for a card, put it into your hand, then shuffle" + )); } private InfernalTutor(final InfernalTutor card) { @@ -58,7 +56,6 @@ class InfernalTutorEffect extends OneShotEffect { InfernalTutorEffect() { super(Outcome.Benefit); - this.staticText = "Reveal a card from your hand. Search your library for a card with the same name as that card, reveal it, put it into your hand, then shuffle"; } private InfernalTutorEffect(final InfernalTutorEffect effect) { @@ -74,32 +71,21 @@ class InfernalTutorEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source); - if (controller != null && sourceObject != null) { - if (!controller.getHand().isEmpty()) { - Card cardToReveal = null; - if (controller.getHand().size() > 1) { - Target target = new TargetCardInHand(StaticFilters.FILTER_CARD); - target.withNotTarget(true); - if (controller.chooseTarget(outcome, target, source, game)) { - cardToReveal = game.getCard(target.getFirstTarget()); - } - } else { - cardToReveal = controller.getHand().getRandom(game); - } - FilterCard filterCard; - if (cardToReveal != null) { - controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game); - String nameToSearch = CardUtil.getCardNameForSameNameSearch(cardToReveal); - filterCard = new FilterCard("card named " + nameToSearch); - filterCard.add(new NamePredicate(nameToSearch)); - } else { - filterCard = new FilterCard(); - } - return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true).apply(game, source); - - } - return true; + if (controller == null || sourceObject == null) { + return false; } - return false; + Card cardToReveal; + if (controller.getHand().size() > 1) { + Target target = new TargetCardInHand(StaticFilters.FILTER_CARD); + target.withNotTarget(true); + controller.chooseTarget(outcome, target, source, game); + cardToReveal = game.getCard(target.getFirstTarget()); + } else { + cardToReveal = controller.getHand().getRandom(game); + } + controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game); + FilterCard filterCard = new FilterCard("card with the same name as the revealed card"); + filterCard.add(new SharesNamePredicate(cardToReveal)); + return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true).apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/i/IzzetStaticaster.java b/Mage.Sets/src/mage/cards/i/IzzetStaticaster.java index 47b212807e1..13af192cd33 100644 --- a/Mage.Sets/src/mage/cards/i/IzzetStaticaster.java +++ b/Mage.Sets/src/mage/cards/i/IzzetStaticaster.java @@ -13,15 +13,14 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.util.CardUtil; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author LevelX2 @@ -77,18 +76,22 @@ class IzzetStaticasterDamageEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (targetPermanent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent(); - if (CardUtil.haveEmptyName(targetPermanent)) { - filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(targetPermanent.getName())); - } - for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { - permanent.damage(1, source.getSourceId(), source, game, false, true); - } - return true; + if (targetPermanent == null) { + return false; } - return false; + Set set = game + .getBattlefield() + .getActivePermanents( + StaticFilters.FILTER_PERMANENT_CREATURE, + source.getControllerId(), source, game + ) + .stream() + .filter(permanent -> permanent.sharesName(targetPermanent, game)) + .collect(Collectors.toSet()); + set.add(targetPermanent); + for (Permanent creature : set) { + creature.damage(1, source, game); + } + return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DestroyAllNamedPermanentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DestroyAllNamedPermanentsEffect.java index cf1270881b8..b76871ef1a0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DestroyAllNamedPermanentsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DestroyAllNamedPermanentsEffect.java @@ -5,11 +5,11 @@ import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.util.CardUtil; /** * @author BetaSteward_at_googlemail.com @@ -36,12 +36,11 @@ public class DestroyAllNamedPermanentsEffect extends OneShotEffect { return false; } FilterPermanent filter = new FilterPermanent(); - if (CardUtil.haveEmptyName(targetPermanent)) { - filter.add(new PermanentIdPredicate(targetPermanent.getId())); // if no name (face down creature) only the creature itself is selected - } else { - filter.add(new NamePredicate(targetPermanent.getName())); - } - for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { + filter.add(Predicates.or( + new SharesNamePredicate(targetPermanent), + new PermanentIdPredicate(targetPermanent.getId()) + )); + for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { perm.destroy(source, game, false); } return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java index c47f59dbfa0..b18df245aa3 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RippleAbility.java @@ -11,7 +11,7 @@ import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.mageobject.SharesNamePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.stack.Spell; @@ -94,9 +94,8 @@ class RippleEffect extends OneShotEffect { player.revealCards(sourceObject.getIdName(), cards, game); // determine which card should be rippled - String cardNameToRipple = sourceObject.getName(); - FilterCard sameNameFilter = new FilterCard("card(s) with the name: \"" + cardNameToRipple + "\" to cast without paying their mana cost"); - sameNameFilter.add(new NamePredicate(cardNameToRipple)); + FilterCard sameNameFilter = new FilterCard("card(s) to cast without paying their mana cost"); + sameNameFilter.add(new SharesNamePredicate(sourceObject)); TargetCard target1 = new TargetCard(Zone.LIBRARY, sameNameFilter); target1.setRequired(false); diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/SharesNamePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/SharesNamePredicate.java new file mode 100644 index 00000000000..7272a5f5e48 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/SharesNamePredicate.java @@ -0,0 +1,22 @@ +package mage.filter.predicate.mageobject; + +import mage.MageObject; +import mage.filter.predicate.Predicate; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public class SharesNamePredicate implements Predicate { + + private final MageObject mageObject; + + public SharesNamePredicate(MageObject mageObject) { + this.mageObject = mageObject; + } + + @Override + public boolean apply(MageObject input, Game game) { + return input.sharesName(mageObject, game); + } +}