Additional card fixed for named abilities support, also added face down spells support (see #6569);

This commit is contained in:
Oleg Agafonov 2020-06-05 01:13:17 +04:00
parent 4b77cb0fa8
commit ecac9295ec
15 changed files with 110 additions and 118 deletions

View file

@ -12,6 +12,7 @@ import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
@ -66,18 +67,19 @@ class ConjurersBanEffect extends ContinuousRuleModifyingEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.CAST_SPELL || event.getType() == GameEvent.EventType.PLAY_LAND) { if (event.getType() == GameEvent.EventType.CAST_SPELL || event.getType() == GameEvent.EventType.PLAY_LAND) {
MageObject object = game.getObject(event.getSourceId()); 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; return false;
} }
@Override @Override
public String getInfoMessage(Ability source, GameEvent event, Game game) { 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(); 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 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() + ").";
} }
} }

View file

@ -78,7 +78,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }
@ -92,8 +92,8 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
String needName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
return object != null && CardUtil.haveSameNames(object, needName, game); return object != null && CardUtil.haveSameNames(object, cardName, game);
} }
return false; return false;
} }
@ -122,8 +122,8 @@ class CouncilOfTheAbsoluteCostReductionEffect extends CostModificationEffectImpl
&& abilityToModify.isControlledBy(source.getControllerId())) { && abilityToModify.isControlledBy(source.getControllerId())) {
Card card = game.getCard(abilityToModify.getSourceId()); Card card = game.getCard(abilityToModify.getSourceId());
if (card != null) { if (card != null) {
String needName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
return CardUtil.haveSameNames(card, needName, game); return CardUtil.haveSameNames(card, cardName, game);
} }
} }
return false; return false;

View file

@ -58,12 +58,11 @@ class DeniedEffect extends OneShotEffect {
return true; return true;
} }
Player player = game.getPlayer(targetSpell.getControllerId()); Player player = game.getPlayer(targetSpell.getControllerId());
Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (player != null && object instanceof String) { if (player != null && cardName != null) {
player.revealCards("Denied!", player.getHand(), game, true); player.revealCards("Denied!", player.getHand(), game, true);
String namedCard = (String) object;
for (Card card : player.getHand().getCards(game)) { 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); game.getStack().counter(targetSpell.getId(), source.getSourceId(), game);
break; break;
} }

View file

@ -20,6 +20,7 @@ import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.events.PreventDamageEvent; import mage.game.events.PreventDamageEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
@ -132,11 +133,12 @@ class GideonsInterventionPreventAllDamageEffect extends PreventionEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
Permanent targetPerm = game.getPermanent(event.getTargetId()); 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 if (object != null && (event.getType() == GameEvent.EventType.DAMAGE_PLAYER
|| targetPerm != null && (event.getType() == GameEvent.EventType.DAMAGE_CREATURE || targetPerm != null && (event.getType() == GameEvent.EventType.DAMAGE_CREATURE
|| event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER))) { || 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()) && (event.getTargetId().equals(source.getControllerId())
|| targetPerm != null && targetPerm.isControlledBy(source.getControllerId()))) { || targetPerm != null && targetPerm.isControlledBy(source.getControllerId()))) {
return super.applies(event, source, game); return super.applies(event, source, game);

View file

@ -1,7 +1,5 @@
package mage.cards.i; package mage.cards.i;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
@ -14,23 +12,25 @@ import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.AbilityPredicate; import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author lunaskyrise * @author lunaskyrise
*/ */
public final class IsperiaTheInscrutable extends CardImpl { public final class IsperiaTheInscrutable extends CardImpl {
public IsperiaTheInscrutable(UUID ownerId, CardSetInfo setInfo) { 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.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SPHINX); this.subtype.add(SubType.SPHINX);
this.power = new MageInt(3); this.power = new MageInt(3);
@ -78,12 +78,11 @@ class IsperiaTheInscrutableEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (player != null && object instanceof String) { if (player != null && cardName != null) {
player.revealCards(player.getLogName() + " hand", player.getHand(), game, true); player.revealCards(player.getLogName() + " hand", player.getHand(), game, true);
String namedCard = (String) object;
for (Card card : player.getHand().getCards(game)) { 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); return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true).apply(game, source);
} }
} }

View file

@ -1,6 +1,5 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -8,21 +7,17 @@ import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.stack.Spell; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class MeddlingMage extends CardImpl { public final class MeddlingMage extends CardImpl {
@ -77,7 +72,7 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifyingEffectImpl {
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }
@ -89,18 +84,11 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { 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()); MageObject object = game.getObject(event.getSourceId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
return object != null return object != null
&& !object.isCopy() && !object.isCopy()
&& object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY)); && CardUtil.haveSameNames(object, cardName, game);
} }
} }

View file

