diff --git a/Mage.Client/src/main/java/mage/client/remote/S3Uploader.java b/Mage.Client/src/main/java/mage/client/remote/S3Uploader.java index 35a1b538ce..95be10c267 100644 --- a/Mage.Client/src/main/java/mage/client/remote/S3Uploader.java +++ b/Mage.Client/src/main/java/mage/client/remote/S3Uploader.java @@ -4,9 +4,10 @@ import com.amazonaws.AmazonClientException; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.Upload; -import java.io.File; import org.apache.log4j.Logger; +import java.io.File; + public class S3Uploader { private static final Logger logger = Logger.getLogger(S3Uploader.class); @@ -18,9 +19,9 @@ public class S3Uploader { String accessKeyId = System.getenv("AWS_ACCESS_ID"); String secretKeyId = System.getenv("AWS_SECRET_KEY"); - if (accessKeyId == null || "".equals(accessKeyId) - || secretKeyId == null || "".equals(secretKeyId) - || existingBucketName == null || "".equals(existingBucketName)) { + if (accessKeyId == null || accessKeyId.isEmpty() + || secretKeyId == null || secretKeyId.isEmpty() + || existingBucketName == null || existingBucketName.isEmpty()) { logger.info("Aborting json log sync."); return false; } diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapist.java b/Mage.Sets/src/mage/cards/c/CabalTherapist.java index 66ed076a80..56725f4cf6 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapist.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapist.java @@ -10,7 +10,10 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.keyword.MenaceAbility; -import mage.cards.*; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -79,10 +82,10 @@ class CabalTherapistDiscardEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (targetPlayer == null || controller == null || sourceObject == null) { + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (targetPlayer == null || controller == null || sourceObject == null || cardName == null) { return false; } - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); Cards hand = targetPlayer.getHand().copy(); targetPlayer.revealCards(source, hand, game); hand.removeIf(uuid -> { diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapy.java b/Mage.Sets/src/mage/cards/c/CabalTherapy.java index 2df5084432..569e9a5758 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapy.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapy.java @@ -6,10 +6,14 @@ import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.keyword.FlashbackAbility; -import mage.cards.*; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TimingRule; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; @@ -17,7 +21,6 @@ import mage.target.common.TargetControlledCreaturePermanent; import mage.util.CardUtil; import java.util.UUID; -import mage.filter.StaticFilters; /** * @author jonubuu @@ -64,10 +67,10 @@ class CabalTherapyEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (targetPlayer == null || controller == null || sourceObject == null) { + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (targetPlayer == null || controller == null || sourceObject == null || cardName == null) { return false; } - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); Cards hand = targetPlayer.getHand().copy(); targetPlayer.revealCards(source, hand, game); hand.removeIf(uuid -> { diff --git a/Mage.Sets/src/mage/cards/c/CheeringFanatic.java b/Mage.Sets/src/mage/cards/c/CheeringFanatic.java index e0288f1af8..ec8abfa655 100644 --- a/Mage.Sets/src/mage/cards/c/CheeringFanatic.java +++ b/Mage.Sets/src/mage/cards/c/CheeringFanatic.java @@ -1,7 +1,5 @@ - package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -10,18 +8,19 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.ChooseACardNameEffect.TypeOfName; import mage.abilities.effects.common.cost.SpellsCostReductionAllEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class CheeringFanatic extends CardImpl { @@ -67,6 +66,9 @@ class CheeringFanaticEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { new ChooseACardNameEffect(TypeOfName.ALL).apply(game, source); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (cardName == null) { + return false; + } FilterCard filter = new FilterCard(); filter.add(new NamePredicate(cardName)); ContinuousEffect effect = new SpellsCostReductionAllEffect(filter, 1); diff --git a/Mage.Sets/src/mage/cards/c/ChromeReplicator.java b/Mage.Sets/src/mage/cards/c/ChromeReplicator.java index 8075551225..fb331f6133 100644 --- a/Mage.Sets/src/mage/cards/c/ChromeReplicator.java +++ b/Mage.Sets/src/mage/cards/c/ChromeReplicator.java @@ -74,7 +74,7 @@ enum ChromeReplicatorCondition implements Condition { .filter(Objects::nonNull) .map(MageObject::getName) .filter(Objects::nonNull) - .filter(s -> !"".equals(s)) + .filter(s -> !s.isEmpty()) .anyMatch(s -> nameMap.compute(s, (x, i) -> i == null ? 1 : Integer.sum(i, 1)) >= 2); } } diff --git a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java index 483f058a50..55f9a88890 100644 --- a/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java +++ b/Mage.Sets/src/mage/cards/c/CouncilOfTheAbsolute.java @@ -93,7 +93,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifyingEffec if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { MageObject object = game.getObject(event.getSourceId()); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - return object != null && CardUtil.haveSameNames(object, cardName, game); + return object != null && cardName != null && CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java b/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java index 8e761b1c30..32d9a819ce 100644 --- a/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java +++ b/Mage.Sets/src/mage/cards/d/DeclarationOfNaught.java @@ -1,12 +1,11 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CounterTargetEffect; import mage.abilities.effects.common.ChooseACardNameEffect; +import mage.abilities.effects.common.CounterTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -17,8 +16,9 @@ import mage.game.Game; import mage.target.TargetSpell; import mage.target.targetadjustment.TargetAdjuster; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class DeclarationOfNaught extends CardImpl { @@ -55,6 +55,9 @@ enum DeclarationOfNaughtAdjuster implements TargetAdjuster { public void adjustTargets(Ability ability, Game game) { ability.getTargets().clear(); String chosenName = (String) game.getState().getValue(ability.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (chosenName == null) { + return; + } FilterSpell filterSpell = new FilterSpell("spell named " + chosenName); filterSpell.add(new NamePredicate(chosenName)); TargetSpell target = new TargetSpell(1, filterSpell); diff --git a/Mage.Sets/src/mage/cards/d/DementiaSliver.java b/Mage.Sets/src/mage/cards/d/DementiaSliver.java index 1610c825ae..f3a971608d 100644 --- a/Mage.Sets/src/mage/cards/d/DementiaSliver.java +++ b/Mage.Sets/src/mage/cards/d/DementiaSliver.java @@ -79,7 +79,7 @@ class DementiaSliverEffect extends OneShotEffect { Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - if (opponent != null && sourceObject != null && !cardName.isEmpty()) { + if (opponent != null && sourceObject != null && cardName != null && !cardName.isEmpty()) { if (!opponent.getHand().isEmpty()) { Cards revealed = new CardsImpl(); Card card = opponent.getHand().getRandom(game); diff --git a/Mage.Sets/src/mage/cards/d/Dispossess.java b/Mage.Sets/src/mage/cards/d/Dispossess.java index 58569dcca4..8553c03faf 100644 --- a/Mage.Sets/src/mage/cards/d/Dispossess.java +++ b/Mage.Sets/src/mage/cards/d/Dispossess.java @@ -1,7 +1,5 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; @@ -11,8 +9,9 @@ import mage.constants.CardType; import mage.game.Game; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author fireshoes */ public final class Dispossess extends CardImpl { @@ -49,6 +48,9 @@ class DispossessEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExi @Override public boolean apply(Game game, Ability source) { String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (cardName == null) { + return false; + } return super.applySearchAndExile(game, source, cardName, targetPointer.getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/f/FailureComply.java b/Mage.Sets/src/mage/cards/f/FailureComply.java index b463bad11e..c08eac0b82 100644 --- a/Mage.Sets/src/mage/cards/f/FailureComply.java +++ b/Mage.Sets/src/mage/cards/f/FailureComply.java @@ -1,7 +1,5 @@ - package mage.cards.f; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; @@ -19,6 +17,9 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.target.TargetSpell; +import mage.util.CardUtil; + +import java.util.UUID; /** * @author spjspj @@ -72,9 +73,9 @@ class ComplyCantCastEffect extends ContinuousRuleModifyingEffectImpl { @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); - if (mageObject != null) { - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ")."; + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (mageObject != null && cardName != null) { + return "You can't cast a card named " + cardName + " (" + mageObject.getIdName() + ")."; } return null; } @@ -89,9 +90,7 @@ class ComplyCantCastEffect extends ContinuousRuleModifyingEffectImpl { String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(cardName)) { - return true; - } + return object != null && CardUtil.haveSameNames(object, cardName, game); } return false; } diff --git a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java index 1a679be278..c186aa8628 100644 --- a/Mage.Sets/src/mage/cards/g/GideonsIntervention.java +++ b/Mage.Sets/src/mage/cards/g/GideonsIntervention.java @@ -73,9 +73,9 @@ class GideonsInterventionCantCastEffect extends ContinuousRuleModifyingEffectImp @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); - if (mageObject != null) { - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - return "You may not cast a card named " + cardName + " (" + mageObject.getIdName() + ")."; + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (mageObject != null && cardName != null) { + return "You can't cast a card named " + cardName + " (" + mageObject.getIdName() + ")."; } return null; } @@ -134,7 +134,6 @@ class GideonsInterventionPreventAllDamageEffect extends PreventionEffectImpl { 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))) { diff --git a/Mage.Sets/src/mage/cards/j/JestersScepter.java b/Mage.Sets/src/mage/cards/j/JestersScepter.java index c67505242e..88c08a6595 100644 --- a/Mage.Sets/src/mage/cards/j/JestersScepter.java +++ b/Mage.Sets/src/mage/cards/j/JestersScepter.java @@ -1,8 +1,5 @@ - package mage.cards.j; -import java.util.Set; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -14,16 +11,8 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.SplitCard; -import mage.constants.AsThoughEffectType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.cards.*; +import mage.constants.*; import mage.filter.FilterCard; import mage.game.ExileZone; import mage.game.Game; @@ -34,14 +23,16 @@ import mage.target.TargetSpell; import mage.target.common.TargetCardInExile; import mage.util.CardUtil; +import java.util.Set; +import java.util.UUID; + /** - * * @author jeffwadsworth */ public final class JestersScepter extends CardImpl { public JestersScepter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // When Jester's Scepter enters the battlefield, exile the top five cards of target player's library face down. Ability ability = new EntersBattlefieldTriggeredAbility(new JestersScepterEffect(), false); @@ -213,14 +204,11 @@ class JestersScepterCounterEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { - // In case of Split Card String nameOfExiledCardPayment = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment"); String nameOfExiledCardPayment2 = (String) game.getState().getValue(source.getSourceId() + "_nameOfExiledCardPayment2"); - if (nameOfExiledCardPayment != null) { - if (nameOfExiledCardPayment.equals(spell.getCard().getName()) - || (nameOfExiledCardPayment2 != null) && nameOfExiledCardPayment2.equals(spell.getCard().getName())) { - return game.getStack().counter(targetPointer.getFirst(game, source), source.getSourceId(), game); - } + if (CardUtil.haveSameNames(spell.getCard(), nameOfExiledCardPayment, game) + || CardUtil.haveSameNames(spell.getCard(), nameOfExiledCardPayment2, game)) { + return game.getStack().counter(targetPointer.getFirst(game, source), source.getSourceId(), game); } } return false; diff --git a/Mage.Sets/src/mage/cards/m/MedomaisProphecy.java b/Mage.Sets/src/mage/cards/m/MedomaisProphecy.java index 64dbb24e0d..85079d76fc 100644 --- a/Mage.Sets/src/mage/cards/m/MedomaisProphecy.java +++ b/Mage.Sets/src/mage/cards/m/MedomaisProphecy.java @@ -78,7 +78,7 @@ class MedomaisProphecyTriggerEffect extends OneShotEffect { String cardName = (String) game.getState().getValue( source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY ); - if (cardName == null || "".equals(cardName)) { + if (cardName == null || cardName.isEmpty()) { return false; } game.addDelayedTriggeredAbility(new MedomaisProphecyDelayedTriggeredAbility(cardName), source); diff --git a/Mage.Sets/src/mage/cards/m/Memoricide.java b/Mage.Sets/src/mage/cards/m/Memoricide.java index c38672412f..88948a85f9 100644 --- a/Mage.Sets/src/mage/cards/m/Memoricide.java +++ b/Mage.Sets/src/mage/cards/m/Memoricide.java @@ -1,6 +1,5 @@ package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.common.ChooseACardNameEffect; @@ -11,8 +10,9 @@ import mage.constants.CardType; import mage.game.Game; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public final class Memoricide extends CardImpl { @@ -51,6 +51,9 @@ class MemoricideEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExi @Override public boolean apply(Game game, Ability source) { String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (cardName == null) { + return false; + } return super.applySearchAndExile(game, source, cardName, targetPointer.getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/p/PatternMatcher.java b/Mage.Sets/src/mage/cards/p/PatternMatcher.java index c53382c25e..97099f2cef 100644 --- a/Mage.Sets/src/mage/cards/p/PatternMatcher.java +++ b/Mage.Sets/src/mage/cards/p/PatternMatcher.java @@ -20,6 +20,7 @@ import mage.players.Player; import mage.target.common.TargetCardInLibrary; import java.util.List; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @@ -79,7 +80,8 @@ class RegularExpression extends OneShotEffect { source.getControllerId(), source.getSourceId(), game ).stream() .map(Permanent::getName) - .filter(s -> !"".equals(s)) + .filter(Objects::nonNull) + .filter(s -> !s.isEmpty()) .map(NamePredicate::new) .collect(Collectors.toList()); FilterCard filter diff --git a/Mage.Sets/src/mage/cards/s/Shapeshifter.java b/Mage.Sets/src/mage/cards/s/Shapeshifter.java index 92ea75e059..65fd94cbfb 100644 --- a/Mage.Sets/src/mage/cards/s/Shapeshifter.java +++ b/Mage.Sets/src/mage/cards/s/Shapeshifter.java @@ -1,9 +1,5 @@ - package mage.cards.s; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; @@ -22,8 +18,11 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author MarcoMarin / HCrescent */ public final class Shapeshifter extends CardImpl { @@ -116,8 +115,8 @@ class ShapeshifterContinuousEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - String lastChosen = (String) game.getState().getValue(source.getSourceId().toString() + "_Shapeshifter"); + String lastChosen = (String) game.getState().getValue(source.getSourceId().toString() + "_Shapeshifter"); + if (permanent != null && lastChosen != null) { int lastChosenNumber = Integer.parseInt(lastChosen); permanent.getPower().modifyBaseValue(lastChosenNumber); permanent.getToughness().modifyBaseValue(7 - lastChosenNumber); diff --git a/Mage.Sets/src/mage/cards/s/SlaughterGames.java b/Mage.Sets/src/mage/cards/s/SlaughterGames.java index e1cf56315e..e398dcb968 100644 --- a/Mage.Sets/src/mage/cards/s/SlaughterGames.java +++ b/Mage.Sets/src/mage/cards/s/SlaughterGames.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; @@ -15,14 +13,15 @@ import mage.constants.Zone; import mage.game.Game; import mage.target.common.TargetOpponent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class SlaughterGames extends CardImpl { public SlaughterGames(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{R}"); // Slaughter Games can't be countered. Effect effect = new CantBeCounteredSourceEffect(); @@ -60,6 +59,9 @@ class SlaughterGamesEffect extends SearchTargetGraveyardHandLibraryForCardNameAn @Override public boolean apply(Game game, Ability source) { String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (cardName == null) { + return false; + } return super.applySearchAndExile(game, source, cardName, targetPointer.getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java b/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java index b95f6f96b0..ad523d865a 100644 --- a/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java +++ b/Mage.Sets/src/mage/cards/s/StaffOfTheLetterMagus.java @@ -130,7 +130,7 @@ class StaffOfTheLetterMagusEffect extends OneShotEffect { for (int i = 0; i < spellName.length(); i++) { char letter = spellName.charAt(i); String chosenLetter = (String) game.getState().getValue(mageObject.getId() + "_letter"); - if (Character.isLetter(letter) && Character.toUpperCase(letter) == chosenLetter.charAt(0)) { + if (chosenLetter != null && Character.isLetter(letter) && Character.toUpperCase(letter) == chosenLetter.charAt(0)) { lifegainValue++; } } diff --git a/Mage.Sets/src/mage/cards/s/StainTheMind.java b/Mage.Sets/src/mage/cards/s/StainTheMind.java index 509edcca9b..953b0ad71b 100644 --- a/Mage.Sets/src/mage/cards/s/StainTheMind.java +++ b/Mage.Sets/src/mage/cards/s/StainTheMind.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; @@ -12,14 +10,15 @@ import mage.constants.CardType; import mage.game.Game; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class StainTheMind extends CardImpl { public StainTheMind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // Convoke this.addAbility(new ConvokeAbility()); @@ -52,6 +51,9 @@ class StainTheMindEffect extends SearchTargetGraveyardHandLibraryForCardNameAndE @Override public boolean apply(Game game, Ability source) { String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + if (cardName == null) { + return false; + } return super.applySearchAndExile(game, source, cardName, targetPointer.getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/cards/t/TwinningGlass.java b/Mage.Sets/src/mage/cards/t/TwinningGlass.java index a89d9321ba..76d0468c3b 100644 --- a/Mage.Sets/src/mage/cards/t/TwinningGlass.java +++ b/Mage.Sets/src/mage/cards/t/TwinningGlass.java @@ -1,6 +1,6 @@ package mage.cards.t; -import java.util.ArrayList; +import mage.ApprovingObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -12,19 +12,21 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.players.Player; +import mage.target.TargetCard; import mage.watchers.common.SpellsCastWatcher; + +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; -import mage.ApprovingObject; -import mage.filter.common.FilterNonlandCard; -import mage.filter.predicate.mageobject.NamePredicate; -import mage.target.TargetCard; /** * @author jeffwadsworth @@ -95,7 +97,8 @@ class TwinningGlassEffect extends OneShotEffect { } List predicates = spells.stream() .map(Spell::getName) - .filter(s -> !"".equals(s)) + .filter(Objects::nonNull) + .filter(s -> !s.isEmpty()) .map(NamePredicate::new) .collect(Collectors.toList()); FilterNonlandCard filterCard = new FilterNonlandCard("nonland card that was cast this turn"); 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 fbc763c73a..294f2d18af 100644 --- a/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/mageobject/NamePredicate.java @@ -27,6 +27,9 @@ public class NamePredicate implements Predicate { @Override public boolean apply(MageObject input, Game game) { + if (name == null) { + return false; + } // If a player names a card, the player may name either half of a split card, but not both. // A split card has the chosen name if one of its two names matches the chosen name. if (input instanceof SplitCard) {