diff --git a/Mage.Sets/src/mage/cards/c/CallousSellSword.java b/Mage.Sets/src/mage/cards/c/CallousSellSword.java index 714b57ebf02..2a6da8ea1a8 100644 --- a/Mage.Sets/src/mage/cards/c/CallousSellSword.java +++ b/Mage.Sets/src/mage/cards/c/CallousSellSword.java @@ -16,6 +16,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.counters.CounterType; +import mage.filter.common.FilterAnyTarget; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetAnyTarget; @@ -29,6 +30,8 @@ import java.util.UUID; */ public final class CallousSellSword extends AdventureCard { + private static final FilterAnyTarget filterSecondTarget = new FilterAnyTarget("any other target"); + private static final Hint hint = new ValueHint( "Creatures that died under your control this turn", CallousSellSwordValue.instance ); @@ -53,7 +56,7 @@ public final class CallousSellSword extends AdventureCard { // Target creature you control deals damage equal to its power to any other target. Then sacrifice it. this.getSpellCard().getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect()); this.getSpellCard().getSpellAbility().addTarget(new TargetControlledCreaturePermanent().setTargetTag(1)); - this.getSpellCard().getSpellAbility().addTarget(new TargetAnyTarget().setTargetTag(2)); + this.getSpellCard().getSpellAbility().addTarget(new TargetAnyTarget(1, 1, filterSecondTarget).setTargetTag(2)); this.getSpellCard().getSpellAbility().addEffect(new CallousSellSwordSacrificeFirstTargetEffect().concatBy("Then")); } diff --git a/Mage.Sets/src/mage/cards/i/InsultInjury.java b/Mage.Sets/src/mage/cards/i/InsultInjury.java index 0ee8c5cade2..f110d89587e 100644 --- a/Mage.Sets/src/mage/cards/i/InsultInjury.java +++ b/Mage.Sets/src/mage/cards/i/InsultInjury.java @@ -97,7 +97,7 @@ class InjuryEffect extends OneShotEffect { InjuryEffect() { super(Outcome.Damage); - this.staticText = "{this} deals 2 damage to target creature and 2 damage to target player"; + this.staticText = "{this} deals 2 damage to target creature and 2 damage to target player or planeswalker"; } InjuryEffect(final InjuryEffect effect) { diff --git a/Mage.Sets/src/mage/cards/l/LivingLectern.java b/Mage.Sets/src/mage/cards/l/LivingLectern.java index 110a2844b1a..365023aaad3 100644 --- a/Mage.Sets/src/mage/cards/l/LivingLectern.java +++ b/Mage.Sets/src/mage/cards/l/LivingLectern.java @@ -12,7 +12,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.RoleType; import mage.constants.SubType; -import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.target.TargetPermanent; import java.util.UUID; @@ -22,6 +23,13 @@ import java.util.UUID; */ public final class LivingLectern extends CardImpl { + private static final FilterControlledCreaturePermanent filter = + new FilterControlledCreaturePermanent("other target creature you control"); + + static { + filter.add(AnotherPredicate.instance); + } + public LivingLectern(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}"); @@ -36,7 +44,7 @@ public final class LivingLectern extends CardImpl { ability.addCost(new SacrificeSourceCost()); ability.addEffect(new CreateRoleAttachedTargetEffect(RoleType.SORCERER)); ability.addTarget(new TargetPermanent( - 0, 1, StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + 0, 1, filter )); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java b/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java index c1e6eb954c5..089ddf801e4 100644 --- a/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java +++ b/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java @@ -47,7 +47,8 @@ public final class RedcapGutterDweller extends CardImpl { new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)), "Sacrifice another creature? If you do, put a +1/+1 counter on {this} " + "and exile the top card of your library. You may play that card this turn." - ).addEffect(new ExileTopXMayPlayUntilEndOfTurnEffect(1, false).concatBy("and")), + ).addEffect(new ExileTopXMayPlayUntilEndOfTurnEffect(1, false) + .setText("and exile the top card of your library. You may play that card this turn")), TargetController.YOU, false )); diff --git a/Mage.Sets/src/mage/cards/r/RestlessSpire.java b/Mage.Sets/src/mage/cards/r/RestlessSpire.java index 6e2fbc1c071..e2855d726b0 100644 --- a/Mage.Sets/src/mage/cards/r/RestlessSpire.java +++ b/Mage.Sets/src/mage/cards/r/RestlessSpire.java @@ -40,7 +40,7 @@ public final class RestlessSpire extends CardImpl { // {U}{R}: Until end of turn, Restless Spire becomes a 2/1 blue and red Elemental creature with "As long as it's your turn, this creature has first strike". It's still a land. this.addAbility(new SimpleActivatedAbility(new BecomesCreatureSourceEffect( - new CreatureToken(2, 1, "2/1 blue and red Elemental creature with \"As long as it's your turn, this creature has first strike\"") + new CreatureToken(2, 1, "2/1 blue and red Elemental creature with \"As long as it's your turn, this creature has first strike.\"") .withColor("UR").withSubType(SubType.ELEMENTAL) .withAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield), diff --git a/Mage.Sets/src/mage/cards/s/SentinelOfLostLore.java b/Mage.Sets/src/mage/cards/s/SentinelOfLostLore.java index 6b7da599e0c..6508e575397 100644 --- a/Mage.Sets/src/mage/cards/s/SentinelOfLostLore.java +++ b/Mage.Sets/src/mage/cards/s/SentinelOfLostLore.java @@ -44,7 +44,8 @@ public final class SentinelOfLostLore extends CardImpl { // When Sentinel of Lost Lore enters the battlefield, choose one or more — // • Return target card you own in exile that has an Adventure to your hand. - Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect() + .setText("return target card you own in exile that has an Adventure to your hand")); ability.addTarget(new TargetCardInExile(filterOwnedCard)); ability.getModes().setMinModes(1); ability.getModes().setMaxModes(3); diff --git a/Mage.Sets/src/mage/cards/t/TeferisResponse.java b/Mage.Sets/src/mage/cards/t/TeferisResponse.java index a4b2150844a..a86521686c5 100644 --- a/Mage.Sets/src/mage/cards/t/TeferisResponse.java +++ b/Mage.Sets/src/mage/cards/t/TeferisResponse.java @@ -1,7 +1,6 @@ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -17,6 +16,8 @@ import mage.game.permanent.Permanent; import mage.game.stack.StackObject; import mage.target.TargetStackObject; +import java.util.UUID; + /** * * @author AlumiuN @@ -37,7 +38,7 @@ public final class TeferisResponse extends CardImpl { this.getSpellAbility().addTarget(new TargetStackObject(filter)); // Draw two cards. - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2).concatBy("
")); } private TeferisResponse(final TeferisResponse card) { diff --git a/Mage.Sets/src/mage/cards/t/TwiningTwins.java b/Mage.Sets/src/mage/cards/t/TwiningTwins.java index 457dab15958..4df5cfcbe58 100644 --- a/Mage.Sets/src/mage/cards/t/TwiningTwins.java +++ b/Mage.Sets/src/mage/cards/t/TwiningTwins.java @@ -67,7 +67,7 @@ class TwiningTwinsEffect extends OneShotEffect { TwiningTwinsEffect() { super(Outcome.Detriment); - staticText = "Exile target nontoken creature. Return that card to the battlefield under its " + staticText = "Exile target nontoken creature. Return it to the battlefield under its " + "owner's control at the beginning of the next end step"; } diff --git a/Mage.Sets/src/mage/cards/v/VerdantOutrider.java b/Mage.Sets/src/mage/cards/v/VerdantOutrider.java index 76aa5085022..5074b7af795 100644 --- a/Mage.Sets/src/mage/cards/v/VerdantOutrider.java +++ b/Mage.Sets/src/mage/cards/v/VerdantOutrider.java @@ -36,7 +36,8 @@ public final class VerdantOutrider extends CardImpl { // {1}{G}: Verdant Outrider can't be blocked by creatures with power 2 or less this turn. this.addAbility(new SimpleActivatedAbility( - new CantBeBlockedByCreaturesSourceEffect(filter, Duration.EndOfTurn), + new CantBeBlockedByCreaturesSourceEffect(filter, Duration.EndOfTurn) + .setText("{this} can't be blocked by creatures with power 2 or less this turn"), new ManaCostsImpl<>("{1}{G}") )); } diff --git a/Mage.Sets/src/mage/cards/v/VeryCrypticCommandD.java b/Mage.Sets/src/mage/cards/v/VeryCrypticCommandD.java index 58157a7a24b..5bee29b2ea8 100644 --- a/Mage.Sets/src/mage/cards/v/VeryCrypticCommandD.java +++ b/Mage.Sets/src/mage/cards/v/VeryCrypticCommandD.java @@ -1,7 +1,6 @@ package mage.cards.v; -import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.Mode; @@ -18,6 +17,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.filter.FilterSpell; import mage.filter.FilterStackObject; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.other.NumberOfTargetsPredicate; @@ -28,13 +28,15 @@ import mage.target.TargetPermanent; import mage.target.TargetStackObject; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author spjspj */ public final class VeryCrypticCommandD extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("spell or ability with a single target"); + private static final FilterStackObject filter = new FilterSpell("spell with a single target"); private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("nontoken creature"); static { diff --git a/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java index df03d47f5ab..4e7aede57ab 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java @@ -178,7 +178,10 @@ public class DamageTargetEffect extends OneShotEffect { sb.append(' '); } } - sb.append("target ").append(targetName); + if (!targetName.contains("target ")) { + sb.append("target "); + } + sb.append(targetName); } } else { sb.append("that target"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToTargetEffect.java index 12fd71ba3ea..c29f641e05d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventNextDamageFromChosenSourceToTargetEffect.java @@ -70,8 +70,12 @@ public class PreventNextDamageFromChosenSourceToTargetEffect extends PreventionE @Override public String getText(Mode mode) { StringBuilder sb = new StringBuilder("The next time a ").append(targetSource.getFilter().getMessage()); - sb.append(" of your choice would deal damage to target "); - sb.append(mode.getTargets().get(0).getTargetName()); + sb.append(" of your choice would deal damage to "); + String targetName = mode.getTargets().get(0).getTargetName(); + if (!targetName.contains("target ") && !targetName.endsWith("any target")) { + sb.append("target "); + } + sb.append(targetName); if (duration == Duration.EndOfTurn) { sb.append(" this turn"); } diff --git a/Mage/src/main/java/mage/target/TargetImpl.java b/Mage/src/main/java/mage/target/TargetImpl.java index 47de4700030..fa2e8be7a99 100644 --- a/Mage/src/main/java/mage/target/TargetImpl.java +++ b/Mage/src/main/java/mage/target/TargetImpl.java @@ -119,7 +119,19 @@ public abstract class TargetImpl implements Target { sb.append(CardUtil.numberToText(max)); sb.append(' '); } - if (!isNotTarget() && !getTargetName().contains("target ") && !getTargetName().endsWith("any target")) { + boolean addTargetWord = false; + if (!isNotTarget()) { + addTargetWord = true; + if (getTargetName().contains("target ")) { + addTargetWord = false; + } else if (getTargetName().endsWith("any target") + || getTargetName().endsWith("any other target")) { + addTargetWord = false; + } + // endsWith needs to be specific. + // e.g. "spell with a single target" => need to prefix with "target ". + } + if (addTargetWord) { sb.append("target "); } if (isNotTarget() && min == 1 && max == 1) { diff --git a/Mage/src/main/java/mage/target/common/TargetAnyTarget.java b/Mage/src/main/java/mage/target/common/TargetAnyTarget.java index cabe6310758..ce7117c90bb 100644 --- a/Mage/src/main/java/mage/target/common/TargetAnyTarget.java +++ b/Mage/src/main/java/mage/target/common/TargetAnyTarget.java @@ -7,7 +7,7 @@ import mage.filter.common.FilterAnyTarget; */ public class TargetAnyTarget extends TargetPermanentOrPlayer { - private static final FilterAnyTarget filter = new FilterAnyTarget(); + private static final FilterAnyTarget defaultFilter = new FilterAnyTarget(); public TargetAnyTarget() { this(1); @@ -18,6 +18,10 @@ public class TargetAnyTarget extends TargetPermanentOrPlayer { } public TargetAnyTarget(int minNumTargets, int maxNumTargets) { + this(minNumTargets, maxNumTargets, defaultFilter); + } + + public TargetAnyTarget(int minNumTargets, int maxNumTargets, FilterAnyTarget filter) { super(minNumTargets, maxNumTargets, filter, false); }