[SNC] various text fixes

This commit is contained in:
Evan Kranzler 2022-04-23 21:28:32 -04:00
parent 62655793da
commit cf885a3312
42 changed files with 91 additions and 65 deletions

View file

@ -24,7 +24,7 @@ import java.util.UUID;
public final class AngelicObserver extends CardImpl { public final class AngelicObserver extends CardImpl {
private static final FilterPermanent filter private static final FilterPermanent filter
= new FilterControlledPermanent(SubType.CITIZEN, "Citizens you control"); = new FilterControlledPermanent(SubType.CITIZEN, "Citizen you control");
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
private static final Hint hint = new ValueHint("Citizens you control", xValue); private static final Hint hint = new ValueHint("Citizens you control", xValue);

View file

@ -1,6 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility;
@ -8,12 +7,12 @@ import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.Effects; import mage.abilities.effects.Effects;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.keyword.ConniveSourceEffect; import mage.abilities.effects.keyword.ConniveSourceEffect;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
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.ComparisonType;
import mage.constants.SubType;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
@ -25,8 +24,9 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetadjustment.TargetAdjuster;
import java.util.UUID;
/** /**
*
* @author weirddan455 * @author weirddan455
*/ */
public final class BodyLaunderer extends CardImpl { public final class BodyLaunderer extends CardImpl {
@ -51,11 +51,11 @@ public final class BodyLaunderer extends CardImpl {
this.addAbility(DeathtouchAbility.getInstance()); this.addAbility(DeathtouchAbility.getInstance());
// Whenever another nontoken creature you control dies, Body Launderer connives. // Whenever another nontoken creature you control dies, Body Launderer connives.
this.addAbility(new DiesCreatureTriggeredAbility(new ConniveSourceEffect(), false, filter)); this.addAbility(new DiesCreatureTriggeredAbility(new ConniveSourceEffect("{this}"), false, filter));
// When Body Launderer dies, return another target non-Rogue creature card with power less than or equal to Body Launderer from your graveyard to the battlefield. // When Body Launderer dies, return another target non-Rogue creature card with power less than or equal to Body Launderer from your graveyard to the battlefield.
Ability ability = new DiesSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect() Ability ability = new DiesSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()
.setText("return another target non-Rogue creature card with power less than or equal to {this} from your graveyard to the battlefield") .setText("return another target non-Rogue creature card with equal or lesser power from your graveyard to the battlefield")
); );
ability.setTargetAdjuster(BodyLaundererAdjuster.instance); ability.setTargetAdjuster(BodyLaundererAdjuster.instance);
this.addAbility(ability); this.addAbility(ability);

View file

@ -1,16 +1,16 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.effects.keyword.ScryEffect;
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.counters.CounterType; import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class BoonOfSafety extends CardImpl { public final class BoonOfSafety extends CardImpl {
@ -20,9 +20,10 @@ public final class BoonOfSafety extends CardImpl {
// Put a shield counter on target creature. // Put a shield counter on target creature.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.SHIELD.createInstance())); this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.SHIELD.createInstance()));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Scry 1. // Scry 1.
this.getSpellAbility().addEffect(new ScryEffect(1,false).concatBy("<br>")); this.getSpellAbility().addEffect(new ScryEffect(1, false).concatBy("<br>"));
} }
private BoonOfSafety(final BoonOfSafety card) { private BoonOfSafety(final BoonOfSafety card) {

View file

@ -37,7 +37,7 @@ public final class BouncersBeatdown extends CardImpl {
// This spell costs {2} less to cast if it targets a black permanent. // This spell costs {2} less to cast if it targets a black permanent.
this.addAbility(new SimpleStaticAbility( this.addAbility(new SimpleStaticAbility(
Zone.ALL, new SpellCostReductionSourceEffect(3, condition).setCanWorksOnStackOnly(true) Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true)
).setRuleAtTheTop(true)); ).setRuleAtTheTop(true));
// Bouncer's Beatdown deals X damage to target creature or planeswalker, where X is the greatest power among creatures you control. If that creature or planeswalker would die this turn, exile it instead. // Bouncer's Beatdown deals X damage to target creature or planeswalker, where X is the greatest power among creatures you control. If that creature or planeswalker would die this turn, exile it instead.

View file

@ -43,7 +43,7 @@ public final class BrokersHideout extends CardImpl {
), false); ), false);
ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), null, false ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
))); )));
} }

View file

