[FIN] various text fixes

This commit is contained in:
theelk801 2025-05-30 21:27:14 -04:00
parent bf487046e1
commit 9ef2aac469
54 changed files with 222 additions and 141 deletions

View file

@ -75,8 +75,8 @@ class ArdynTheUsurperEffect extends OneShotEffect {
ArdynTheUsurperEffect() {
super(Outcome.Benefit);
staticText = "at the beginning of combat on your turn, exile up to one target creature card from a graveyard. " +
"If you exiled a card this way, create a token that's a copy of that card, except it's a 5/5 black Demon";
staticText = "exile up to one target creature card from a graveyard. If you exiled a card this way, " +
"create a token that's a copy of that card, except it's a 5/5 black Demon";
}
private ArdynTheUsurperEffect(final ArdynTheUsurperEffect effect) {

View file

@ -49,7 +49,8 @@ public final class BarretWallace extends CardImpl {
// Whenever Barret Wallace attacks, it deals damage equal to the number of equipped creatures you control to defending player.
this.addAbility(new AttacksTriggeredAbility(
new DamageTargetEffect(xValue, true, "it", true),
new DamageTargetEffect(xValue, true, "it", true)
.setText("it deals damage equal to the number of equipped creatures you control to defending player"),
false, null, SetTargetPointer.PLAYER
).withRuleTextReplacement(true).addHint(hint));
}

View file

@ -39,7 +39,9 @@ public final class BlazingBomb extends CardImpl {
// Blow Up -- {T}, Sacrifice this creature: It deals damage equal to its power to target creature. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
new DamageTargetEffect(SourcePermanentPowerValue.NOT_NEGATIVE, "it"), new TapSourceCost()
new DamageTargetEffect(SourcePermanentPowerValue.NOT_NEGATIVE)
.setText("it deals damage equal to its power to target creature"),
new TapSourceCost()
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreaturePermanent());

View file

@ -1,10 +1,10 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageEquippedTriggeredAbility;
import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
@ -36,7 +36,9 @@ public final class BusterSword extends CardImpl {
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(3, 2)));
// Whenever equipped creature deals combat damage to a player, draw a card, then you may cast a spell from your hand with mana value less than or equal to that damage without paying its mana cost.
Ability ability = new DealsCombatDamageEquippedTriggeredAbility(new DrawCardTargetEffect(1));
Ability ability = new DealsDamageToAPlayerAttachedTriggeredAbility(
new DrawCardSourceControllerEffect(1), "equipped", false
);
ability.addEffect(new BusterSwordEffect());
this.addAbility(ability);

View file

@ -38,7 +38,9 @@ public final class ChocoSeekerOfParadise extends CardImpl {
this.toughness = new MageInt(5);
// Whenever one or more Birds you control attack, look at that many cards from the top of your library. You may put one of them into your hand. Then put any number of land cards from among them onto the battlefield tapped and the rest into your graveyard.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new ChocoSeekerOfParadiseEffect(), 1, filter));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(
new ChocoSeekerOfParadiseEffect(), 1, filter
).setTriggerPhrase("Whenever one or more Birds you control attack, "));
// Landfall -- Whenever a land you control enters, Choco gets +1/+0 until end of turn.
this.addAbility(new LandfallAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn)));

View file

@ -38,7 +38,8 @@ public final class CliveIfritsDominant extends CardImpl {
// When Clive enters, you may discard your hand, then draw cards equal to your devotion to red.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardHandControllerEffect(), true);
ability.addEffect(new DrawCardSourceControllerEffect(DevotionCount.R).concatBy(", then"));
ability.addEffect(new DrawCardSourceControllerEffect(DevotionCount.R)
.setText(", then draw cards equal to your devotion to red"));
this.addAbility(ability.addHint(DevotionCount.R.getHint()));
// {4}{R}{R}, {T}: Exile Clive, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery.

View file

@ -30,7 +30,7 @@ public final class CrystallizedSerah extends CardImpl {
// Legendary creatures you control get +2/+2.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
2, 2, Duration.WhileControlled, StaticFilters.FILTER_CREATURES_LEGENDARY
2, 2, Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURES_LEGENDARY
)));
}

View file

@ -19,7 +19,7 @@ public final class EvilReawakened extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}");
// Return target creature card from your graveyard to the battlefield with two additional +1/+1 counters on it.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(true, CounterType.P1P1.createInstance()));
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(true, CounterType.P1P1.createInstance(2)));
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
}

View file