@ -1,7 +1,5 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.ChooseACardNameEffect;
@ -13,15 +11,17 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author L_J * @author L_J
*/ */
public final class Mise extends CardImpl { public final class Mise extends CardImpl {
public Mise(UUID ownerId, CardSetInfo setInfo) { 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. // 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 ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME));
@ -52,14 +52,13 @@ class MiseEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Object object = game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
if (player != null && object instanceof String) { if (player != null && cardName != null) {
Card card = player.getLibrary().getFromTop(game); Card card = player.getLibrary().getFromTop(game);
String namedCard = (String) object;
CardsImpl cards = new CardsImpl(card); CardsImpl cards = new CardsImpl(card);
if (card != null) { if (card != null) {
player.revealCards("Mise", cards, game, true); player.revealCards("Mise", cards, game, true);
if (card.getName().equals(namedCard)) { if (CardUtil.haveSameNames(card, cardName, game)) {
player.drawCards(3, source.getSourceId(), game); player.drawCards(3, source.getSourceId(), game);
} }
} }

View file

@ -1,6 +1,5 @@
package mage.cards.n; package mage.cards.n;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
@ -16,9 +15,11 @@ import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class Nevermore extends CardImpl { public final class Nevermore extends CardImpl {
@ -70,9 +71,8 @@ class NevermoreEffect2 extends ContinuousRuleModifyingEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.CAST_SPELL) { if (event.getType() == EventType.CAST_SPELL) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
if (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 true; return CardUtil.haveSameNames(object, cardName, game);
}
} }
return false; return false;
} }

View file

@ -1,22 +1,17 @@
package mage.cards.n; package mage.cards.n;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.constants.SuperType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
@ -25,8 +20,9 @@ import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class NullChamber extends CardImpl { public final class NullChamber extends CardImpl {
@ -141,7 +137,7 @@ class NullChamberReplacementEffect extends ContinuousRuleModifyingEffectImpl {
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -11,23 +9,21 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class PhyrexianRevoker extends CardImpl { public final class PhyrexianRevoker extends CardImpl {
public PhyrexianRevoker(UUID ownerId, CardSetInfo setInfo) { 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.subtype.add(SubType.HORROR);
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
@ -75,7 +71,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl {
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }
@ -84,9 +80,8 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ACTIVATE_ABILITY) { if (event.getType() == EventType.ACTIVATE_ABILITY) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
if (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 true; return CardUtil.haveSameNames(object, cardName, game);
}
} }
return false; return false;
} }

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
@ -11,12 +9,18 @@ import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; 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.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.util.CardUtil;
import java.util.Optional;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth, nox * @author jeffwadsworth, nox
*/ */
public final class PithingNeedle extends CardImpl { public final class PithingNeedle extends CardImpl {
@ -70,14 +74,13 @@ class PithingNeedleEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId()); Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent() if (ability.isPresent()
&& object != null) { && 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 && !(ability.get() instanceof ActivatedManaAbilityImpl) // not an activated mana ability
&& object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { && CardUtil.haveSameNames(object, cardName, game);
return true;
}
} }
return false; return false;
} }

View file

@ -1,8 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
@ -11,18 +8,17 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AbilityType; 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.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.util.CardUtil;
import java.util.Optional;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class SorcerousSpyglass extends CardImpl { public final class SorcerousSpyglass extends CardImpl {
@ -110,13 +106,12 @@ class SorcerousSpyglassActivationEffect extends ContinuousRuleModifyingEffectImp
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId()); Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent() && object != null) { 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 && ability.get().getAbilityType() != AbilityType.MANA
&& object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { && CardUtil.haveSameNames(object, cardName, game);
return true;
}
} }
return false; return false;
} }

View file

@ -1,6 +1,5 @@
package mage.cards.v; package mage.cards.v;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -11,17 +10,15 @@ import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class VoidstoneGargoyle extends CardImpl { public final class VoidstoneGargoyle extends CardImpl {
@ -78,7 +75,7 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifyingEffectI
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }
@ -87,10 +84,8 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifyingEffectI
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.CAST_SPELL) { if (event.getType() == GameEvent.EventType.CAST_SPELL) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
if (object != null String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY);
&& object.getName().equals(game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY))) { return CardUtil.haveSameNames(object, cardName, game);
return true;
}
} }
return false; return false;
} }
@ -122,7 +117,7 @@ class VoidstoneGargoyleRuleModifyingEffect2 extends ContinuousRuleModifyingEffec
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) { 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; return null;
} }
@ -131,9 +126,8 @@ class VoidstoneGargoyleRuleModifyingEffect2 extends ContinuousRuleModifyingEffec
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.ACTIVATE_ABILITY) { if (event.getType() == EventType.ACTIVATE_ABILITY) {
MageObject object = game.getObject(event.getSourceId()); MageObject object = game.getObject(event.getSourceId());
if (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 true; return CardUtil.haveSameNames(object, cardName, game);
}
} }
return false; return false;
} }

View file

@ -5,6 +5,7 @@ import mage.cards.repository.CardRepository;
import mage.constants.EmptyNames; import mage.constants.EmptyNames;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.stack.Spell;
import mage.util.CardUtil; import mage.util.CardUtil;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; 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, "Other // Dangerous", currentGame));
Assert.assertFalse(CardUtil.haveSameNames(splitCard1, "Armed // Other", currentGame)); Assert.assertFalse(CardUtil.haveSameNames(splitCard1, "Armed // Other", currentGame));
Assert.assertFalse(CardUtil.haveSameNames(splitCard1, splitCard2)); 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 @Test

View file

@ -38,10 +38,13 @@ public class NamePredicate implements Predicate<MageObject> {
return CardUtil.haveSameNames(name, card.getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) || return CardUtil.haveSameNames(name, card.getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
CardUtil.haveSameNames(name, card.getRightHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) || CardUtil.haveSameNames(name, card.getRightHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
CardUtil.haveSameNames(name, card.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 { } else {
if (name.contains(" // ")) { if (name.contains(" // ")) {
String leftName = name.substring(0, name.indexOf(" // ")); 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) || return CardUtil.haveSameNames(leftName, input.getName(), this.ignoreMtgRuleForEmptyNames) ||
CardUtil.haveSameNames(rightName, input.getName(), this.ignoreMtgRuleForEmptyNames); CardUtil.haveSameNames(rightName, input.getName(), this.ignoreMtgRuleForEmptyNames);
} else { } else {
@ -52,6 +55,6 @@ public class NamePredicate implements Predicate<MageObject> {
@Override @Override
public String toString() { public String toString() {
return "Name(" + name + ')'; return "Name (" + name + ')';
} }
} }