@ -44,7 +44,7 @@ class CabarettiAscendencyEffect extends OneShotEffect {
public CabarettiAscendencyEffect() { public CabarettiAscendencyEffect() {
super(Outcome.DrawCard); super(Outcome.DrawCard);
this.staticText = "look at the top card of your library. If it's a creature or planeswalker card, you may reveal it and put it in your hand. If you don't, you may put it on the bottom of your library"; this.staticText = "look at the top card of your library. If it's a creature or planeswalker card, you may reveal it and put it into your hand. If you don't put the card into your hand, you may put it on the bottom of your library";
} }
private CabarettiAscendencyEffect(final CabarettiAscendencyEffect effect) { private CabarettiAscendencyEffect(final CabarettiAscendencyEffect effect) {

View file

@ -42,7 +42,7 @@ public final class CabarettiCourtyard extends CardImpl {
), false); ), false);
ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), null, false ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
))); )));
} }

View file

@ -19,7 +19,7 @@ import java.util.UUID;
*/ */
public final class CapennaExpress extends CardImpl { public final class CapennaExpress extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TREASURE); private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TREASURE, "Treasure");
public CapennaExpress(UUID ownerId, CardSetInfo setInfo) { public CapennaExpress(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{G}");

View file

@ -1,7 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -10,14 +8,15 @@ import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.constants.AttachmentType;
import mage.constants.SubType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/** /**
*
* @author weirddan455 * @author weirddan455
*/ */
public final class CementShoes extends CardImpl { public final class CementShoes extends CardImpl {
@ -33,12 +32,11 @@ public final class CementShoes extends CardImpl {
new BeginningOfYourEndStepTriggeredAbility(new TapSourceEffect(), false), new BeginningOfYourEndStepTriggeredAbility(new TapSourceEffect(), false),
AttachmentType.EQUIPMENT AttachmentType.EQUIPMENT
).setText("and has \"At the beginning of your end step, tap this creature.\"")); ).setText("and has \"At the beginning of your end step, tap this creature.\""));
this.addAbility(ability);
// Equipped creature doesn't untap during its controller's untap step. // Equipped creature doesn't untap during its controller's untap step.
ability.addEffect(new DontUntapInControllersUntapStepEnchantedEffect() this.addAbility(new SimpleStaticAbility(new DontUntapInControllersUntapStepEnchantedEffect()
.setText("Equipped creature doesn't untap during its controller's untap step") .setText("Equipped creature doesn't untap during its controller's untap step")));
);
this.addAbility(ability);
// Equip {2} // Equip {2}
this.addAbility(new EquipAbility(2)); this.addAbility(new EquipAbility(2));

View file

@ -43,6 +43,7 @@ public final class CitizensCrowbar extends CardImpl {
new DestroyTargetEffect(), new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT), new DestroyTargetEffect(), new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT),
new SacrificeAttachmentCost(), new ManaCostsImpl<>("{W}"), new TapSourceCost() new SacrificeAttachmentCost(), new ManaCostsImpl<>("{W}"), new TapSourceCost()
)); ));
this.addAbility(ability);
// Equip {2} // Equip {2}
this.addAbility(new EquipAbility(2)); this.addAbility(new EquipAbility(2));

View file