@ -33,7 +33,9 @@ public final class FangFearlessLCie extends CardImpl {
this.meldsToClazz = mage.cards.r.RagnarokDivineDeliverance.class;
// Whenever one or more cards leave your graveyard, you draw a card and you lose 1 life. This ability triggers only once each turn.
Ability ability = new CardsLeaveGraveyardTriggeredAbility(new DrawCardSourceControllerEffect(1, true));
Ability ability = new CardsLeaveGraveyardTriggeredAbility(
new DrawCardSourceControllerEffect(1, true)
).setTriggersLimitEachTurn(1);
ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and"));
this.addAbility(ability);

View file

@ -24,7 +24,7 @@ public final class FireMagic extends CardImpl {
// * Fire -- {0} -- Fire Magic deals 1 damage to each creature.
this.getSpellAbility().addEffect(new DamageAllEffect(1, StaticFilters.FILTER_PERMANENT_CREATURE));
this.getSpellAbility().withFirstModeCost(new GenericManaCost(1));
this.getSpellAbility().withFirstModeCost(new GenericManaCost(0));
this.getSpellAbility().withFirstModeFlavorWord("Fire");
// * Fira -- {2} -- Fire Magic deals 2 damage to each creature.

View file

@ -1,16 +1,19 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalAsThoughEffect;
import mage.abilities.effects.common.replacement.GraveyardFromAnywhereExileReplacementEffect;
import mage.abilities.effects.common.ruleModifying.PlayFromGraveyardControllerEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author balazskristof
@ -19,7 +22,7 @@ public final class HadesSorcererOfEld extends CardImpl {
public HadesSorcererOfEld(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.AVATAR);
this.power = new MageInt(6);
@ -33,7 +36,9 @@ public final class HadesSorcererOfEld extends CardImpl {
this.addAbility(VigilanceAbility.getInstance());
// Echo of the Lost -- During your turn you may play cards from your graveyard.
this.addAbility(new SimpleStaticAbility(PlayFromGraveyardControllerEffect.playCards()).withFlavorWord("Echo of the Lost"));
this.addAbility(new SimpleStaticAbility(new ConditionalAsThoughEffect(
PlayFromGraveyardControllerEffect.playCards(), MyTurnCondition.instance
).setText("during your turn, you may play cards from your graveyard")).withFlavorWord("Echo of the Lost"));
// If a card or token would be put into your graveyard from anywhere, exile it instead.
this.addAbility(new SimpleStaticAbility(new GraveyardFromAnywhereExileReplacementEffect(true, true)));

View file

@ -28,7 +28,7 @@ public final class IceMagic extends CardImpl {
// * Blizzard -- {0} -- Return target creature to its owner's hand.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().withFirstModeCost(new GenericManaCost(2));
this.getSpellAbility().withFirstModeCost(new GenericManaCost(0));
this.getSpellAbility().withFirstModeFlavorWord("Blizzard");
// * Blizzara -- {2} -- Target creature's owner puts it on their choice of the top or bottom of their library.

View file

@ -50,10 +50,11 @@ public final class IfritWardenOfInferno extends CardImpl {
// II, III -- Brimstone -- Add {R}{R}{R}{R}. If Ifrit has three or more lore counters on it, exile it, then return it to the battlefield
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_III, ability -> {
ability.addEffect(new BasicManaEffect(Mana.RedMana(5)));
ability.addEffect(new BasicManaEffect(Mana.RedMana(4)));
ability.addEffect(new ConditionalOneShotEffect(
new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD), condition,
"If {this} has three or more lore counters on it, exile it, then return it to the battlefield"
"If {this} has three or more lore counters on it, exile it, " +
"then return it to the battlefield <i>(front face up.)</i>."
));
ability.withFlavorWord("Brimstone");
});

View file

@ -63,7 +63,7 @@ class KainTraitorousDragoonEffect extends OneShotEffect {
KainTraitorousDragoonEffect() {
super(Outcome.Benefit);
staticText = ", that player gains control of {this}. If they do, you draw that many cards, " +
staticText = "that player gains control of {this}. If they do, you draw that many cards, " +
"create that many tapped Treasure tokens, then lose that much life";
}

View file

@ -38,7 +38,7 @@ public final class MachinistsArsenal extends CardImpl {
.setText("equipped creature gets +2/+2 for each artifact you control"));
ability.addEffect(new AddCardSubtypeAttachedEffect(
SubType.ARTIFICER, AttachmentType.EQUIPMENT
).setText(", and is a Artificer in addition to its other types"));
).setText("and is an Artificer in addition to its other types"));
this.addAbility(ability.addHint(ArtifactYouControlHint.instance));
// Machina -- Equip {4}

View file

@ -32,6 +32,7 @@ public final class MonksFist extends CardImpl {
ability.addEffect(new AddCardSubtypeAttachedEffect(
SubType.MONK, AttachmentType.EQUIPMENT
).setText("and is a Monk in addition to its other types"));
this.addAbility(ability);
// Equip {2}
this.addAbility(new EquipAbility(2));

View file

@ -2,10 +2,10 @@ package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -15,7 +15,6 @@ import mage.game.Game;
import mage.game.events.DieRolledEvent;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
@ -79,6 +78,7 @@ class NetheresePuzzleWardTriggeredAbility extends TriggeredAbilityImpl {
NetheresePuzzleWardTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1));
this.withFlavorWord("Perfect Illumination");
this.setTriggerPhrase("Whenever you roll a die's highest natural result, ");
}
private NetheresePuzzleWardTriggeredAbility(final NetheresePuzzleWardTriggeredAbility ability) {
@ -101,10 +101,4 @@ class NetheresePuzzleWardTriggeredAbility extends TriggeredAbilityImpl {
public NetheresePuzzleWardTriggeredAbility copy() {
return new NetheresePuzzleWardTriggeredAbility(this);
}
@Override
public String getRule() {
return CardUtil.italicizeWithEmDash(flavorWord)
+ "Whenever you roll a die's highest natural result, draw a card.";
}
}

View file

@ -52,7 +52,7 @@ public final class OmegaHeartlessEvolution extends CardImpl {
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance(), xValue)
.setTargetPointer(new EachTargetPointer())
.setText("Put X stun counters on each of those permanents"));
ability.addEffect(new GainLifeEffect(xValue).concatBy("and"));
ability.addEffect(new GainLifeEffect(xValue).setText("and you gain X life, where X is the number of nonbasic lands you control"));
ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_NON_LAND));
this.addAbility(ability.withFlavorWord("Wave Cannon").setTargetAdjuster(new ForEachOpponentTargetsAdjuster()));
}

