diff --git a/Mage.Sets/src/mage/cards/a/AetherfluxConduit.java b/Mage.Sets/src/mage/cards/a/AetherfluxConduit.java index d21de17365e..f4f9316a48e 100644 --- a/Mage.Sets/src/mage/cards/a/AetherfluxConduit.java +++ b/Mage.Sets/src/mage/cards/a/AetherfluxConduit.java @@ -1,8 +1,5 @@ package mage.cards.a; -import java.util.Optional; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; @@ -10,14 +7,20 @@ import mage.abilities.costs.common.PayEnergyCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.CastFromHandWithoutPayingManaCostEffect; import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.stack.Spell; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; /** * @author sobiech @@ -28,14 +31,12 @@ public final class AetherfluxConduit extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}"); // Whenever you cast a spell, you get an amount of {E} equal to the amount of mana spent to cast that spell. - this.addAbility(new SpellCastControllerTriggeredAbility( - new AetherfluxConduitEffect(),false - )); + this.addAbility(new SpellCastControllerTriggeredAbility(new AetherfluxConduitManaEffect(), false)); // {T}, Pay fifty {E}: Draw seven cards. You may cast any number of spells from your hand without paying their mana costs. final Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(7), new TapSourceCost()); ability.addCost(new PayEnergyCost(50).setText("Pay fifty {E}")); - ability.addEffect(new CastFromHandWithoutPayingManaCostEffect()); + ability.addEffect(new AetherfluxConduitCastEffect()); this.addAbility(ability); } @@ -48,19 +49,21 @@ public final class AetherfluxConduit extends CardImpl { return new AetherfluxConduit(this); } } -class AetherfluxConduitEffect extends OneShotEffect { - AetherfluxConduitEffect() { +class AetherfluxConduitManaEffect extends OneShotEffect { + + AetherfluxConduitManaEffect() { super(Outcome.Benefit); this.staticText = "you get an amount of {E} (energy counters) equal to the amount of mana spent to cast that spell"; } - private AetherfluxConduitEffect(AetherfluxConduitEffect effect) { + + private AetherfluxConduitManaEffect(AetherfluxConduitManaEffect effect) { super(effect); } @Override - public AetherfluxConduitEffect copy() { - return new AetherfluxConduitEffect(this); + public AetherfluxConduitManaEffect copy() { + return new AetherfluxConduitManaEffect(this); } @Override @@ -72,3 +75,31 @@ class AetherfluxConduitEffect extends OneShotEffect { } } +class AetherfluxConduitCastEffect extends OneShotEffect { + + AetherfluxConduitCastEffect() { + super(Outcome.Benefit); + staticText = "You may cast any number of spells from your hand without paying their mana costs"; + } + + private AetherfluxConduitCastEffect(final AetherfluxConduitCastEffect effect) { + super(effect); + } + + @Override + public AetherfluxConduitCastEffect copy() { + return new AetherfluxConduitCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + CardUtil.castMultipleWithAttributeForFree( + player, source, game, new CardsImpl(player.getHand()), StaticFilters.FILTER_CARD + ); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CollisionCourse.java b/Mage.Sets/src/mage/cards/c/CollisionCourse.java index a638e55c259..d33a6607735 100644 --- a/Mage.Sets/src/mage/cards/c/CollisionCourse.java +++ b/Mage.Sets/src/mage/cards/c/CollisionCourse.java @@ -42,7 +42,9 @@ public final class CollisionCourse extends CardImpl { // Choose one -- // * Collision Course deals X damage to target creature, where X is the number of permanents you control that are creatures and/or Vehicles. - this.getSpellAbility().addEffect(new DamageTargetEffect(xValue)); + this.getSpellAbility().addEffect(new DamageTargetEffect(xValue) + .setText("{this} deals X damage to target creature, where X is " + + "the number of permanents you control that are creatures and/or Vehicles")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addHint(hint); diff --git a/Mage.Sets/src/mage/cards/e/ExplosiveGetaway.java b/Mage.Sets/src/mage/cards/e/ExplosiveGetaway.java index 5410a4bcbc1..4f2f182a89c 100644 --- a/Mage.Sets/src/mage/cards/e/ExplosiveGetaway.java +++ b/Mage.Sets/src/mage/cards/e/ExplosiveGetaway.java @@ -1,43 +1,29 @@ package mage.cards.e; -import java.util.UUID; -import java.util.function.Predicate; - -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.predicate.Predicates; import mage.target.TargetPermanent; +import java.util.UUID; + /** - * * @author Jmlundeen */ public final class ExplosiveGetaway extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifact or creature"); - - static { - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.CREATURE.getPredicate() - )); - } public ExplosiveGetaway(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{W}"); - // Exile up to one target artifact or creature. Return it to the battlefield under its owner's control at the beginning of the next end step. this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); - this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter)); + this.getSpellAbility().addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); + // Explosive Getaway deals 4 damage to each creature. - this.getSpellAbility().addEffect(new DamageAllEffect(4, StaticFilters.FILTER_PERMANENT_ALL_CREATURES).concatBy("
")); + this.getSpellAbility().addEffect(new DamageAllEffect(4, StaticFilters.FILTER_PERMANENT_CREATURE).concatBy("
")); } private ExplosiveGetaway(final ExplosiveGetaway card) { diff --git a/Mage.Sets/src/mage/cards/g/GuidelightOptimizer.java b/Mage.Sets/src/mage/cards/g/GuidelightOptimizer.java index 344860c6e58..3d9d9504de3 100644 --- a/Mage.Sets/src/mage/cards/g/GuidelightOptimizer.java +++ b/Mage.Sets/src/mage/cards/g/GuidelightOptimizer.java @@ -53,7 +53,7 @@ class ArtifactOrActivatedManaBuilder extends ConditionalManaBuilder { @Override public String getRule() { - return "Spend this mana only to cast an artifact spells or activate an ability"; + return "Spend this mana only to cast an artifact spell or activate an ability"; } } @@ -61,7 +61,7 @@ class ArtifactOrActivatedConditionalMana extends ConditionalMana { public ArtifactOrActivatedConditionalMana(Mana mana) { super(mana); - staticText = "Spend this mana only to cast an artifact spells or activate an ability"; + staticText = "Spend this mana only to cast an artifact spell or activate an ability"; addCondition(new ArtifactOrActivatedManaCondition()); } } @@ -80,4 +80,4 @@ class ArtifactOrActivatedManaCondition extends ManaCondition implements Conditio public boolean apply(Game game, Ability source, UUID originalId, mage.abilities.costs.Cost costsToPay) { return apply(game, source); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/h/HashatonScarabsFist.java b/Mage.Sets/src/mage/cards/h/HashatonScarabsFist.java index 0423996ec28..135de070b3a 100644 --- a/Mage.Sets/src/mage/cards/h/HashatonScarabsFist.java +++ b/Mage.Sets/src/mage/cards/h/HashatonScarabsFist.java @@ -83,7 +83,7 @@ class HashatonScarabsFistEffect extends OneShotEffect { HashatonScarabsFistEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "create a tapped token that`s a copy of that card, except it`s a 4/4 black Zombie"; + this.staticText = "create a tapped token that's a copy of that card, except it's a 4/4 black Zombie"; } private HashatonScarabsFistEffect(OneShotEffect effect) { diff --git a/Mage.Sets/src/mage/cards/h/HowlsquadHeavy.java b/Mage.Sets/src/mage/cards/h/HowlsquadHeavy.java index 9ad6dc1e633..84f03204171 100644 --- a/Mage.Sets/src/mage/cards/h/HowlsquadHeavy.java +++ b/Mage.Sets/src/mage/cards/h/HowlsquadHeavy.java @@ -9,7 +9,7 @@ import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.HasteAbility; @@ -22,7 +22,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SubType; -import mage.filter.StaticFilters; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.token.GoblinToken; @@ -36,7 +36,8 @@ import java.util.UUID; */ public final class HowlsquadHeavy extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.GOBLIN)); + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.GOBLIN); + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); private static final Hint hint = new ValueHint("Goblins you control", xValue); public HowlsquadHeavy(UUID ownerId, CardSetInfo setInfo) { @@ -51,10 +52,9 @@ public final class HowlsquadHeavy extends CardImpl { this.addAbility(new StartYourEnginesAbility()); // Other Goblins you control have haste. - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - HasteAbility.getInstance(), Duration.WhileOnBattlefield, - StaticFilters.FILTER_PERMANENT_CREATURE_GOBLINS, true - ))); + this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect( + HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ).setText("other Goblins you control have haste"))); // At the beginning of combat on your turn, create a 1/1 red Goblin creature token. That token attacks this combat if able. this.addAbility(new BeginningOfCombatTriggeredAbility(new HowlsquadHeavyEffect())); diff --git a/Mage.Sets/src/mage/cards/l/LifecraftEngine.java b/Mage.Sets/src/mage/cards/l/LifecraftEngine.java index dae3206bb16..f7d3493c669 100644 --- a/Mage.Sets/src/mage/cards/l/LifecraftEngine.java +++ b/Mage.Sets/src/mage/cards/l/LifecraftEngine.java @@ -68,7 +68,7 @@ class LifecraftEngineAddSubTypeAllEffect extends ContinuousEffectImpl { public LifecraftEngineAddSubTypeAllEffect() { super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); - staticText = "Vehicle creatures you control are the chosen type in addition to their other types."; + staticText = "Vehicle creatures you control are the chosen creature type in addition to their other types."; } private LifecraftEngineAddSubTypeAllEffect(final LifecraftEngineAddSubTypeAllEffect effect) { diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheWorldOoze.java b/Mage.Sets/src/mage/cards/m/MarchOfTheWorldOoze.java index 44328e1b21f..2385f48705f 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfTheWorldOoze.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfTheWorldOoze.java @@ -34,11 +34,11 @@ public final class MarchOfTheWorldOoze extends CardImpl { // Creatures you control have base power and toughness 6/6 and are Oozes in addition to their other types. Ability ability = new SimpleStaticAbility(new SetBasePowerToughnessAllEffect( - 6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURE + 6, 6, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES )); ability.addEffect(new AddCardSubtypeAllEffect( - StaticFilters.FILTER_CONTROLLED_CREATURE, SubType.OOZE, null - ).concatBy("and")); + StaticFilters.FILTER_CONTROLLED_CREATURES, SubType.OOZE, null + ).setText("and are Oozes in addition to their other types")); this.addAbility(ability); // Whenever an opponent casts a spell, if it's not their turn, you create a 3/3 green Elephant creature token. diff --git a/Mage.Sets/src/mage/cards/m/MarketbackWalker.java b/Mage.Sets/src/mage/cards/m/MarketbackWalker.java index fcca439cd66..79ae7f2372e 100644 --- a/Mage.Sets/src/mage/cards/m/MarketbackWalker.java +++ b/Mage.Sets/src/mage/cards/m/MarketbackWalker.java @@ -41,7 +41,7 @@ public final class MarketbackWalker extends CardImpl { )); // When this creature dies, draw a card for each +1/+1 counter on it. - this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(xValue))); + this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(xValue).setText("draw a card for each +1/+1 counter on it"))); } private MarketbackWalker(final MarketbackWalker card) { diff --git a/Mage.Sets/src/mage/cards/m/MarshalsPathcruiser.java b/Mage.Sets/src/mage/cards/m/MarshalsPathcruiser.java index 86b53670b0d..16a2732dc8c 100644 --- a/Mage.Sets/src/mage/cards/m/MarshalsPathcruiser.java +++ b/Mage.Sets/src/mage/cards/m/MarshalsPathcruiser.java @@ -42,7 +42,7 @@ public final class MarshalsPathcruiser extends CardImpl { new AddCardTypeSourceEffect(Duration.Custom, CardType.ARTIFACT, CardType.CREATURE), new ManaCostsImpl<>("{W}{U}{B}{R}{G}") ); - ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2))); + ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).setText("Put two +1/+1 counters on it")); this.addAbility(ability); // Crew 5 diff --git a/Mage.Sets/src/mage/cards/p/Panharmonicon.java b/Mage.Sets/src/mage/cards/p/Panharmonicon.java index 239825fbfaa..5d9f0a9aebd 100644 --- a/Mage.Sets/src/mage/cards/p/Panharmonicon.java +++ b/Mage.Sets/src/mage/cards/p/Panharmonicon.java @@ -43,7 +43,7 @@ class PanharmoniconEffect extends ReplacementEffectImpl { PanharmoniconEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "If an artifact or creature entering the battlefield causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time"; + staticText = "If an artifact or creature entering causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time"; } private PanharmoniconEffect(final PanharmoniconEffect effect) { diff --git a/Mage.Sets/src/mage/cards/p/PiaNalaarChiefMechanic.java b/Mage.Sets/src/mage/cards/p/PiaNalaarChiefMechanic.java index 59f4a8d8b49..f52834a4cc9 100644 --- a/Mage.Sets/src/mage/cards/p/PiaNalaarChiefMechanic.java +++ b/Mage.Sets/src/mage/cards/p/PiaNalaarChiefMechanic.java @@ -1,6 +1,5 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility; @@ -9,9 +8,9 @@ import mage.abilities.costs.common.PayEnergyCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -19,8 +18,9 @@ import mage.game.permanent.token.NalaarAetherjetToken; import mage.game.permanent.token.Token; import mage.players.Player; +import java.util.UUID; + /** - * * @author Jmlundeen */ public final class PiaNalaarChiefMechanic extends CardImpl { @@ -33,7 +33,7 @@ public final class PiaNalaarChiefMechanic extends CardImpl { public PiaNalaarChiefMechanic(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}{R}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); @@ -64,7 +64,7 @@ class PiaNalaarChiefMechanicEffect extends OneShotEffect { public PiaNalaarChiefMechanicEffect() { super(Outcome.Benefit); staticText = "you may pay one or more {E}. If you do, create an X/X colorless Vehicle artifact token " + - "named Nalaar Aetherjet with flying and crew 2, where X is the amount of {E} spent this way"; + "named Nalaar Aetherjet with flying and crew 2, where X is the amount of {E} paid this way"; } public PiaNalaarChiefMechanicEffect(final PiaNalaarChiefMechanicEffect effect) { @@ -95,4 +95,4 @@ class PiaNalaarChiefMechanicEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheCrossing.java b/Mage.Sets/src/mage/cards/p/PriestOfTheCrossing.java index f35d63dfdad..09ee13e628d 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfTheCrossing.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheCrossing.java @@ -9,6 +9,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.TargetController; import mage.counters.CounterType; import mage.filter.StaticFilters; @@ -30,8 +31,13 @@ public class PriestOfTheCrossing extends CardImpl { // At the beginning of each end step, put X +1/+1 counters on each creature you control, where X is the number of creatures that died under your control this turn. this.addAbility(new BeginningOfEndStepTriggeredAbility( - new AddCountersAllEffect(CounterType.P1P1.createInstance(), CreaturesYouControlDiedCount.instance, StaticFilters.FILTER_CONTROLLED_CREATURE) - .setText("put X +1/+1 counters on each creature you control, where X is the number of creatures that died under your control this turn"))); + TargetController.ANY, + new AddCountersAllEffect( + CounterType.P1P1.createInstance(), CreaturesYouControlDiedCount.instance, + StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("put X +1/+1 counters on each creature you control, where X is " + + "the number of creatures that died under your control this turn"), false + )); } public PriestOfTheCrossing(PriestOfTheCrossing card) { diff --git a/Mage.Sets/src/mage/cards/s/SaheeliRadiantCreator.java b/Mage.Sets/src/mage/cards/s/SaheeliRadiantCreator.java index 970968117af..52f3aa5c77b 100644 --- a/Mage.Sets/src/mage/cards/s/SaheeliRadiantCreator.java +++ b/Mage.Sets/src/mage/cards/s/SaheeliRadiantCreator.java @@ -1,6 +1,5 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; @@ -11,12 +10,12 @@ import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterSpell; import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; @@ -24,13 +23,14 @@ import mage.game.Game; import mage.target.TargetPermanent; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author Jmlundeen */ public final class SaheeliRadiantCreator extends CardImpl { - private static final FilterSpell filter = new FilterSpell("Artificer or artifact spell"); + private static final FilterSpell filter = new FilterSpell("an Artificer or artifact spell"); static { filter.add(Predicates.or( @@ -41,7 +41,7 @@ public final class SaheeliRadiantCreator extends CardImpl { public SaheeliRadiantCreator(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}{R}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); @@ -105,4 +105,4 @@ class SaheeliRadiantCreatorCopyEffect extends OneShotEffect { effect.sacrificeTokensCreatedAtNextEndStep(game, source); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/v/VoyagerGlidecar.java b/Mage.Sets/src/mage/cards/v/VoyagerGlidecar.java index 5131996f87e..36386420cea 100644 --- a/Mage.Sets/src/mage/cards/v/VoyagerGlidecar.java +++ b/Mage.Sets/src/mage/cards/v/VoyagerGlidecar.java @@ -17,7 +17,10 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.counters.CounterType; -import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.permanent.TappedPredicate; import mage.target.common.TargetControlledPermanent; import java.util.UUID; @@ -27,6 +30,13 @@ import java.util.UUID; */ public final class VoyagerGlidecar extends CardImpl { + private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("other untapped creatures you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(TappedPredicate.UNTAPPED); + } + public VoyagerGlidecar(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{W}"); @@ -42,9 +52,7 @@ public final class VoyagerGlidecar extends CardImpl { new AddCardTypeSourceEffect( Duration.EndOfTurn, CardType.ARTIFACT, CardType.CREATURE ).setText("until end of turn, this Vehicle becomes an artifact creature"), - new TapTargetCost(new TargetControlledPermanent( - 3, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES - )) + new TapTargetCost(new TargetControlledPermanent(3, filter)) ); ability.addEffect(new GainAbilitySourceEffect( FlyingAbility.getInstance(), Duration.EndOfTurn diff --git a/Mage.Sets/src/mage/cards/w/WinterCursedRider.java b/Mage.Sets/src/mage/cards/w/WinterCursedRider.java index c2fea8bd0f0..82eeb2ae7c5 100644 --- a/Mage.Sets/src/mage/cards/w/WinterCursedRider.java +++ b/Mage.Sets/src/mage/cards/w/WinterCursedRider.java @@ -24,6 +24,7 @@ import mage.constants.CardType; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; +import mage.util.CardUtil; /** * @@ -54,7 +55,7 @@ public final class WinterCursedRider extends CardImpl { WardAbility wardAbility = new WardAbility(new PayLifeCost(2)); this.addAbility(new SimpleStaticAbility( new GainAbilityAllEffect(wardAbility, Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACTS) - .setText("Artifacts you control have " + "\"" + wardAbility.getRuleWithoutHint() + "\"") + .setText("Artifacts you control have " + "\"" + CardUtil.getTextWithFirstCharUpperCase(wardAbility.getRuleWithoutHint()) + "\"") )); // Exhaust -- {2}{U}{B}, {T}, Exile X artifact cards from your graveyard: Each other nonartifact creature gets -X/-X until end of turn. Ability ability = new ExhaustAbility(new BoostAllEffect(xValue, xValue, Duration.EndOfTurn, filter, true), diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index aed774e5565..05056c4e059 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -75,7 +75,7 @@ public class VerifyCardDataTest { private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class); - private static final String FULL_ABILITIES_CHECK_SET_CODES = "INR"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all + private static final String FULL_ABILITIES_CHECK_SET_CODES = "DRC"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all private static final boolean CHECK_ONLY_ABILITIES_TEXT = false; // use when checking text locally, suppresses unnecessary checks and output messages private static final boolean CHECK_COPYABLE_FIELDS = true; // disable for better verify test performance diff --git a/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java index f67a6bdba61..e798718f028 100644 --- a/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/PutIntoGraveFromBattlefieldAllTriggeredAbility.java @@ -30,8 +30,8 @@ public class PutIntoGraveFromBattlefieldAllTriggeredAbility extends TriggeredAbi this.filter = filter; this.onlyToControllerGraveyard = onlyToControllerGraveyard; this.setTargetPointer = setTargetPointer; - setTriggerPhrase("Whenever " + filter.getMessage() + " is put into " + (onlyToControllerGraveyard ? "your" : "a") - + " graveyard from the battlefield, "); + setTriggerPhrase("Whenever " + filter.getMessage() + " is put into " + + (onlyToControllerGraveyard ? "your" : "a") + " graveyard, "); } protected PutIntoGraveFromBattlefieldAllTriggeredAbility(final PutIntoGraveFromBattlefieldAllTriggeredAbility ability) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java index a6b0234d495..9a9a32d454c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileCardYouChooseTargetOpponentEffect.java @@ -9,6 +9,7 @@ import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; +import mage.util.CardUtil; /** * @author LevelX2 @@ -20,7 +21,7 @@ public class ExileCardYouChooseTargetOpponentEffect extends OneShotEffect { public ExileCardYouChooseTargetOpponentEffect(FilterCard filter) { super(Outcome.Discard); this.staticText = "target opponent reveals their hand. You choose " - + filter.getMessage() + (filter.getMessage().contains("from it") ? "" : " from it") + " and exile that card"; + + CardUtil.addArticle(filter.getMessage()) + (filter.getMessage().contains("from it") ? "" : " from it") + " and exile that card"; this.filter = filter; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java index 5d3f0b1bea0..078e2b09e91 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java @@ -7,10 +7,11 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.*; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.util.CardUtil; import java.util.ArrayList; import java.util.List; -import java.util.Locale; +import java.util.stream.Collectors; /** * @author emerald000 @@ -76,19 +77,20 @@ public class AddCardTypeSourceEffect extends ContinuousEffectImpl { } StringBuilder sb = new StringBuilder(); sb.append("{this} becomes "); - boolean article = false; - for (CardType cardType : addedCardTypes) { - if (!article) { - if (cardType.toString().startsWith("A") || cardType.toString().startsWith("E")) { - sb.append("an "); - } else { - sb.append("a "); - } - article = true; - } - sb.append(cardType.toString().toLowerCase(Locale.ENGLISH)).append(" "); + sb.append(CardUtil.addArticle( + addedCardTypes + .stream() + .map(CardType::toString) + .map(String::toLowerCase) + .collect(Collectors.joining(" ")) + )); + if (!addedCardTypes.contains(CardType.ARTIFACT) || !addedCardTypes.contains(CardType.CREATURE)) { + sb.append(" in addition to its other types"); + } + if (!this.getDuration().toString().isEmpty()) { + sb.append(' '); + sb.append(this.getDuration()); } - sb.append("in addition to its other types ").append(this.getDuration().toString()); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/ExhaustAbility.java b/Mage/src/main/java/mage/abilities/keyword/ExhaustAbility.java index f8cd4e3f532..c34fcfc2a6c 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ExhaustAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ExhaustAbility.java @@ -12,15 +12,14 @@ import mage.game.Game; */ public class ExhaustAbility extends ActivatedAbilityImpl { - private boolean withReminderText = true; + private final boolean withReminderText; public ExhaustAbility(Effect effect, Cost cost) { - super(Zone.BATTLEFIELD, effect, cost); + this(effect, cost, true); } public ExhaustAbility(Effect effect, Cost cost, boolean withReminderText) { super(Zone.BATTLEFIELD, effect, cost); - this.setRuleVisible(false); this.withReminderText = withReminderText; } @@ -30,11 +29,6 @@ public class ExhaustAbility extends ActivatedAbilityImpl { this.withReminderText = ability.withReminderText; } - public ExhaustAbility withReminderText(boolean withReminderText) { - this.withReminderText = withReminderText; - return this; - } - @Override public ExhaustAbility copy() { return new ExhaustAbility(this); @@ -45,8 +39,8 @@ public class ExhaustAbility extends ActivatedAbilityImpl { ActivationInfo info = getActivationInfo(game); if (info != null && info.totalActivations >= maxActivationsPerGame) { boolean canActivate = !game.getContinuousEffects() - .asThough(sourceId, AsThoughEffectType.ALLOW_EXHAUST_PER_TURN, this, controllerId, game) - .isEmpty(); + .asThough(sourceId, AsThoughEffectType.ALLOW_EXHAUST_PER_TURN, this, controllerId, game) + .isEmpty(); if (canActivate) { return true; }