@ -42,7 +42,7 @@ public final class CivilServant extends CardImpl {
// Whenever Civil Servant attacks, you may tap another untapped Citizen you control. If you do, Civil Servant gets +1/+0 and gains lifelink until end of turn. // Whenever Civil Servant attacks, you may tap another untapped Citizen you control. If you do, Civil Servant gets +1/+0 and gains lifelink until end of turn.
this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid(
new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("{this} gets +1/+1"), new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("{this} gets +1/+0"),
new TapTargetCost(new TargetControlledPermanent(filter)) new TapTargetCost(new TargetControlledPermanent(filter))
).addEffect(new GainAbilitySourceEffect( ).addEffect(new GainAbilitySourceEffect(
LifelinkAbility.getInstance(), Duration.EndOfTurn LifelinkAbility.getInstance(), Duration.EndOfTurn

View file

@ -21,7 +21,7 @@ public final class DaringEscape extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Target creature gets +1/+0 and gains first strike until end of turn. Scry 1. // Target creature gets +1/+0 and gains first strike until end of turn. Scry 1.
this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0)); this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0).setText("target creature gets +1/+0"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance()).setText("and gains first strike until end of turn")); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance()).setText("and gains first strike until end of turn"));
this.getSpellAbility().addEffect(new ScryEffect(1, false)); this.getSpellAbility().addEffect(new ScryEffect(1, false));
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -46,7 +46,7 @@ public final class ElspethResplendent extends CardImpl {
this.addAbility(new LoyaltyAbility(new ElspethResplendentLookEffect(), -3)); this.addAbility(new LoyaltyAbility(new ElspethResplendentLookEffect(), -3));
// 7: Create five 3/3 white Angel creature tokens with flying. // 7: Create five 3/3 white Angel creature tokens with flying.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new Angel33Token(), 5))); this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new Angel33Token(), 5), -7));
} }
private ElspethResplendent(final ElspethResplendent card) { private ElspethResplendent(final ElspethResplendent card) {
@ -113,7 +113,7 @@ class ElspethResplendentLookEffect extends OneShotEffect {
ElspethResplendentLookEffect() { ElspethResplendentLookEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "look at the top seven cards of your library. You may put a permanent card" + staticText = "look at the top seven cards of your library. You may put a permanent card " +
"with mana value 3 or less from among them onto the battlefield with a shield counter on it. " + "with mana value 3 or less from among them onto the battlefield with a shield counter on it. " +
"Put the rest on the bottom of your library in a random order"; "Put the rest on the bottom of your library in a random order";
} }

View file

@ -3,6 +3,7 @@ package mage.cards.e;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CopyTargetSpellEffect; import mage.abilities.effects.common.CopyTargetSpellEffect;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
@ -54,6 +55,7 @@ public final class ErrantStreetArtist extends CardImpl {
// {1}{U}, {T}: Copy target spell you control that wasn't cast. You may choose new targets for the copy. // {1}{U}, {T}: Copy target spell you control that wasn't cast. You may choose new targets for the copy.
Ability ability = new SimpleActivatedAbility(new CopyTargetSpellEffect(), new ManaCostsImpl<>("{1}{U}")); Ability ability = new SimpleActivatedAbility(new CopyTargetSpellEffect(), new ManaCostsImpl<>("{1}{U}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetSpell(filter)); ability.addTarget(new TargetSpell(filter));
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -57,4 +57,9 @@ enum EvenTheScoreCondition implements Condition {
.mapToInt(game.getState().getWatcher(CardsDrawnThisTurnWatcher.class)::getCardsDrawnThisTurn) .mapToInt(game.getState().getWatcher(CardsDrawnThisTurnWatcher.class)::getCardsDrawnThisTurn)
.anyMatch(x -> x >= 4); .anyMatch(x -> x >= 4);
} }
@Override
public String toString() {
return "an opponent has drawn four or more cards this turn";
}
} }

View file

@ -2,7 +2,7 @@ package mage.cards.e;
import mage.ApprovingObject; import mage.ApprovingObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
@ -34,7 +34,7 @@ public final class EvolvingDoor extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{G}");
// {1}, {T}, Sacrifice a creature: Count the colors of the sacrificed creature, then search your library for a creature card that's exactly that many colors plus one. Exile that card, then shuffle. You may cast the exiled card. Activate only as a sorcery. // {1}, {T}, Sacrifice a creature: Count the colors of the sacrificed creature, then search your library for a creature card that's exactly that many colors plus one. Exile that card, then shuffle. You may cast the exiled card. Activate only as a sorcery.
Ability ability = new SimpleActivatedAbility(new EvolvingDoorEffect(), new GenericManaCost(1)); Ability ability = new ActivateAsSorceryActivatedAbility(new EvolvingDoorEffect(), new GenericManaCost(1));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
this.addAbility(ability); this.addAbility(ability);

View file

@ -37,7 +37,7 @@ public final class FatalGrudge extends CardImpl {
this.getSpellAbility().addEffect(new FatalGrudgeEffect()); this.getSpellAbility().addEffect(new FatalGrudgeEffect());
// Draw a card. // Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("<br>"));
} }
private FatalGrudge(final FatalGrudge card) { private FatalGrudge(final FatalGrudge card) {

View file

@ -46,7 +46,7 @@ public final class FightRigging extends CardImpl {
TargetController.YOU, false TargetController.YOU, false
); );
ability.addEffect(new ConditionalOneShotEffect( ability.addEffect(new ConditionalOneShotEffect(
new HideawayPlayEffect(), condition, "then if you control a creature " + new HideawayPlayEffect(), condition, "Then if you control a creature " +
"with power 7 or greater, you may play the exiled card without paying its mana cost" "with power 7 or greater, you may play the exiled card without paying its mana cost"
)); ));
ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetControlledCreaturePermanent());

View file

@ -29,7 +29,7 @@ public final class GlamorousOutlaw extends CardImpl {
// When Glamorous Outlaw enters the battlefield, it deals 2 damage to each opponent and you scry 2. // When Glamorous Outlaw enters the battlefield, it deals 2 damage to each opponent and you scry 2.
Ability ability = new EntersBattlefieldTriggeredAbility( Ability ability = new EntersBattlefieldTriggeredAbility(
new DamagePlayersEffect(2, TargetController.OPPONENT) new DamagePlayersEffect(2, TargetController.OPPONENT, "it")
); );
ability.addEffect(new ScryEffect(2, false).concatBy("and you")); ability.addEffect(new ScryEffect(2, false).concatBy("and you"));
this.addAbility(ability); this.addAbility(ability);

View file

@ -13,7 +13,7 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID; import java.util.UUID;
@ -36,7 +36,7 @@ public final class GraveyardShift extends CardImpl {
// Return target creature card from your graveyard to the battlefield. // Return target creature card from your graveyard to the battlefield.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect());
this.getSpellAbility().addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
} }
private GraveyardShift(final GraveyardShift card) { private GraveyardShift(final GraveyardShift card) {

View file

@ -25,7 +25,7 @@ public final class HypnoticGrifter extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// {3}: Hypnotic Grifter connives. // {3}: Hypnotic Grifter connives.
this.addAbility(new SimpleActivatedAbility(new ConniveSourceEffect(), new GenericManaCost(3))); this.addAbility(new SimpleActivatedAbility(new ConniveSourceEffect("{this}"), new GenericManaCost(3)));
} }
private HypnoticGrifter(final HypnoticGrifter card) { private HypnoticGrifter(final HypnoticGrifter card) {

View file

@ -12,6 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetAttackingOrBlockingCreature; import mage.target.common.TargetAttackingOrBlockingCreature;
@ -23,7 +24,7 @@ import java.util.UUID;
public final class KnockoutBlow extends CardImpl { public final class KnockoutBlow extends CardImpl {
private static final FilterPermanent filter private static final FilterPermanent filter
= new FilterPermanent("a red permanent"); = new FilterCreaturePermanent("a red creature");
static { static {
filter.add(new ColorPredicate(ObjectColor.RED)); filter.add(new ColorPredicate(ObjectColor.RED));

View file

@ -29,7 +29,7 @@ public final class LedgerShredder extends CardImpl {
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// Whenever a player casts their second spell each turn, Ledger Shredder connives. // Whenever a player casts their second spell each turn, Ledger Shredder connives.
this.addAbility(new CastSecondSpellTriggeredAbility(new ConniveSourceEffect(), TargetController.ANY)); this.addAbility(new CastSecondSpellTriggeredAbility(new ConniveSourceEffect("{this}"), TargetController.ANY));
} }
private LedgerShredder(final LedgerShredder card) { private LedgerShredder(final LedgerShredder card) {

View file

@ -42,7 +42,7 @@ public final class MaestrosTheater extends CardImpl {
), false); ), false);
ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), null, false ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
))); )));
} }