View file

@ -1,11 +1,11 @@
package mage.cards.p;
import mage.MageInt;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.PlayCardTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -57,7 +57,7 @@ class ProsperTomeBoundTriggeredAbility extends PlayCardTriggeredAbility {
ProsperTomeBoundTriggeredAbility() {
super(TargetController.YOU, Zone.BATTLEFIELD, new CreateTokenEffect(new TreasureToken()));
this.flavorWord = "Pact Boon";
this.withFlavorWord("Pact Boon");
setTriggerPhrase("Whenever you play a card from exile, ");
}

View file

@ -36,7 +36,7 @@ public final class QuistisTrepe extends CardImpl {
Ability ability = new EntersBattlefieldTriggeredAbility(
new MayCastTargetCardEffect(CastManaAdjustment.AS_THOUGH_ANY_MANA_TYPE, true)
);
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter));
ability.addTarget(new TargetCardInGraveyard(filter));
this.addAbility(ability.withFlavorWord("Blue Magic"));
}

View file

@ -35,7 +35,7 @@ public final class RaubahnBullOfAlaMhigo extends CardImpl {
// Ward--Pay life equal to Raubahn's power.
this.addAbility(new WardAbility(new PayLifeCost(
SourcePermanentPowerValue.NOT_NEGATIVE, "Pay life equal to {this}'s power"
SourcePermanentPowerValue.NOT_NEGATIVE, "life equal to {this}'s power"
)));
// Whenever Raubahn attacks, attach up to one target Equipment you control to target attacking creature.

View file

@ -56,7 +56,7 @@ class RenoAndRudeEffect extends OneShotEffect {
RenoAndRudeEffect() {
super(Outcome.Benefit);
staticText = ", exile the top card of that player's library. " +
staticText = "exile the top card of that player's library. " +
"Then you may sacrifice another creature or artifact. If you do, " +
"you may play the exiled card this turn, and mana of any type can be spent to cast it";
}

View file

@ -38,7 +38,7 @@ public final class SagesNouliths extends CardImpl {
triggeredAbility.addTarget(new TargetAttackingCreature());
ability.addEffect(new GainAbilityAttachedEffect(
triggeredAbility, AttachmentType.EQUIPMENT
).setText("has \"Whenever this creature attacks, untap target attacking creature,\""));
).setText(", has \"Whenever this creature attacks, untap target attacking creature,\""));
ability.addEffect(new AddCardSubtypeAttachedEffect(
SubType.CLERIC, AttachmentType.EQUIPMENT
).setText("and is a Cleric in addition to its other types"));

View file

@ -16,6 +16,7 @@ import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -47,13 +48,14 @@ public final class SazhKatzroy extends CardImpl {
// When Sazh Katzroy enters, you may search your library for a Bird or basic land card, reveal it, put it into your hand, then shuffle.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true)
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), true
));
// Whenever Sazh Katzroy attacks, put counter on target creature, then double the number of +1/+1 counters on that creature.
Ability ability = new AttacksTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addEffect(new DoubleCountersTargetEffect(CounterType.P1P1)
.setText(", then double the number of +1/+1 counters on that creature"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -13,6 +13,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.common.TargetOpponent;
import mage.watchers.common.AbilityResolvedWatcher;
import java.util.UUID;
@ -47,6 +48,7 @@ public final class SephirothFabledSOLDIER extends CardImpl {
);
ability.addEffect(new GainLifeEffect(1).concatBy("and"));
ability.addEffect(new IfAbilityHasResolvedXTimesEffect(4, new TransformSourceEffect()));
ability.addTarget(new TargetOpponent());
this.addAbility(ability, new AbilityResolvedWatcher());
}

View file

@ -47,7 +47,7 @@ public final class ShantottoTacticianMagician extends CardImpl {
ability.addEffect(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1),
ShantottoTacticianMagicianCondition.instance,
"If X is 4 or greater, draw a card"
"If X is 4 or more, draw a card"
));
this.addAbility(ability);
}

