some more refactoring

This commit is contained in:
theelk801 2024-09-23 19:38:58 -04:00
parent 7d33b2230d
commit c07b9680bd
18 changed files with 302 additions and 391 deletions

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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<Card> 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()) {

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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();
}
}

View file

@ -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

View file

@ -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<Card> 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;
}
}

View file

@ -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<Card> 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;
}
}

View file

@ -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<Card> 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);
}
}

View file

@ -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));
}
}

View file

@ -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<Permanent> 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;
}

View file

@ -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,
"<br/><br/><i>Hellbent</i> &mdash; 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.<br><i>Hellbent</i> &mdash; 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);
}
}

View file

@ -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<Permanent> 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;
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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<MageObject> {
private final MageObject mageObject;
public SharesNamePredicate(MageObject mageObject) {
this.mageObject = mageObject;
}
@Override
public boolean apply(MageObject input, Game game) {
return input.sharesName(mageObject, game);
}
}