View file

@ -73,7 +73,7 @@ class ObNixilisTheAdversaryCasualtyAbility extends StaticAbility {
public ObNixilisTheAdversaryCasualtyAbility(Card card) { public ObNixilisTheAdversaryCasualtyAbility(Card card) {
super(Zone.ALL, new InfoEffect( super(Zone.ALL, new InfoEffect(
"Casualty X. <i>(As you cast this spell, " + "Casualty X. The copy isn't legendary and has starting loyalty X. <i>(As you cast this spell, " +
"you may sacrifice a creature with power X. " + "you may sacrifice a creature with power X. " +
"When you do, copy this spell. The copy becomes a token.)</i>" "When you do, copy this spell. The copy becomes a token.)</i>"
)); ));

View file

@ -9,6 +9,7 @@ import mage.abilities.keyword.LifelinkAbility;
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.Duration;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.UUID; import java.util.UUID;
@ -30,9 +31,9 @@ public final class ObscuraInitiate extends CardImpl {
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// {1}{W/B}: Obscura Initiate gains lifelink until end of turn. // {1}{W/B}: Obscura Initiate gains lifelink until end of turn.
this.addAbility(new SimpleActivatedAbility( this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect(
new GainAbilitySourceEffect(LifelinkAbility.getInstance()), new ManaCostsImpl<>("{1}{W/B}") LifelinkAbility.getInstance(), Duration.EndOfTurn
)); ), new ManaCostsImpl<>("{1}{W/B}")));
} }
private ObscuraInitiate(final ObscuraInitiate card) { private ObscuraInitiate(final ObscuraInitiate card) {

View file

@ -38,7 +38,7 @@ public final class ObscuraInterceptor extends CardImpl {
// When Obscura Interceptor enters the battlefield, it connives. When it connives this way, return up to one target spell to its owner's hand. // When Obscura Interceptor enters the battlefield, it connives. When it connives this way, return up to one target spell to its owner's hand.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnToHandTargetEffect(), false); ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnToHandTargetEffect(), false);
ability.addTarget(new TargetSpell(0, 1, StaticFilters.FILTER_SPELL)); ability.addTarget(new TargetSpell(0, 1, StaticFilters.FILTER_SPELL));
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConniveSourceEffect(ability))); this.addAbility(new EntersBattlefieldTriggeredAbility(new ConniveSourceEffect("it", ability)));
} }
private ObscuraInterceptor(final ObscuraInterceptor card) { private ObscuraInterceptor(final ObscuraInterceptor card) {

View file

@ -42,7 +42,7 @@ public final class ObscuraStorefront extends CardImpl {
), false); ), false);
ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), null, false ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
))); )));
} }