View file

@ -59,8 +59,7 @@ class StolenUniformAttachEffect extends OneShotEffect {
StolenUniformAttachEffect() {
super(Outcome.Benefit);
staticText = "Attach it to the chosen creature. When you lose control of that Equipment this turn, " +
"if it's attached to a creature you control, unattach it";
staticText = "Attach it to the chosen creature";
this.setTargetPointer(new EachTargetPointer());
}

View file

@ -47,7 +47,9 @@ public final class SummonEsperRamuh extends CardImpl {
// I -- Judgment Bolt -- This creature deals damage equal to the number of noncreature, nonland cards in your graveyard to target creature an opponent controls.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> {
ability.addEffect(new DamageTargetEffect(xValue));
ability.addEffect(new DamageTargetEffect(xValue)
.setText("{this} deals damage equal to the number of noncreature, nonland " +
"cards in your graveyard to target creature an opponent controls"));
ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.withFlavorWord("Judgment Bolt");
});

View file

@ -44,7 +44,7 @@ public final class SummonFenrir extends CardImpl {
// I -- Crescent Fang -- Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> {
ability.addEffect(new SearchLibraryPutInPlayEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true, true
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
));
ability.withFlavorWord("Crescent Fang");
});

View file

@ -35,11 +35,14 @@ public final class SummonKnightsOfRound extends CardImpl {
SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_V);
// I, II, III, IV -- Create three 2/2 white Knight creature tokens.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_IV, new CreateTokenEffect(new WaylayToken()));
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_IV,
new CreateTokenEffect(new WaylayToken(), 3)
);
// V -- Ultimate End -- Other creatures you control get +2/+2 until end of turn. Put an indestructible counter on each of them.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_V, ability -> {
ability.addEffect(new BoostControlledEffect(2, 2, Duration.EndOfTurn));
ability.addEffect(new BoostControlledEffect(2, 2, Duration.EndOfTurn, true));
ability.addEffect(new AddCountersAllEffect(
CounterType.INDESTRUCTIBLE.createInstance(),
StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES

View file

@ -47,7 +47,7 @@ public final class SummonPrimalOdin extends CardImpl {
new DealsCombatDamageToAPlayerTriggeredAbility(
new LoseGameTargetPlayerEffect(), false, true
), Duration.Custom
));
).setText("{this} gains \"Whenever this creature deals combat damage to a player, that player loses the game.\""));
ability.withFlavorWord("Zantetsuken");
});

View file

@ -47,7 +47,7 @@ public final class TheFireCrystal extends CardImpl {
// Creatures you control have haste.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
HasteAbility.getInstance(), Duration.WhileControlled,
HasteAbility.getInstance(), Duration.WhileOnBattlefield,
StaticFilters.FILTER_PERMANENT_CREATURES
)));

View file

@ -14,7 +14,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.permanent.token.custom.CreatureToken;
import mage.game.permanent.token.TreasureToken;
import java.util.UUID;
@ -33,13 +33,13 @@ public final class TheGoldSaucer extends CardImpl {
// {2}, {T}: Flip a coin. If you win the flip, create a Treasure token.
Ability ability = new SimpleActivatedAbility(
new FlipCoinEffect(new CreateTokenEffect(new CreatureToken())), new GenericManaCost(2)
new FlipCoinEffect(new CreateTokenEffect(new TreasureToken())), new GenericManaCost(2)
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {3}, {T}, Sacrifice two artifacts: Draw a card.
ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(2), new GenericManaCost(3));
ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_ARTIFACTS));
this.addAbility(ability);

