From ecac9295ece2a91fdc061e13cdc9a00c8940f1bf Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Fri, 5 Jun 2020 01:13:17 +0400 Subject: [PATCH] Additional card fixed for named abilities support, also added face down spells support (see #6569); --- Mage.Sets/src/mage/cards/c/ConjurersBan.java | 10 ++++--- .../mage/cards/c/CouncilOfTheAbsolute.java | 10 +++---- Mage.Sets/src/mage/cards/d/Denied.java | 7 +++-- .../src/mage/cards/g/GideonsIntervention.java | 4 ++- .../mage/cards/i/IsperiaTheInscrutable.java | 19 +++++++------- Mage.Sets/src/mage/cards/m/MeddlingMage.java | 26 +++++-------------- Mage.Sets/src/mage/cards/m/Mise.java | 17 ++++++------ Mage.Sets/src/mage/cards/n/Nevermore.java | 10 +++---- Mage.Sets/src/mage/cards/n/NullChamber.java | 12 +++------ .../src/mage/cards/p/PhyrexianRevoker.java | 21 ++++++--------- Mage.Sets/src/mage/cards/p/PithingNeedle.java | 21 ++++++++------- .../src/mage/cards/s/SorcerousSpyglass.java | 21 ++++++--------- .../src/mage/cards/v/VoidstoneGargoyle.java | 26 +++++++------------ .../org/mage/test/testapi/TestAliases.java | 17 ++++++++++++ .../predicate/mageobject/NamePredicate.java | 7 +++-- 15 files changed, 110 insertions(+), 118 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/ConjurersBan.java b/Mage.Sets/src/mage/cards/c/ConjurersBan.java index db7b0bd5a14..ee03ad72530 100644 --- a/Mage.Sets/src/mage/cards/c/ConjurersBan.java +++ b/Mage.Sets/src/mage/cards/c/ConjurersBan.java @@ -12,6 +12,7 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; import mage.game.events.GameEvent; +import mage.util.CardUtil; import java.util.UUID; @@ -66,18 +67,19 @@ class ConjurersBanEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL || event.getType() == GameEvent.EventType.PLAY_LAND) { MageObject object = game.getObject(event.getSourceId()); - return object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(object, cardName, game); } return false; } @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { - String namedCard = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String playerName = game.getPlayer(source.getControllerId()).getName(); - if (namedCard == null || playerName == null || source.getSourceObject(game) == null) { + if (cardName == null || playerName == null || source.getSourceObject(game) == null) { return super.getInfoMessage(source, event, game); } - return "Until " + playerName + "'s next turn, spells named " + namedCard + " can't be cast and lands named " + namedCard + " can't be played (" + source.getSourceObject(game).getIdName() + ")."; + return "Until " + playerName + "'s next turn, spells named " + cardName + " can't be cast and lands named " + cardName + " can't be played (" + source.getSourceObject(game).getIdName() + ")."; } } diff --git a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java index 90fd017f89b..483f058a501 100644 --- a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java +++ b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java @@ -78,7 +78,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't cast a spell with that name (" + mageObject.getLogName() + " in play)."; + return "You can't cast a spell with that name (" + mageObject.getName() + " in play)."; } return null; } @@ -92,8 +92,8 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { MageObject object = game.getObject(event.getSourceId()); - String needName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - return object != null && CardUtil.haveSameNames(object, needName, game); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return object != null && CardUtil.haveSameNames(object, cardName, game); } return false; } @@ -122,8 +122,8 @@ class CouncilOfTheAbsoluteCostReductionEffect extends CostModificationEffectImpl && abilityToModify.isControlledBy(source.getControllerId())) { Card card = game.getCard(abilityToModify.getSourceId()); if (card != null) { - String needName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - return CardUtil.haveSameNames(card, needName, game); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(card, cardName, game); } } return false; diff --git a/Mage.Sets/src/mage/cards/d/Denied.java b/Mage.Sets/src/mage/cards/d/Denied.java index 596b96114f4..b8d60aec7af 100644 --- a/Mage.Sets/src/mage/cards/d/Denied.java +++ b/Mage.Sets/src/mage/cards/d/Denied.java @@ -58,12 +58,11 @@ class DeniedEffect extends OneShotEffect { return true; } Player player = game.getPlayer(targetSpell.getControllerId()); - Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - if (player != null && object instanceof String) { + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (player != null && cardName != null) { player.revealCards("Denied!", player.getHand(), game, true); - String namedCard = (String) object; for (Card card : player.getHand().getCards(game)) { - if (card != null && CardUtil.haveSameNames(card, namedCard, game)) { + if (card != null && CardUtil.haveSameNames(card, cardName, game)) { game.getStack().counter(targetSpell.getId(), source.getSourceId(), game); break; } diff --git a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java index 9ab17cfb9b8..1a679be278d 100644 --- a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java +++ b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java @@ -20,6 +20,7 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.PreventDamageEvent; import mage.game.permanent.Permanent; +import mage.util.CardUtil; import java.util.UUID; @@ -132,11 +133,12 @@ class GideonsInterventionPreventAllDamageEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); Permanent targetPerm = game.getPermanent(event.getTargetId()); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); if (object != null && (event.getType() == GameEvent.EventType.DAMAGE_PLAYER || targetPerm != null && (event.getType() == GameEvent.EventType.DAMAGE_CREATURE || event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER))) { - if (object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)) + if (CardUtil.haveSameNames(object, cardName, game) && (event.getTargetId().equals(source.getControllerId()) || targetPerm != null && targetPerm.isControlledBy(source.getControllerId()))) { return super.applies(event, source, game); diff --git a/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java b/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java index 7a6a663c2d3..ade3ddfe383 100644 --- a/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java +++ b/Mage.Sets/src/mage/cards/i/IsperiaTheInscrutable.java @@ -1,7 +1,5 @@ - package mage.cards.i; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; @@ -14,23 +12,25 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author lunaskyrise */ public final class IsperiaTheInscrutable extends CardImpl { public IsperiaTheInscrutable(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}{U}{U}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.SPHINX); this.power = new MageInt(3); @@ -38,7 +38,7 @@ public final class IsperiaTheInscrutable extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // Whenever Isperia the Inscrutable deals combat damage to a player, name a card. That player reveals their hand. If they reveal the named card, search your library for a creature card with flying, reveal it, put it into your hand, then shuffle your library. Effect effect1 = new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.ALL); Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect1, false, true); @@ -78,12 +78,11 @@ class IsperiaTheInscrutableEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - if (player != null && object instanceof String) { + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (player != null && cardName != null) { player.revealCards(player.getLogName() + " hand", player.getHand(), game, true); - String namedCard = (String) object; for (Card card : player.getHand().getCards(game)) { - if (card != null && card.getName().equals(namedCard)) { + if (CardUtil.haveSameNames(card, cardName, game)) { return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true).apply(game, source); } } diff --git a/Mage.Sets/src/mage/cards/m/MeddlingMage.java b/Mage.Sets/src/mage/cards/m/MeddlingMage.java index ebf5f71d3ac..bb855380b14 100644 --- a/Mage.Sets/src/mage/cards/m/MeddlingMage.java +++ b/Mage.Sets/src/mage/cards/m/MeddlingMage.java @@ -1,6 +1,5 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -8,21 +7,17 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.ChooseACardNameEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.stack.Spell; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author Plopman */ public final class MeddlingMage extends CardImpl { @@ -77,7 +72,7 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifyingEffectImpl { public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't cast a spell with that name (" + mageObject.getLogName() + " in play)."; + return "You can't cast a spell with that name (" + mageObject.getName() + " in play)."; } return null; } @@ -89,18 +84,11 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - // Check for Morph spell (no name) - Card card = game.getCard(event.getSourceId()); - if (card != null) { - Spell spell = game.getState().getStack().getSpell(event.getSourceId()); - if (spell != null && spell.isFaceDown(game)) { - return false; // Face Down cast spell (Morph creature) has no name - } - } MageObject object = game.getObject(event.getSourceId()); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); return object != null && !object.isCopy() - && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)); + && CardUtil.haveSameNames(object, cardName, game); } } diff --git a/Mage.Sets/src/mage/cards/m/Mise.java b/Mage.Sets/src/mage/cards/m/Mise.java index 221affc8fd5..b09b753876f 100644 --- a/Mage.Sets/src/mage/cards/m/Mise.java +++ b/Mage.Sets/src/mage/cards/m/Mise.java @@ -1,7 +1,5 @@ - package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseACardNameEffect; @@ -13,16 +11,18 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author L_J */ public final class Mise extends CardImpl { public Mise(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}"); + // Choose a nonland card name, then reveal the top card of your library. If that card has the chosen name, you draw three cards. this.getSpellAbility().addEffect(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME)); this.getSpellAbility().addEffect(new MiseEffect()); @@ -52,14 +52,13 @@ class MiseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - if (player != null && object instanceof String) { + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (player != null && cardName != null) { Card card = player.getLibrary().getFromTop(game); - String namedCard = (String) object; CardsImpl cards = new CardsImpl(card); if (card != null) { player.revealCards("Mise", cards, game, true); - if (card.getName().equals(namedCard)) { + if (CardUtil.haveSameNames(card, cardName, game)) { player.drawCards(3, source.getSourceId(), game); } } diff --git a/Mage.Sets/src/mage/cards/n/Nevermore.java b/Mage.Sets/src/mage/cards/n/Nevermore.java index 755bf786cd2..36557baebe2 100644 --- a/Mage.Sets/src/mage/cards/n/Nevermore.java +++ b/Mage.Sets/src/mage/cards/n/Nevermore.java @@ -1,6 +1,5 @@ package mage.cards.n; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -16,9 +15,11 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author BetaSteward_at_googlemail.com */ public final class Nevermore extends CardImpl { @@ -70,9 +71,8 @@ class NevermoreEffect2 extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/n/NullChamber.java b/Mage.Sets/src/mage/cards/n/NullChamber.java index c3562465a34..99b0bf51ec3 100644 --- a/Mage.Sets/src/mage/cards/n/NullChamber.java +++ b/Mage.Sets/src/mage/cards/n/NullChamber.java @@ -1,22 +1,17 @@ package mage.cards.n; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.repository.CardRepository; import mage.choices.Choice; import mage.choices.ChoiceImpl; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -25,8 +20,9 @@ import mage.players.Player; import mage.target.common.TargetOpponent; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class NullChamber extends CardImpl { @@ -141,7 +137,7 @@ class NullChamberReplacementEffect extends ContinuousRuleModifyingEffectImpl { public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't cast a spell with that name (" + mageObject.getLogName() + " in play)."; + return "You can't cast a spell with that name (" + mageObject.getName() + " in play)."; } return null; } diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java b/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java index a0880af364a..b68174a304d 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianRevoker.java @@ -1,7 +1,5 @@ - package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -11,23 +9,21 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author BetaSteward_at_googlemail.com */ public final class PhyrexianRevoker extends CardImpl { public PhyrexianRevoker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); this.subtype.add(SubType.HORROR); this.power = new MageInt(2); this.toughness = new MageInt(1); @@ -75,7 +71,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl { public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't activate abilities of sources with that name (" + mageObject.getLogName() + " in play)."; + return "You can't activate abilities of sources with that name (" + mageObject.getName() + " in play)."; } return null; } @@ -84,9 +80,8 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ACTIVATE_ABILITY) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/p/PithingNeedle.java b/Mage.Sets/src/mage/cards/p/PithingNeedle.java index d8049e8ab00..2ec117dff4a 100644 --- a/Mage.Sets/src/mage/cards/p/PithingNeedle.java +++ b/Mage.Sets/src/mage/cards/p/PithingNeedle.java @@ -1,7 +1,5 @@ package mage.cards.p; -import java.util.Optional; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -11,12 +9,18 @@ import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; /** - * * @author jeffwadsworth, nox */ public final class PithingNeedle extends CardImpl { @@ -70,14 +74,13 @@ class PithingNeedleEffect extends ContinuousRuleModifyingEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); - if (ability.isPresent() + if (ability.isPresent() && object != null) { - if (game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range + return game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range && !(ability.get() instanceof ActivatedManaAbilityImpl) // not an activated mana ability - && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + && CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java index 1e1735f9a22..6db68ce6e59 100644 --- a/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java +++ b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java @@ -1,8 +1,5 @@ - package mage.cards.s; -import java.util.Optional; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -11,18 +8,17 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; /** - * * @author TheElk801 */ public final class SorcerousSpyglass extends CardImpl { @@ -110,13 +106,12 @@ class SorcerousSpyglassActivationEffect extends ContinuousRuleModifyingEffectImp @Override public boolean applies(GameEvent event, Ability source, Game game) { MageObject object = game.getObject(event.getSourceId()); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); if (ability.isPresent() && object != null) { - if (game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range + return game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range && ability.get().getAbilityType() != AbilityType.MANA - && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + && CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/v/VoidstoneGargoyle.java b/Mage.Sets/src/mage/cards/v/VoidstoneGargoyle.java index c2cdda72625..16294ad597d 100644 --- a/Mage.Sets/src/mage/cards/v/VoidstoneGargoyle.java +++ b/Mage.Sets/src/mage/cards/v/VoidstoneGargoyle.java @@ -1,6 +1,5 @@ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -11,17 +10,15 @@ import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.util.CardUtil; + +import java.util.UUID; /** - * * @author Plopman */ public final class VoidstoneGargoyle extends CardImpl { @@ -78,7 +75,7 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifyingEffectI public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't cast a spell with that name (" + mageObject.getIdName() + ")."; + return "You can't cast a spell with that name (" + mageObject.getName() + ")."; } return null; } @@ -87,10 +84,8 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifyingEffectI public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); - if (object != null - && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(object, cardName, game); } return false; } @@ -122,7 +117,7 @@ class VoidstoneGargoyleRuleModifyingEffect2 extends ContinuousRuleModifyingEffec public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { - return "You can't activate abilities of sources with that name (" + mageObject.getLogName() + " in play)."; + return "You can't activate abilities of sources with that name (" + mageObject.getName() + " in play)."; } return null; } @@ -131,9 +126,8 @@ class VoidstoneGargoyleRuleModifyingEffect2 extends ContinuousRuleModifyingEffec public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ACTIVATE_ABILITY) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { - return true; - } + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + return CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java b/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java index 1702f2f90ff..f5a72e3721a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java +++ b/Mage.Tests/src/test/java/org/mage/test/testapi/TestAliases.java @@ -5,6 +5,7 @@ import mage.cards.repository.CardRepository; import mage.constants.EmptyNames; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.game.stack.Spell; import mage.util.CardUtil; import org.junit.Assert; import org.junit.Test; @@ -58,6 +59,22 @@ public class TestAliases extends CardTestPlayerBase { Assert.assertFalse(CardUtil.haveSameNames(splitCard1, "Other // Dangerous", currentGame)); Assert.assertFalse(CardUtil.haveSameNames(splitCard1, "Armed // Other", currentGame)); Assert.assertFalse(CardUtil.haveSameNames(splitCard1, splitCard2)); + + // name with face down spells: face down spells don't have names, see https://github.com/magefree/mage/issues/6569 + Card bearCard = CardRepository.instance.findCard("Balduvian Bears").getCard(); + Spell normalSpell = new Spell(bearCard, bearCard.getSpellAbility(), playerA.getId(), Zone.HAND); + Spell faceDownSpell = new Spell(bearCard, bearCard.getSpellAbility(), playerA.getId(), Zone.HAND); + faceDownSpell.setFaceDown(true, currentGame); + // normal spell + Assert.assertFalse(CardUtil.haveSameNames(normalSpell, "", currentGame)); + Assert.assertFalse(CardUtil.haveSameNames(normalSpell, "Other", currentGame)); + Assert.assertFalse(CardUtil.haveSameNames(normalSpell, EmptyNames.FACE_DOWN_CREATURE.toString(), currentGame)); + Assert.assertTrue(CardUtil.haveSameNames(normalSpell, "Balduvian Bears", currentGame)); + // face down spell + Assert.assertFalse(CardUtil.haveSameNames(faceDownSpell, "", currentGame)); + Assert.assertFalse(CardUtil.haveSameNames(faceDownSpell, "Other", currentGame)); + Assert.assertFalse(CardUtil.haveSameNames(faceDownSpell, EmptyNames.FACE_DOWN_CREATURE.toString(), currentGame)); + Assert.assertFalse(CardUtil.haveSameNames(faceDownSpell, "Balduvian Bears", currentGame)); } @Test diff --git a/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java b/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java index bc266d2718f..fbc763c73a4 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java @@ -38,10 +38,13 @@ public class NamePredicate implements Predicate { return CardUtil.haveSameNames(name, card.getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) || CardUtil.haveSameNames(name, card.getRightHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) || CardUtil.haveSameNames(name, card.getName(), this.ignoreMtgRuleForEmptyNames); + } else if (input instanceof Spell && ((Spell) input).isFaceDown(game)) { + // face down spells don't have names, so it's not equal, see https://github.com/magefree/mage/issues/6569 + return false; } else { if (name.contains(" // ")) { String leftName = name.substring(0, name.indexOf(" // ")); - String rightName = name.substring(name.indexOf(" // ") + 4, name.length()); + String rightName = name.substring(name.indexOf(" // ") + 4); return CardUtil.haveSameNames(leftName, input.getName(), this.ignoreMtgRuleForEmptyNames) || CardUtil.haveSameNames(rightName, input.getName(), this.ignoreMtgRuleForEmptyNames); } else { @@ -52,6 +55,6 @@ public class NamePredicate implements Predicate { @Override public String toString() { - return "Name(" + name + ')'; + return "Name (" + name + ')'; } }