View file

@ -29,7 +29,7 @@ public final class PsychicPickpocket extends CardImpl {
// When Psychic Pickpocket enters the battlefield, it connives. When it connives this way, return up to one target nonland permanent to its owner's hand. // When Psychic Pickpocket enters the battlefield, it connives. When it connives this way, return up to one target nonland permanent to its owner's hand.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnToHandTargetEffect(), false); ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnToHandTargetEffect(), false);
ability.addTarget(new TargetNonlandPermanent(0, 1)); ability.addTarget(new TargetNonlandPermanent(0, 1));
this.addAbility(new EntersBattlefieldTriggeredAbility(new ConniveSourceEffect(ability))); this.addAbility(new EntersBattlefieldTriggeredAbility(new ConniveSourceEffect("it", ability)));
} }
private PsychicPickpocket(final PsychicPickpocket card) { private PsychicPickpocket(final PsychicPickpocket card) {

View file

@ -30,7 +30,7 @@ public final class QuezaAugurOfAgonies extends CardImpl {
// Whenever you draw a card, target opponent loses 1 life and you gain 1 life. // Whenever you draw a card, target opponent loses 1 life and you gain 1 life.
Ability ability = new DrawCardControllerTriggeredAbility(new LoseLifeTargetEffect(1), false); Ability ability = new DrawCardControllerTriggeredAbility(new LoseLifeTargetEffect(1), false);
ability.addEffect(new GainLifeEffect(1)); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
ability.addTarget(new TargetOpponent()); ability.addTarget(new TargetOpponent());
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -9,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.ObjectSourcePlayerPredicate;
@ -25,7 +26,7 @@ import java.util.UUID;
public final class RiveteersAscendancy extends CardImpl { public final class RiveteersAscendancy extends CardImpl {
private static final FilterCard filter private static final FilterCard filter
= new FilterCreatureCard("creature card with lesser mana value from your graveyard "); = new FilterCreatureCard("creature card with lesser mana value from your graveyard");
static { static {
filter.add(RiveteersAscendancyPredicate.instance); filter.add(RiveteersAscendancyPredicate.instance);
@ -36,7 +37,8 @@ public final class RiveteersAscendancy extends CardImpl {
// Whenever you sacrifice a creature, you may return target creature card with lesser mana value from your graveyard to the battlefield tapped. Do this only once each turn. // Whenever you sacrifice a creature, you may return target creature card with lesser mana value from your graveyard to the battlefield tapped. Do this only once each turn.
Ability ability = new SacrificePermanentTriggeredAbility( Ability ability = new SacrificePermanentTriggeredAbility(
new ReturnFromGraveyardToBattlefieldTargetEffect(true) new ReturnFromGraveyardToBattlefieldTargetEffect(true),
StaticFilters.FILTER_PERMANENT_A_CREATURE
).setDoOnlyOnce(true); ).setDoOnlyOnce(true);
ability.addTarget(new TargetCardInYourGraveyard(filter)); ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability); this.addAbility(ability);

View file

@ -42,7 +42,7 @@ public final class RiveteersOverlook extends CardImpl {
), false); ), false);
ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), null, false ability, new SacrificeSourceCost().setText("sacrifice it"), null, false
))); )));
} }