View file

@ -36,7 +36,7 @@ public final class TifaLockhart extends CardImpl {
this.addAbility(new LandfallAbility(new BoostSourceEffect(
SourcePermanentPowerValue.ALLOW_NEGATIVE,
StaticValue.get(0), Duration.EndOfTurn
).setText(" double {this}'s power until end of turn")));
).setText("double {this}'s power until end of turn")));
}
private TifaLockhart(final TifaLockhart card) {

View file

@ -66,7 +66,7 @@ class TravelingChocoboEffect extends ReplacementEffectImpl {
TravelingChocoboEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "if land or Bird entering the battlefield causes a triggered ability " +
staticText = "if a land or Bird you control entering the battlefield causes a triggered ability " +
"of a permanent you control to trigger, that ability triggers an additional time";
}
@ -102,6 +102,7 @@ class TravelingChocoboEffect extends ReplacementEffectImpl {
EntersTheBattlefieldEvent entersTheBattlefieldEvent = (EntersTheBattlefieldEvent) sourceEvent;
return (entersTheBattlefieldEvent.getTarget().isLand(game)
|| entersTheBattlefieldEvent.getTarget().hasSubtype(SubType.BIRD, game))
&& entersTheBattlefieldEvent.getTarget().isControlledBy(source.getControllerId())
&& game.getPermanent(numberOfTriggersEvent.getSourceId()) != null;
}

View file

@ -1,7 +1,7 @@
package mage.cards.u;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.AttacksAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@ -27,7 +27,7 @@ public final class UltimaWeapon extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Whenever equipped creature attacks, destroy target creature an opponent controls.
Ability ability = new AttacksTriggeredAbility(new DestroyTargetEffect());
Ability ability = new AttacksAttachedTriggeredAbility(new DestroyTargetEffect());
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);

View file

@ -31,7 +31,7 @@ public final class WarriorsSword extends CardImpl {
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 2));
ability.addEffect(new AddCardSubtypeAttachedEffect(
SubType.WARRIOR, AttachmentType.EQUIPMENT
).setText(", and is a Warrior in addition to its other types"));
).setText("and is a Warrior in addition to its other types"));
this.addAbility(ability);
// Equip {5}

View file

