diff --git a/Mage.Sets/src/mage/cards/c/ChasmSkulker.java b/Mage.Sets/src/mage/cards/c/ChasmSkulker.java index a17ce113f04..45e1edc39dd 100644 --- a/Mage.Sets/src/mage/cards/c/ChasmSkulker.java +++ b/Mage.Sets/src/mage/cards/c/ChasmSkulker.java @@ -1,32 +1,28 @@ - package mage.cards.c; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.DrawCardControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.token.SquidToken; -import mage.players.Player; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class ChasmSkulker extends CardImpl { + private static final DynamicValue xValue = new CountersSourceCount(CounterType.P1P1); + public ChasmSkulker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.SQUID); @@ -36,10 +32,14 @@ public final class ChasmSkulker extends CardImpl { this.toughness = new MageInt(1); // Whenever you draw a card, put a +1/+1 counter on Chasm Skulker. - this.addAbility(new DrawCardControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false)); + this.addAbility(new DrawCardControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false + )); // When Chasm Skulker dies, create X 1/1 blue Squid creature tokens with islandwalk, where X is the number of +1/+1 counters on Chasm Skulker. - this.addAbility(new DiesSourceTriggeredAbility(new ChasmSkulkerEffect(), false)); + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new SquidToken(), xValue) + .setText("create X 1/1 blue Squid creature tokens with islandwalk, " + + "where X is the number of +1/+1 counters on {this}"), false)); } private ChasmSkulker(final ChasmSkulker card) { @@ -51,36 +51,3 @@ public final class ChasmSkulker extends CardImpl { return new ChasmSkulker(this); } } - -class ChasmSkulkerEffect extends OneShotEffect { - - ChasmSkulkerEffect() { - super(Outcome.Benefit); - this.staticText = "create X 1/1 blue Squid creature tokens with islandwalk, where X is the number of +1/+1 counters on Chasm Skulker"; - } - - private ChasmSkulkerEffect(final ChasmSkulkerEffect effect) { - super(effect); - } - - @Override - public ChasmSkulkerEffect copy() { - return new ChasmSkulkerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent permanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (permanent != null) { - int counters = permanent.getCounters(game).getCount(CounterType.P1P1); - if (counters > 0) { - return new CreateTokenEffect(new SquidToken(), counters).apply(game, source); - } - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/e/EyeOfNidhogg.java b/Mage.Sets/src/mage/cards/e/EyeOfNidhogg.java index cff808d64d4..abd58a38e60 100644 --- a/Mage.Sets/src/mage/cards/e/EyeOfNidhogg.java +++ b/Mage.Sets/src/mage/cards/e/EyeOfNidhogg.java @@ -42,13 +42,13 @@ public final class EyeOfNidhogg extends CardImpl { // Enchanted creature is a black Dragon with base power and toughness 4/2, has flying and deathtouch, and is goaded. Ability ability = new SimpleStaticAbility(new SetCardColorAttachedEffect( ObjectColor.BLACK, Duration.WhileControlled, AttachmentType.AURA - ).setText("enchanted creature is a black")); + ).setText("enchanted creature is a black Dragon")); ability.addEffect(new AddCardSubtypeAttachedEffect( SubType.DRAGON, AttachmentType.AURA - ).setText("Dragon with power")); + ).setText("with base power")); ability.addEffect(new SetBasePowerToughnessAttachedEffect( - 4, 2, - AttachmentType.AURA).setText("and toughness 4/2")); + 4, 2, AttachmentType.AURA + ).setText("and toughness 4/2")); ability.addEffect(new GainAbilityAttachedEffect( FlyingAbility.getInstance(), AttachmentType.AURA ).setText(", has flying")); diff --git a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java index 0afa1b2edf9..1f32bf5ba9b 100644 --- a/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java +++ b/Mage.Sets/src/mage/cards/f/FlayerOfTheHatebound.java @@ -82,7 +82,7 @@ class FlayerTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever Flayer of the Hatebound or another creature enters the battlefield from your graveyard, that creature deals damage equal to its power to any target."; + return "Whenever {this} or another creature enters from your graveyard, that creature deals damage equal to its power to any target."; } @Override diff --git a/Mage.Sets/src/mage/cards/f/ForgeOfHeroes.java b/Mage.Sets/src/mage/cards/f/ForgeOfHeroes.java index 25347b5a4e1..a667c878c46 100644 --- a/Mage.Sets/src/mage/cards/f/ForgeOfHeroes.java +++ b/Mage.Sets/src/mage/cards/f/ForgeOfHeroes.java @@ -1,11 +1,9 @@ package mage.cards.f; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -19,14 +17,15 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class ForgeOfHeroes extends CardImpl { private static final FilterPermanent filter - = new FilterPermanent("commander that entered the battlefield this turn"); + = new FilterPermanent("commander that entered this turn"); static { filter.add(CommanderPredicate.instance); @@ -40,10 +39,7 @@ public final class ForgeOfHeroes extends CardImpl { this.addAbility(new ColorlessManaAbility()); // {T}: Choose target commander that entered the battlefield this turn. Put a +1/+1 counter on it if it's a creature and a loyalty counter on it if it's a planeswalker. - Ability ability = new SimpleActivatedAbility( - new ForgeOfHeroesEffect(), - new TapSourceCost() - ); + Ability ability = new SimpleActivatedAbility(new ForgeOfHeroesEffect(), new TapSourceCost()); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } @@ -62,7 +58,7 @@ class ForgeOfHeroesEffect extends OneShotEffect { ForgeOfHeroesEffect() { super(Outcome.Benefit); - this.staticText = "choose target commander that entered the battlefield this turn. " + this.staticText = "choose target commander that entered this turn. " + "Put a +1/+1 counter on it if it's a creature " + "and a loyalty counter on it if it's a planeswalker"; } @@ -78,20 +74,15 @@ class ForgeOfHeroesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent == null) { return false; } if (permanent.isCreature(game)) { - new AddCountersTargetEffect( - CounterType.P1P1.createInstance() - ).apply(game, source); - } else if (permanent.isPlaneswalker(game)) { - new AddCountersTargetEffect( - CounterType.LOYALTY.createInstance() - ).apply(game, source); - } else { - return false; + permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + } + if (permanent.isPlaneswalker(game)) { + permanent.addCounters(CounterType.LOYALTY.createInstance(), source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/n/NestingGrounds.java b/Mage.Sets/src/mage/cards/n/NestingGrounds.java index cc3cbe926ac..1682f65cf3d 100644 --- a/Mage.Sets/src/mage/cards/n/NestingGrounds.java +++ b/Mage.Sets/src/mage/cards/n/NestingGrounds.java @@ -21,7 +21,7 @@ import java.util.UUID; */ public final class NestingGrounds extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("another target"); + private static final FilterPermanent filter = new FilterPermanent("another target permanent"); static { filter.add(new AnotherTargetPredicate(2)); diff --git a/Mage.Sets/src/mage/cards/r/ResourcefulDefense.java b/Mage.Sets/src/mage/cards/r/ResourcefulDefense.java index f6dcb3cd044..790377d630d 100644 --- a/Mage.Sets/src/mage/cards/r/ResourcefulDefense.java +++ b/Mage.Sets/src/mage/cards/r/ResourcefulDefense.java @@ -91,7 +91,7 @@ class ResourcefulDefenseMoveCounterEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent fromPermanent = game.getPermanent(source.getFirstTarget()); Permanent toPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - if(controller == null || fromPermanent == null || toPermanent == null) { + if (controller == null || fromPermanent == null || toPermanent == null) { return false; } @@ -143,7 +143,7 @@ class ResourcefulDefenseTriggeredAbility extends LeavesBattlefieldAllTriggeredAb ResourcefulDefenseTriggeredAbility() { super(new ResourcefulDefenseLeaveEffect(), StaticFilters.FILTER_CONTROLLED_PERMANENT); - setTriggerPhrase("Whenever a creature you control leaves the battlefield, if it had counters on it, "); + setTriggerPhrase("Whenever a permanent you control leaves the battlefield, if it had counters on it, "); } private ResourcefulDefenseTriggeredAbility(final ResourcefulDefenseTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/s/SOLDIERMilitaryProgram.java b/Mage.Sets/src/mage/cards/s/SOLDIERMilitaryProgram.java index eb6677c5a37..acc52444607 100644 --- a/Mage.Sets/src/mage/cards/s/SOLDIERMilitaryProgram.java +++ b/Mage.Sets/src/mage/cards/s/SOLDIERMilitaryProgram.java @@ -3,19 +3,23 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.condition.common.ControlACommanderCondition; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; import mage.game.permanent.token.SoldierToken; +import mage.players.Player; import mage.target.TargetPermanent; +import java.util.Optional; import java.util.UUID; /** @@ -35,8 +39,7 @@ public final class SOLDIERMilitaryProgram extends CardImpl { ability.getModes().setMoreCondition(2, ControlACommanderCondition.instance); // * Put a +1/+1 counter on each of up to two Soldiers you control. - ability.addMode(new Mode(new AddCountersTargetEffect(CounterType.P1P1.createInstance())) - .addTarget(new TargetPermanent(0, 2, filter))); + ability.addMode(new Mode(new SOLDIERMilitaryProgramEffect())); this.addAbility(ability); } @@ -49,3 +52,38 @@ public final class SOLDIERMilitaryProgram extends CardImpl { return new SOLDIERMilitaryProgram(this); } } + +class SOLDIERMilitaryProgramEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.SOLDIER, "Soldiers you control"); + + SOLDIERMilitaryProgramEffect() { + super(Outcome.Benefit); + staticText = "put a +1/+1 counter on each of up to two Soldiers you control"; + } + + private SOLDIERMilitaryProgramEffect(final SOLDIERMilitaryProgramEffect effect) { + super(effect); + } + + @Override + public SOLDIERMilitaryProgramEffect copy() { + return new SOLDIERMilitaryProgramEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetPermanent target = new TargetPermanent(0, 2, filter, true); + player.choose(Outcome.BoostCreature, target, source, game); + for (UUID targetId : target.getTargets()) { + Optional.ofNullable(targetId) + .map(game::getPermanent) + .map(permanent -> permanent.addCounters(CounterType.P1P1.createInstance(), source, game)); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SummonYojimbo.java b/Mage.Sets/src/mage/cards/s/SummonYojimbo.java index 7ac21cbea3b..061328fcbd1 100644 --- a/Mage.Sets/src/mage/cards/s/SummonYojimbo.java +++ b/Mage.Sets/src/mage/cards/s/SummonYojimbo.java @@ -65,6 +65,7 @@ public final class SummonYojimbo extends CardImpl { sagaAbility.addChapterEffect( this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_III, new CantAttackYouUnlessPayAllEffect(Duration.UntilYourNextTurn, new GenericManaCost(2)) + .setText("until your next turn, creatures can't attack you unless their controller pays {2} for each of those creatures") ); // IV - Create X Treasure tokens, where X is the number of opponents who control a creature with power 4 or greater. diff --git a/Mage.Sets/src/mage/cards/s/SummoningMateria.java b/Mage.Sets/src/mage/cards/s/SummoningMateria.java index b7cd8a28f80..7a2317cb1b1 100644 --- a/Mage.Sets/src/mage/cards/s/SummoningMateria.java +++ b/Mage.Sets/src/mage/cards/s/SummoningMateria.java @@ -48,7 +48,7 @@ public final class SummoningMateria extends CardImpl { ).setText("and has vigilance")); ability.addEffect(new GainAbilityAttachedEffect( new GreenManaAbility(), AttachmentType.EQUIPMENT - ).setText("and {T}: Add {G}.")); + ).setText("and \"{T}: Add {G}.\"")); this.addAbility(ability); // Equip {2} diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 090e621d20a..1dd2eb42a95 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -71,7 +71,7 @@ public class VerifyCardDataTest { private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class); - private static final String FULL_ABILITIES_CHECK_SET_CODES = "FCA"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all + private static final String FULL_ABILITIES_CHECK_SET_CODES = "FIC"; // 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/EntersBattlefieldOrAttacksAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksAllTriggeredAbility.java index 888838aead2..8c20fae76ad 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksAllTriggeredAbility.java @@ -130,8 +130,9 @@ public class EntersBattlefieldOrAttacksAllTriggeredAbility extends TriggeredAbil } private String generateTriggerPhrase() { - StringBuilder sb = new StringBuilder("Whenever ").append(filter.getMessage()); - sb.append(" enters the battlefield "); + StringBuilder sb = new StringBuilder("Whenever "); + sb.append(filter.getMessage()); + sb.append(" enters "); if (controlledText) { sb.append("under your control, "); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java index 8812762b3af..80b35e51bec 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateDelayedTriggeredAbilityEffect.java @@ -68,7 +68,10 @@ public class CreateDelayedTriggeredAbilityEffect extends OneShotEffect { return staticText; } if (ability.getRuleVisible()) { - return rulePrefix + CardUtil.getTextWithFirstCharLowerCase(ability.getRule()); + if (rulePrefix == null || rulePrefix.isEmpty()) { + return CardUtil.getTextWithFirstCharLowerCase(ability.getRule()); + } + return rulePrefix + ability.getRule(); } else { return ""; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java index 768462f1dd4..c531d1fc39c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DamageTargetEffect.java @@ -175,7 +175,7 @@ public class DamageTargetEffect extends OneShotEffect { if (maxTargets == Integer.MAX_VALUE) { sb.append("any number of "); } else { - sb.append("up to "); + sb.append("each of up to "); sb.append(CardUtil.numberToText(maxTargets)); sb.append(' '); } diff --git a/Mage/src/main/java/mage/target/common/TargetControlledCreaturePermanent.java b/Mage/src/main/java/mage/target/common/TargetControlledCreaturePermanent.java index 6c323bfd701..784e5e3d2a0 100644 --- a/Mage/src/main/java/mage/target/common/TargetControlledCreaturePermanent.java +++ b/Mage/src/main/java/mage/target/common/TargetControlledCreaturePermanent.java @@ -17,7 +17,7 @@ public class TargetControlledCreaturePermanent extends TargetControlledPermanent } public TargetControlledCreaturePermanent(int minNumTargets, int maxNumTargets) { - this(minNumTargets, maxNumTargets, StaticFilters.FILTER_CONTROLLED_CREATURE, false); + this(minNumTargets, maxNumTargets, maxNumTargets > 1 ? StaticFilters.FILTER_CONTROLLED_CREATURES : StaticFilters.FILTER_CONTROLLED_CREATURE, false); } public TargetControlledCreaturePermanent(FilterControlledCreaturePermanent filter) { diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index eb12ec70b86..d19068d52e3 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -979,7 +979,11 @@ public final class CardUtil { sb.append(counter.getDescription()); } if (!targetPlayerGets) { - sb.append(add ? " on " : " from ").append(description); + sb.append(add ? " on " : " from "); + if (description.contains("up to")) { + sb.append("each of "); + } + sb.append(description); } if (!amount.getMessage().isEmpty()) { sb.append(xValue ? ", where X is " : " for each ").append(amount.getMessage());