View file

@ -59,7 +59,7 @@ public final class SanctuaryWarden extends CardImpl {
new DoIfCostPaid( new DoIfCostPaid(
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),
new RemoveCounterCost(new TargetControlledPermanent(filter)) new RemoveCounterCost(new TargetControlledPermanent(filter))
).addEffect(new CreateTokenEffect(new CitizenGreenWhiteToken())) ).addEffect(new CreateTokenEffect(new CitizenGreenWhiteToken()).concatBy("and"))
)); ));
} }

View file

@ -42,7 +42,7 @@ public final class StickyFingers extends CardImpl {
// Enchanted creature has menace and "Whenever this creature deals combat damage to a player, create a Treasure token. // Enchanted creature has menace and "Whenever this creature deals combat damage to a player, create a Treasure token.
Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect(new MenaceAbility(false), AttachmentType.AURA)); Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect(new MenaceAbility(false), AttachmentType.AURA));
ability.addEffect(new GainAbilityAttachedEffect(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenEffect(new TreasureToken()), false), AttachmentType.AURA) ability.addEffect(new GainAbilityAttachedEffect(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenEffect(new TreasureToken()), false), AttachmentType.AURA)
.setText("and \"Whenever this creature deals combat damage to a player, create a Treasure token. <i>(It creature can't be blocked except by two or more creatures. The token is an artiface with \"{T}, Sacrifice this artifact: Add one mana of any color.\")</i>")); .setText("and \"Whenever this creature deals combat damage to a player, create a Treasure token.\" <i>(It can't be blocked except by two or more creatures. The token is an artifact with \"{T}, Sacrifice this artifact: Add one mana of any color.\")</i>"));
this.addAbility(ability); this.addAbility(ability);
// When enchanted creature dies, draw a card. // When enchanted creature dies, draw a card.

View file

@ -19,7 +19,7 @@ import java.util.UUID;
*/ */
public final class StimulusPackage extends CardImpl { public final class StimulusPackage extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TREASURE); private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.TREASURE, "a Treasure");
public StimulusPackage(UUID ownerId, CardSetInfo setInfo) { public StimulusPackage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{G}");

View file

@ -62,7 +62,7 @@ public class VerifyCardDataTest {
private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class); private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class);
private static final String FULL_ABILITIES_CHECK_SET_CODE = "FUT"; // check all abilities and output cards with wrong abilities texts; private static final String FULL_ABILITIES_CHECK_SET_CODE = "SNC"; // check all abilities and output cards with wrong abilities texts;
private static final boolean AUTO_FIX_SAMPLE_DECKS = false; // debug only: auto-fix sample decks by test_checkSampleDecks test run private static final boolean AUTO_FIX_SAMPLE_DECKS = false; // debug only: auto-fix sample decks by test_checkSampleDecks test run
private static final boolean ONLY_TEXT = false; // use when checking text locally, suppresses unnecessary checks and output messages private static final boolean ONLY_TEXT = false; // use when checking text locally, suppresses unnecessary checks and output messages

View file