@ -5,7 +5,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -23,7 +23,7 @@ public final class WorldMap extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {1}, {T}, Sacrifice this artifact: Search your library for a basic land card, reveal it, put it into your hand, then shuffle.
Ability ability = new SimpleActivatedAbility(new SearchLibraryPutInPlayEffect(
Ability ability = new SimpleActivatedAbility(new SearchLibraryPutInHandEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true
), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
@ -31,7 +31,7 @@ public final class WorldMap extends CardImpl {
this.addAbility(ability);
// {3}, {T}, Sacrifice this artifact: Search your library for a land card, reveal it, put it into your hand, then shuffle.
ability = new SimpleActivatedAbility(new SearchLibraryPutInPlayEffect(
ability = new SimpleActivatedAbility(new SearchLibraryPutInHandEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND), true
), new GenericManaCost(3));
ability.addCost(new TapSourceCost());

View file

@ -22,7 +22,7 @@ import java.util.UUID;
*/
public final class XandeDarkMage extends CardImpl {
private static final FilterCard filter = new FilterCard("noncreature, nonland card in your graveyard");
private static final FilterCard filter = new FilterCard("noncreature, nonland card");
static {
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));

View file

@ -11,6 +11,7 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
@ -46,7 +47,7 @@ public final class YiazmatUltimateMark extends CardImpl {
// {1}{B}, Sacrifice another creature or artifact: Yiazmat gains indestructible until end of turn. Tap it.
Ability ability = new SimpleActivatedAbility(
new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), new ManaCostsImpl<>("{1}{B}")
new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl<>("{1}{B}")
);
ability.addCost(new SacrificeTargetCost(filter));
ability.addEffect(new TapSourceEffect().setText("tap it"));

View file

@ -1,21 +1,18 @@
package mage.cards.y;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileThenReturnTargetEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TurnPhase;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.turn.TurnMod;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import java.util.UUID;
/**
* @author balazskristof
@ -24,7 +21,7 @@ public final class YshtolaRhul extends CardImpl {
public YshtolaRhul(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.CAT);
this.subtype.add(SubType.DRUID);
@ -32,9 +29,9 @@ public final class YshtolaRhul extends CardImpl {
this.toughness = new MageInt(5);
// At the beginning of your end step, exile target creature you control, then return it to the battlefield under its owner's control. Then if it's the first end step of the turn, there is an additional end step after this step.
Ability ability = new BeginningOfEndStepTriggeredAbility(new ExileThenReturnTargetEffect(true, false));
Ability ability = new BeginningOfEndStepTriggeredAbility(new ExileThenReturnTargetEffect(false, false));
ability.addTarget(new TargetControlledCreaturePermanent());
ability.addEffect(new YshtolaRhulEffect().concatBy("Then"));
ability.addEffect(new YshtolaRhulEffect());
this.addAbility(ability);
}
@ -51,7 +48,7 @@ public final class YshtolaRhul extends CardImpl {
class YshtolaRhulEffect extends OneShotEffect {
public YshtolaRhulEffect() {
super(Outcome.Benefit);
staticText = "if it's the first end step of the turn, there is an additional end step after this step";
staticText = "Then if it's the first end step of the turn, there is an additional end step after this step";
}
protected YshtolaRhulEffect(final YshtolaRhulEffect effect) {
@ -65,10 +62,10 @@ class YshtolaRhulEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
if (game.getTurn().getPhase(TurnPhase.END).getCount() == 0) {
TurnMod end = new TurnMod(game.getState().getActivePlayerId()).withExtraPhase(TurnPhase.END);
game.getState().getTurnMods().add(end);
if (game.getTurn().getPhase(TurnPhase.END).getCount() != 0) {
return false;
}
game.getState().getTurnMods().add(new TurnMod(game.getState().getActivePlayerId()).withExtraPhase(TurnPhase.END));
return true;
}
}

View file

@ -45,7 +45,7 @@ public final class ZellDincht extends CardImpl {
// At the beginning of your end step, return a land you control to its owner's hand.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
new ReturnToHandChosenControlledPermanentEffect(StaticFilters.FILTER_CONTROLLED_PERMANENT_A_LAND)
new ReturnToHandChosenControlledPermanentEffect(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)
));
}

View file

@ -32,6 +32,7 @@ import mage.constants.*;
import mage.filter.Filter;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.command.Dungeon;
import mage.game.command.Plane;
import mage.game.draft.DraftCube;
@ -70,7 +71,7 @@ public class VerifyCardDataTest {
private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class);
private static final String FULL_ABILITIES_CHECK_SET_CODES = "WHO"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all
private static final String FULL_ABILITIES_CHECK_SET_CODES = "FIN"; // 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
@ -2320,7 +2321,81 @@ public class VerifyCardDataTest {
// TODO: add legality checks (by sets and cards, by banned)
}
private String prepareRule(String cardName, String rule) {
private static final List<SubType> selfRefNamedSubtypes = Arrays.asList(
SubType.EQUIPMENT,
SubType.VEHICLE,
SubType.AURA,
SubType.CLASS,
SubType.SAGA,
SubType.SIEGE
);
private static String applySelfReference(String rule, MageObject mageObject, Game game) {
return rule
.replace("{this}", getCardSelfReference(mageObject, game))
.replace(". this", ". This")
.replace("\nthis", "\nThis")
.replace("-this", "-This")
.replace(": this", ": This")
.replace("&bull this", "&bull This")
.replace("&mdash; this", "&mdash; This")
.replace("&mdash;this", "&mdash;This")
.replace("- this", "- This");
}
/**
* Returns the description of the card for rules text that references itself.
* Applies to abilities that function only on the battlefield.
* Does not account for every exception.
* <a href="https://scryfall.com/blog/errata-notice-aetherdrift-231">Details here</a>
*/
private static String getCardSelfReference(MageObject mageObject, Game game) {
if (!mageObject.isPermanent(game)) {
return mageObject.getName();
}
if (mageObject.isPlaneswalker(game)) {
// try to ref by planeswalker name which is subtype
return mageObject
.getSubtype(game)
.stream()
.filter(SubType.getPlaneswalkerTypes()::contains)
.findFirst()
.map(SubType::getDescription)
.orElse(mageObject.getName());
}
if (mageObject.isLegendary(game)) {
// Generate shortname for legendary permanent (other than planeswalker)
List<String> parts = Arrays.asList(mageObject.getName().split("(, | of the )"));
if (parts.size() > 1) {
return parts.get(0);
} else {
return mageObject.getName();
}
}
if (mageObject.isCreature(game)) {
return "this creature";
}
if (mageObject.isLand(game)) {
return "this land";
}
for (SubType subType : selfRefNamedSubtypes) {
if (mageObject.hasSubtype(subType, game)) {
return "this " + subType.getDescription();
}
}
if (mageObject.isBattle(game)) {
return "this battle";
}
if (mageObject.isEnchantment(game)) {
return "this enchantment";
}
if (mageObject.isArtifact(game)) {
return "this artifact";
}
return "this permanent";
}
private String prepareRule(Card card, String rule) {
// remove and optimize rule text for analyze
String newRule = rule;
@ -2336,8 +2411,7 @@ public class VerifyCardDataTest {
}
// replace special text and symbols
newRule = newRule
.replace("{this}", cardName)
newRule = applySelfReference(newRule, card, null)
.replace("", "-")
.replace("", "-")
.replace("&mdash;", "-");
@ -2349,7 +2423,7 @@ public class VerifyCardDataTest {
newRule = CardNameUtil.normalizeCardName(newRule);
return newRule.trim();
return CardUtil.getTextWithFirstCharUpperCase(newRule.trim());
}
@Test
@ -2582,7 +2656,7 @@ public class VerifyCardDataTest {
String[] refRules = refText.split("[\\$\\\n]"); // ref card's abilities can be splited by \n or $ chars
for (int i = 0; i < refRules.length; i++) {
refRules[i] = prepareRule(card.getName(), refRules[i]);
refRules[i] = prepareRule(card, refRules[i]);
}
if (ref.subtypes.contains("Adventure")) {
@ -2615,7 +2689,7 @@ public class VerifyCardDataTest {
.replace("</b>", "")
.split("[\\$\\\n]");
for (int i = 0; i < cardRules.length; i++) {
cardRules[i] = prepareRule(card.getName(), cardRules[i]);
cardRules[i] = prepareRule(card, cardRules[i]);
}
boolean isFine = true;

View file

@ -474,6 +474,11 @@ public interface Ability extends Controllable, Serializable {
*/
Ability withFlavorWord(String flavorWord);
/**
* Gets rule prefix for text generation
*/
String addRulePrefix(String rule);
/**
* Sets flavor word for first mode
*/

View file

@ -1018,38 +1018,28 @@ public abstract class AbilityImpl implements Ability {
String ruleStart = sbRule.toString();
String text = getModes().getText();
String rule;
StringBuilder rule = new StringBuilder();
if (!text.isEmpty()) {
if (ruleStart.length() > 1) {
String end = ruleStart.substring(ruleStart.length() - 2).trim();
if (end.isEmpty() || end.equals(":") || end.equals(".")) {
rule = ruleStart + CardUtil.getTextWithFirstCharUpperCase(text);
rule.append(ruleStart + CardUtil.getTextWithFirstCharUpperCase(text));
} else {
rule = ruleStart + text;
rule.append(ruleStart + text);
}
} else {
rule = ruleStart + text;
rule.append(ruleStart + text);
}
} else {
rule = ruleStart;
}
String prefix;
if (this instanceof TriggeredAbility || this instanceof EntersBattlefieldAbility) {
prefix = null;
} else if (abilityWord != null) {
prefix = abilityWord.formatWord();
} else if (flavorWord != null) {
prefix = CardUtil.italicizeWithEmDash(flavorWord);
} else {
prefix = null;
}
if (prefix != null) {
rule = prefix + CardUtil.getTextWithFirstCharUpperCase(rule);
rule.append(ruleStart);
}
if (appendToRule != null) {
rule = rule.concat(appendToRule);
rule.append(appendToRule);
}
return rule;
if (this instanceof TriggeredAbility || this instanceof EntersBattlefieldAbility) {
return rule.toString();
}
return addRulePrefix(rule.toString());
}
@Override
@ -1479,6 +1469,17 @@ public abstract class AbilityImpl implements Ability {
return this;
}
@Override
public String addRulePrefix(String rule) {
if (abilityWord != null) {
return abilityWord.formatWord() + CardUtil.getTextWithFirstCharUpperCase(rule);
} else if (flavorWord != null) {
return CardUtil.italicizeWithEmDash(flavorWord) + CardUtil.getTextWithFirstCharUpperCase(rule);
} else {
return rule;
}
}
@Override
public Ability withFirstModeFlavorWord(String flavorWord) {
this.modes.getMode().withFlavorWord(flavorWord);

View file

@ -294,16 +294,6 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
@Override
public String getRule() {
StringBuilder sb = new StringBuilder();
String prefix;
if (abilityWord != null) {
prefix = abilityWord.formatWord();
} else if (flavorWord != null) {
prefix = CardUtil.italicizeWithEmDash(flavorWord);
} else {
prefix = "";
}
sb.append(prefix);
sb.append(triggerPhrase == null ? "" : triggerPhrase);
if (interveningIfCondition != null) {
@ -376,7 +366,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
sb.append(" Do this only once each turn.");
}
}
return sb.toString();
return addRulePrefix(sb.toString());
}
private static boolean startsWithVerb(String ruleLow) {

View file

@ -6,7 +6,6 @@ import mage.abilities.condition.Condition;
import mage.abilities.effects.Effect;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.constants.Zone;
import mage.util.CardUtil;
/**
* @author BetaSteward_at_googlemail.com
@ -81,19 +80,8 @@ public class EntersBattlefieldAbility extends StaticAbility {
return abilityRule;
}
String superRule = super.getRule();
String prefix;
if (abilityWord != null) {
prefix = abilityWord.formatWord();
} else if (flavorWord != null) {
prefix = CardUtil.italicizeWithEmDash(flavorWord);
} else {
prefix = null;
}
String rule = (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s")
+ (!superRule.isEmpty() && superRule.charAt(0) == ' ' ? "" : " ") + superRule;
if (prefix != null) {
return prefix + CardUtil.getTextWithFirstCharUpperCase(rule);
}
return rule;
return addRulePrefix(rule);
}
}

View file

@ -9,10 +9,8 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.hint.Hint;
import mage.constants.EffectType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.ArrayList;
@ -83,9 +81,7 @@ public class ConditionalInterveningIfTriggeredAbility extends TriggeredAbilityIm
if (abilityText == null || abilityText.isEmpty()) {
return ability.getRule();
}
return (flavorWord != null ? CardUtil.italicizeWithEmDash(flavorWord) : "") +
(abilityWord != null ? abilityWord.formatWord() : "") +
abilityText + (abilityText.endsWith(".") || abilityText.endsWith("\"") || abilityText.endsWith(">") ? "" : ".");
return addRulePrefix(abilityText + (abilityText.endsWith(".") || abilityText.endsWith("\"") || abilityText.endsWith(">") ? "" : "."));
}
@Override

View file

@ -29,7 +29,7 @@ public class ChooseCreatureEffect extends OneShotEffect {
public ChooseCreatureEffect(FilterPermanent filter, boolean useOffset) {
super(Outcome.Benefit);
this.filter = filter;
this.staticText = "choose " + filter.getMessage();
this.staticText = "choose " + CardUtil.addArticle(filter.getMessage());
this.useOffset = useOffset;
}

View file

@ -10,7 +10,7 @@ public class ExileSourceAndReturnFaceUpEffect extends ExileAndReturnSourceEffect
public ExileSourceAndReturnFaceUpEffect() {
super(PutCards.BATTLEFIELD, Pronoun.IT, true, null);
staticText = "exile {this}, then return it to the battlefield. <i>(front face up)</i>";
staticText = "exile {this}, then return it to the battlefield <i>(front face up)</i>.";
}
private ExileSourceAndReturnFaceUpEffect(final ExileSourceAndReturnFaceUpEffect effect) {

View file

@ -156,7 +156,11 @@ public class MayCastTargetCardEffect extends OneShotEffect {
}
text += ".";
if (thenExile) {
text += " " + ThatSpellGraveyardExileReplacementEffect.RULE_YOUR;
if (text.contains("a graveyard")) {
text += " " + ThatSpellGraveyardExileReplacementEffect.RULE_A;
} else {
text += " " + ThatSpellGraveyardExileReplacementEffect.RULE_YOUR;
}
}
return text;
}

View file

@ -88,7 +88,7 @@ public class EquipAbility extends ActivatedAbilityImpl {
String targetText = getTargets().get(0) != null ? getTargets().get(0).getFilter().getMessage() : "creature";
String reminderText = " <i>(" + getManaCosts().getText() + ": Attach to target " + targetText + ". Equip only as a sorcery.)</i>";
StringBuilder sb = new StringBuilder("Equip");
StringBuilder sb = new StringBuilder(addRulePrefix("Equip"));
if (!targetText.equals("creature you control")) {
sb.append(' ').append(targetText);
}

View file

@ -81,8 +81,8 @@ public class ProtectionAbility extends StaticAbility {
if (this.staticText != null && !this.staticText.isEmpty()) {
return this.staticText;
}
return (flavorWord == null ? "protection from " : CardUtil.italicizeWithEmDash(flavorWord) + "Protection from ")
+ filter.getMessage() + (removeAuras ? "" : ". This effect doesn't remove Auras.");
return addRulePrefix("protection from ") + filter.getMessage() +
(removeAuras ? "" : ". This effect doesn't remove Auras.");
}
public ProtectionAbility setText(String text) {

View file

@ -583,6 +583,11 @@ public class StackAbility extends StackObjectImpl implements Ability {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public String addRulePrefix(String rule) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public Ability withFirstModeFlavorWord(String flavorWord) {
throw new UnsupportedOperationException("Not supported.");