@ -128,11 +128,18 @@ public class RemoveCounterCost extends CostImpl {
private String setText() { private String setText() {
StringBuilder sb = new StringBuilder("remove "); StringBuilder sb = new StringBuilder("remove ");
if (counterTypeToRemove != null) { if (counterTypeToRemove != null) {
sb.append(CardUtil.numberToText(countersToRemove, counterTypeToRemove.getArticle())).append(' ').append(counterTypeToRemove.getName()); sb.append(CardUtil.numberToText(countersToRemove, counterTypeToRemove.getArticle()));
sb.append(' ');
sb.append(counterTypeToRemove.getName());
} else { } else {
sb.append(CardUtil.numberToText(countersToRemove, "a")); sb.append(CardUtil.numberToText(countersToRemove, "a"));
} }
sb.append(countersToRemove == 1 ? " counter from " : " counters from ").append(target.getMaxNumberOfTargets() == 1 ? "a " : "").append(target.getTargetName()); sb.append(countersToRemove > 1 ? " counters from " : " counter from ");
if (target.getMaxNumberOfTargets() > 1) {
sb.append(target.getTargetName());
} else {
sb.append(CardUtil.addArticle(target.getTargetName()));
}
return sb.toString(); return sb.toString();
} }

View file

@ -57,7 +57,8 @@ public class UntapTargetCost extends CostImpl {
StringBuilder sb = new StringBuilder("untap "); StringBuilder sb = new StringBuilder("untap ");
if (target.getMaxNumberOfTargets() > 1) { if (target.getMaxNumberOfTargets() > 1) {
sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets())); sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets()));
sb.append(target.getTargetName().replace("you control", "s you control")); sb.append(' ');
sb.append(target.getTargetName().replace(" you control", "s you control"));
} else { } else {
sb.append(CardUtil.addArticle(target.getTargetName())); sb.append(CardUtil.addArticle(target.getTargetName()));
} }

View file

@ -19,7 +19,7 @@ public class HideawayPlayEffect extends OneShotEffect {
public HideawayPlayEffect() { public HideawayPlayEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "You may play the exiled card without paying its mana cost"; staticText = "you may play the exiled card without paying its mana cost";
} }
public HideawayPlayEffect(final HideawayPlayEffect effect) { public HideawayPlayEffect(final HideawayPlayEffect effect) {

View file

@ -12,7 +12,7 @@ import mage.players.Player;
*/ */
public class MillHalfLibraryTargetEffect extends OneShotEffect { public class MillHalfLibraryTargetEffect extends OneShotEffect {
private static boolean roundUp; private final boolean roundUp;
public MillHalfLibraryTargetEffect(boolean roundUp) { public MillHalfLibraryTargetEffect(boolean roundUp) {
super(Outcome.Benefit); super(Outcome.Benefit);

View file

@ -17,19 +17,26 @@ import mage.util.CardUtil;
*/ */
public class ConniveSourceEffect extends OneShotEffect { public class ConniveSourceEffect extends OneShotEffect {
private final String selfName;
private final ReflexiveTriggeredAbility ability; private final ReflexiveTriggeredAbility ability;
public ConniveSourceEffect() { public ConniveSourceEffect() {
this((ReflexiveTriggeredAbility) null); this("it");
} }
public ConniveSourceEffect(ReflexiveTriggeredAbility ability) { public ConniveSourceEffect(String selfName) {
this(selfName, null);
}
public ConniveSourceEffect(String selfName, ReflexiveTriggeredAbility ability) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.selfName = selfName;
this.ability = ability; this.ability = ability;
} }
private ConniveSourceEffect(final ConniveSourceEffect effect) { private ConniveSourceEffect(final ConniveSourceEffect effect) {
super(effect); super(effect);
this.selfName = effect.selfName;
this.ability = effect.ability; this.ability = effect.ability;
} }
@ -74,10 +81,10 @@ public class ConniveSourceEffect extends OneShotEffect {
return staticText; return staticText;
} }
if (ability == null) { if (ability == null) {
return "it connives. <i>(Draw a card, then discard a card. " + return selfName + " connives. <i>(Draw a card, then discard a card. " +
"If you discarded a nonland card, put a +1/+1 counter on this creature.)</i>"; "If you discarded a nonland card, put a +1/+1 counter on this creature.)</i>";
} }
return "it connives. When it connives this way, " + return selfName + " connives. When it connives this way, " +
CardUtil.getTextWithFirstCharLowerCase(ability.getRule()) + CardUtil.getTextWithFirstCharLowerCase(ability.getRule()) +
" <i>(To have a creature connive, draw a card, then discard a card. " + " <i>(To have a creature connive, draw a card, then discard a card. " +
"If you discarded a nonland card, put a +1/+1 counter on that creature.)</i>"; "If you discarded a nonland card, put a +1/+1 counter on that creature.)</i>";

View file

@ -56,7 +56,7 @@ public class ConniveTargetEffect extends OneShotEffect {
sb.append(", where X is "); sb.append(", where X is ");
sb.append(xValue.getMessage()); sb.append(xValue.getMessage());
} }
sb.append("<i>(Draw "); sb.append(" <i>(Draw ");
sb.append(xValue); sb.append(xValue);
sb.append(" cards, then discard "); sb.append(" cards, then discard ");
sb.append(xValue); sb.append(xValue);