diff --git a/Mage.Sets/src/mage/cards/b/BanditsTalent.java b/Mage.Sets/src/mage/cards/b/BanditsTalent.java index f9e840fbc0c..3dce439ecf4 100644 --- a/Mage.Sets/src/mage/cards/b/BanditsTalent.java +++ b/Mage.Sets/src/mage/cards/b/BanditsTalent.java @@ -54,7 +54,7 @@ public final class BanditsTalent extends CardImpl { this.addAbility(new ClassLevelAbility(2, "{B}")); // At the beginning of each opponent's upkeep, if that player has one or fewer cards in hand, they lose 2 life. this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(new BeginningOfUpkeepTriggeredAbility( - TargetController.OPPONENT, new ConditionalOneShotEffect(new LoseLifeTargetEffect(2), new CardsInHandCondition(ComparisonType.OR_LESS, 1, TargetController.ACTIVE)), + TargetController.OPPONENT, new ConditionalOneShotEffect(new LoseLifeTargetEffect(2).setText("they lose 2 life"), new CardsInHandCondition(ComparisonType.OR_LESS, 1, TargetController.ACTIVE)), false), 2))); // {3}{B}: Level 3 diff --git a/Mage.Sets/src/mage/cards/b/BezaTheBoundingSpring.java b/Mage.Sets/src/mage/cards/b/BezaTheBoundingSpring.java index cdf57adce26..d515076bf2e 100644 --- a/Mage.Sets/src/mage/cards/b/BezaTheBoundingSpring.java +++ b/Mage.Sets/src/mage/cards/b/BezaTheBoundingSpring.java @@ -10,17 +10,22 @@ import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.StaticFilters; +import mage.game.Controllable; import mage.game.Game; import mage.game.permanent.token.FishNoAbilityToken; import mage.game.permanent.token.TreasureToken; import mage.players.Player; +import java.util.Optional; +import java.util.Set; import java.util.UUID; /** @@ -28,6 +33,13 @@ import java.util.UUID; */ public final class BezaTheBoundingSpring extends CardImpl { + private static final Condition condition = new OpponentControlsMoreCondition(StaticFilters.FILTER_LANDS); + private static final Condition condition2 = new OpponentControlsMoreCondition(StaticFilters.FILTER_PERMANENT_CREATURES); + private static final Hint hint = new ConditionHint(condition); + private static final Hint hint2 = new ConditionHint(condition2); + private static final Hint hint3 = new ConditionHint(OpponentHasMoreLifeCondition.instance); + private static final Hint hint4 = new ConditionHint(BezaOpponentHasMoreCardsInHandThanYouCondition.instance); + public BezaTheBoundingSpring(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); @@ -39,14 +51,23 @@ public final class BezaTheBoundingSpring extends CardImpl { // When Beza, the Bounding Spring enters, create a Treasure token if an opponent controls more lands than you. You gain 4 life if an opponent has more life than you. Create two 1/1 blue Fish creature tokens if an opponent controls more creatures than you. Draw a card if an opponent has more cards in hand than you. Ability ability = new EntersBattlefieldTriggeredAbility(new ConditionalOneShotEffect( - new CreateTokenEffect(new TreasureToken()), new OpponentControlsMoreCondition(StaticFilters.FILTER_LANDS))); + new CreateTokenEffect(new TreasureToken()), condition, + "create a Treasure token if an opponent controls more lands than you" + )); ability.addEffect(new ConditionalOneShotEffect( - new GainLifeEffect(4), OpponentHasMoreLifeCondition.instance)); + new GainLifeEffect(4), OpponentHasMoreLifeCondition.instance, + "you gain 4 life if an opponent has more life than you" + )); ability.addEffect(new ConditionalOneShotEffect( - new CreateTokenEffect(new FishNoAbilityToken(), 2), new OpponentControlsMoreCondition(StaticFilters.FILTER_PERMANENT_CREATURES))); + new CreateTokenEffect(new FishNoAbilityToken(), 2), condition2, + "Create two 1/1 blue Fish creature tokens if an opponent controls more creatures than you" + )); ability.addEffect(new ConditionalOneShotEffect( - new DrawCardSourceControllerEffect(1), BezaOpponentHasMoreCardsInHandThanYouCondition.instance)); - this.addAbility(ability); + new DrawCardSourceControllerEffect(1), + BezaOpponentHasMoreCardsInHandThanYouCondition.instance, + "draw a card if an opponent has more cards in hand than you" + )); + this.addAbility(ability.addHint(hint).addHint(hint2).addHint(hint3).addHint(hint4)); } private BezaTheBoundingSpring(final BezaTheBoundingSpring card) { @@ -61,22 +82,23 @@ public final class BezaTheBoundingSpring extends CardImpl { //Based on MoreCardsInHandThanOpponentsCondition enum BezaOpponentHasMoreCardsInHandThanYouCondition implements Condition { - instance; @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - int cardsInHand = player.getHand().size(); - for (UUID playerId : game.getOpponents(source.getControllerId())) { - Player opponent = game.getPlayer(playerId); - if (opponent != null && opponent.getHand().size() > cardsInHand) { - return true; - } - } - } - return false; + int cardsInHand = Optional + .ofNullable(source) + .map(Controllable::getControllerId) + .map(game::getPlayer) + .map(Player::getHand) + .map(Set::size) + .orElse(0); + return game.getOpponents(source.getControllerId()) + .stream() + .map(game::getPlayer) + .map(Player::getHand) + .mapToInt(Set::size) + .anyMatch(x -> x > cardsInHand); } @Override diff --git a/Mage.Sets/src/mage/cards/b/BushyBodyguard.java b/Mage.Sets/src/mage/cards/b/BushyBodyguard.java index aa6f98136c0..57daacd29e6 100644 --- a/Mage.Sets/src/mage/cards/b/BushyBodyguard.java +++ b/Mage.Sets/src/mage/cards/b/BushyBodyguard.java @@ -32,7 +32,7 @@ public final class BushyBodyguard extends CardImpl { // When this creature enters, you may forage. If you do, put two +1/+1 counters on it. this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ForageCost() + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).setText("put two +1/+1 counters on it"), new ForageCost() ))); } diff --git a/Mage.Sets/src/mage/cards/d/DaringWaverider.java b/Mage.Sets/src/mage/cards/d/DaringWaverider.java index a253a60a4b5..09b1b6aa903 100644 --- a/Mage.Sets/src/mage/cards/d/DaringWaverider.java +++ b/Mage.Sets/src/mage/cards/d/DaringWaverider.java @@ -21,7 +21,7 @@ import java.util.UUID; * @author notgreat */ public final class DaringWaverider extends CardImpl { - private static final FilterCard filter = new FilterInstantOrSorceryCard("instant or sorcery card with mana value 4 or less"); + private static final FilterCard filter = new FilterInstantOrSorceryCard("instant or sorcery card with mana value 4 or less from your graveyard"); static { filter.add(new ManaValuePredicate(ComparisonType.OR_LESS, 4)); diff --git a/Mage.Sets/src/mage/cards/e/ElugeTheShorelessSea.java b/Mage.Sets/src/mage/cards/e/ElugeTheShorelessSea.java index 8b87b566f72..49005367aa2 100644 --- a/Mage.Sets/src/mage/cards/e/ElugeTheShorelessSea.java +++ b/Mage.Sets/src/mage/cards/e/ElugeTheShorelessSea.java @@ -118,7 +118,7 @@ class ElugeTheShorelessSeaEffect extends BecomesBasicLandTargetEffect { ElugeTheShorelessSeaEffect() { super(Duration.Custom, false, false, SubType.ISLAND); - staticText = "It's an land is an Island in addition to its other types for as long as it has a flood counter on it"; + staticText = "It's an Island in addition to its other types for as long as it has a flood counter on it"; } private ElugeTheShorelessSeaEffect(final ElugeTheShorelessSeaEffect effect) { diff --git a/Mage.Sets/src/mage/cards/f/FabledPassage.java b/Mage.Sets/src/mage/cards/f/FabledPassage.java index ce6a2c90e8f..5301cd4bc35 100644 --- a/Mage.Sets/src/mage/cards/f/FabledPassage.java +++ b/Mage.Sets/src/mage/cards/f/FabledPassage.java @@ -16,9 +16,7 @@ import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; -import mage.target.targetpointer.FirstTargetPointer; import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -53,7 +51,7 @@ class FabledPassageSearchForLandEffect extends OneShotEffect { FabledPassageSearchForLandEffect() { super(Outcome.PutCardInPlay); - staticText = "Search your library for a basic land card, put it onto the battlefield tapped, then shuffle "; + staticText = "Search your library for a basic land card, put it onto the battlefield tapped, then shuffle"; } private FabledPassageSearchForLandEffect(final FabledPassageSearchForLandEffect effect) { @@ -129,4 +127,4 @@ class FabledPassageUntapLandEffect extends OneShotEffect { public FabledPassageUntapLandEffect copy() { return new FabledPassageUntapLandEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FecundGreenshell.java b/Mage.Sets/src/mage/cards/f/FecundGreenshell.java index 3a88f596fd6..78362c58dd3 100644 --- a/Mage.Sets/src/mage/cards/f/FecundGreenshell.java +++ b/Mage.Sets/src/mage/cards/f/FecundGreenshell.java @@ -1,7 +1,5 @@ package mage.cards.f; -import java.util.UUID; - import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; @@ -11,24 +9,27 @@ import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.hint.common.LandsYouControlHint; -import mage.cards.Card; -import mage.constants.*; import mage.abilities.keyword.ReachAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.ToughnessGreaterThanPowerPredicate; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** * @author Cguy7777 */ public final class FecundGreenshell extends CardImpl { - private static final FilterCreaturePermanent filter - = new FilterCreaturePermanent("creature you control with toughness greater than its power"); + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("creature you control with toughness greater than its power"); static { filter.add(ToughnessGreaterThanPowerPredicate.instance); @@ -59,7 +60,7 @@ public final class FecundGreenshell extends CardImpl { // Whenever Fecund Greenshell or another creature you control with toughness greater than its power enters, // look at the top card of your library. If it's a land card, you may put it onto the battlefield tapped. Otherwise, put it into your hand. this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility( - new FecundGreenshellEffect(), filter, false, true)); + new FecundGreenshellEffect(), filter, false, false)); } private FecundGreenshell(final FecundGreenshell card) { diff --git a/Mage.Sets/src/mage/cards/f/ForTheCommonGood.java b/Mage.Sets/src/mage/cards/f/ForTheCommonGood.java index 1d90d44e6ad..ac25c6345e0 100644 --- a/Mage.Sets/src/mage/cards/f/ForTheCommonGood.java +++ b/Mage.Sets/src/mage/cards/f/ForTheCommonGood.java @@ -50,7 +50,7 @@ public final class ForTheCommonGood extends CardImpl { IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn, StaticFilters.FILTER_PERMANENT_TOKENS ).concatBy("Then")); - this.getSpellAbility().addEffect(new GainLifeEffect(xValue)); + this.getSpellAbility().addEffect(new GainLifeEffect(xValue).setText("You gain 1 life for each token you control")); this.getSpellAbility().addHint(hint); } diff --git a/Mage.Sets/src/mage/cards/g/GossipsTalent.java b/Mage.Sets/src/mage/cards/g/GossipsTalent.java index e160bd5e9f7..d347e6b334a 100644 --- a/Mage.Sets/src/mage/cards/g/GossipsTalent.java +++ b/Mage.Sets/src/mage/cards/g/GossipsTalent.java @@ -1,7 +1,10 @@ package mage.cards.g; import mage.abilities.Ability; -import mage.abilities.common.*; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; +import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; import mage.abilities.effects.common.continuous.GainClassAbilitySourceEffect; @@ -10,7 +13,10 @@ import mage.abilities.keyword.ClassLevelAbility; import mage.abilities.keyword.ClassReminderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SetTargetPointer; +import mage.constants.SubType; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterAttackingCreature; @@ -24,7 +30,7 @@ import java.util.UUID; */ public final class GossipsTalent extends CardImpl { - private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature with power 3 or less can't be blocked this turn"); + private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature with power 3 or less"); static { filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 4)); @@ -59,7 +65,7 @@ public final class GossipsTalent extends CardImpl { new DealsDamageToAPlayerAllTriggeredAbility( new ExileThenReturnTargetEffect(false, false) .setText("exile it, then return it to the battlefield under its owner's control"), - StaticFilters.FILTER_PERMANENT_CREATURE, true, SetTargetPointer.PERMANENT, true + StaticFilters.FILTER_CONTROLLED_CREATURE, true, SetTargetPointer.PERMANENT, true ), 3 ))); } diff --git a/Mage.Sets/src/mage/cards/h/HazardrootHerbalist.java b/Mage.Sets/src/mage/cards/h/HazardrootHerbalist.java index c7589565095..927905b73f1 100644 --- a/Mage.Sets/src/mage/cards/h/HazardrootHerbalist.java +++ b/Mage.Sets/src/mage/cards/h/HazardrootHerbalist.java @@ -2,7 +2,7 @@ package mage.cards.h; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.TargetObjectMatchesFilterCondition; import mage.abilities.decorator.ConditionalOneShotEffect; @@ -35,7 +35,7 @@ public final class HazardrootHerbalist extends CardImpl { this.toughness = new MageInt(4); // Whenever you attack, target creature you control gets +1/+0 until end of turn. If that creature is a token, it also gains deathtouch until end of turn. - Ability ability = new AttacksCreatureYouControlTriggeredAbility(new BoostTargetEffect(1, 0)); + Ability ability = new AttacksWithCreaturesTriggeredAbility(new BoostTargetEffect(1, 0), 1); ability.addEffect(new ConditionalOneShotEffect( new AddContinuousEffectToGame(new GainAbilityTargetEffect(DeathtouchAbility.getInstance())), condition, "if that creature is a token, it also gains deathtouch until end of turn" diff --git a/Mage.Sets/src/mage/cards/h/HoardersOverflow.java b/Mage.Sets/src/mage/cards/h/HoardersOverflow.java index 5e56f53f01d..c4e5b1e300c 100644 --- a/Mage.Sets/src/mage/cards/h/HoardersOverflow.java +++ b/Mage.Sets/src/mage/cards/h/HoardersOverflow.java @@ -37,7 +37,7 @@ public final class HoardersOverflow extends CardImpl { // {1}{R}, Sacrifice Hoarder's Overflow: Discard your hand, then draw cards equal to the number of stash counters on Hoarder's Overflow. Ability ability = new SimpleActivatedAbility(new DiscardHandControllerEffect(), new ManaCostsImpl<>("{1}{R}")); ability.addCost(new SacrificeSourceCost()); - ability.addEffect(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.STASH)).concatBy(", then")); + ability.addEffect(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.STASH)).setText(", then draw cards equal to the number of stash counters on {this}")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IntoTheFloodMaw.java b/Mage.Sets/src/mage/cards/i/IntoTheFloodMaw.java index c0a5d0adb09..af078458bd5 100644 --- a/Mage.Sets/src/mage/cards/i/IntoTheFloodMaw.java +++ b/Mage.Sets/src/mage/cards/i/IntoTheFloodMaw.java @@ -39,7 +39,7 @@ public final class IntoTheFloodMaw extends CardImpl { // Return target creature an opponent controls to its owner's hand. If the gift was promise, instead return target nonland permanent an opponent controls to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect() - .setText("return target creature an opponent controls to its owner's hand. If the gift was promise, " + + .setText("return target creature an opponent controls to its owner's hand. If the gift was promised, " + "instead return target nonland permanent an opponent controls to its owner's hand")); this.getSpellAbility().addTarget(new TargetPermanent(playableFilter)); this.getSpellAbility().setTargetAdjuster(new ConditionalTargetAdjuster(GiftWasPromisedCondition.TRUE, diff --git a/Mage.Sets/src/mage/cards/k/Knightfisher.java b/Mage.Sets/src/mage/cards/k/Knightfisher.java index 35291fcb2e9..3f54f354aa4 100644 --- a/Mage.Sets/src/mage/cards/k/Knightfisher.java +++ b/Mage.Sets/src/mage/cards/k/Knightfisher.java @@ -1,7 +1,7 @@ package mage.cards.k; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -9,6 +9,8 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.FishNoAbilityToken; @@ -19,9 +21,10 @@ import java.util.UUID; */ public final class Knightfisher extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent(SubType.BIRD, "nontoken Bird"); + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.BIRD, "another nontoken Bird you control"); static { + filter.add(AnotherPredicate.instance); filter.add(TokenPredicate.FALSE); } @@ -37,9 +40,7 @@ public final class Knightfisher extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever another nontoken Bird you control enters, create a 1/1 blue Fish creature token. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( - new CreateTokenEffect(new FishNoAbilityToken()), filter - )); + this.addAbility(new EntersBattlefieldAllTriggeredAbility(new CreateTokenEffect(new FishNoAbilityToken()), filter)); } private Knightfisher(final Knightfisher card) { diff --git a/Mage.Sets/src/mage/cards/l/LongstalkBrawl.java b/Mage.Sets/src/mage/cards/l/LongstalkBrawl.java index db52e9e26b8..e6032504f7e 100644 --- a/Mage.Sets/src/mage/cards/l/LongstalkBrawl.java +++ b/Mage.Sets/src/mage/cards/l/LongstalkBrawl.java @@ -33,7 +33,7 @@ public final class LongstalkBrawl extends CardImpl { GiftWasPromisedCondition.TRUE, "choose target creature you control and target creature " + "you don't control. Put a +1/+1 counter on the creature you control if the gift was promised" )); - this.getSpellAbility().addEffect(new FightTargetsEffect().setText("then those creatures fight each other")); + this.getSpellAbility().addEffect(new FightTargetsEffect().setText("Then those creatures fight each other")); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); } diff --git a/Mage.Sets/src/mage/cards/p/PartingGust.java b/Mage.Sets/src/mage/cards/p/PartingGust.java index 6dc25b06a9e..4d7fbfeb5d7 100644 --- a/Mage.Sets/src/mage/cards/p/PartingGust.java +++ b/Mage.Sets/src/mage/cards/p/PartingGust.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; public final class PartingGust extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + static { filter.add(TokenPredicate.FALSE); } @@ -52,7 +53,7 @@ public final class PartingGust extends CardImpl { new ExileTargetEffect(), new PartingGustExileReturnEffect(), GiftWasPromisedCondition.TRUE, - "Exile target nontoken creature. If the gift wasn't promised, return that creature to the " + + "Exile target nontoken creature. If the gift wasn't promised, return that card to the " + "battlefield under its owner's control with a +1/+1 counter on it at the beginning of the next end step." )); } diff --git a/Mage.Sets/src/mage/cards/p/PeerlessRecycling.java b/Mage.Sets/src/mage/cards/p/PeerlessRecycling.java index 55f023fd46f..bdc60ef9894 100644 --- a/Mage.Sets/src/mage/cards/p/PeerlessRecycling.java +++ b/Mage.Sets/src/mage/cards/p/PeerlessRecycling.java @@ -26,7 +26,7 @@ public final class PeerlessRecycling extends CardImpl { // Return target permanent from your graveyard to your hand. If the gift was promised, instead return two target permanent cards from your graveyard to your hand. this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect() - .setText("return target permanent from your graveyard to your hand. If the gift was promised, " + + .setText("return target permanent card from your graveyard to your hand. If the gift was promised, " + "instead return two target permanent cards from your graveyard to your hand")); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_PERMANENT)); this.getSpellAbility().setTargetAdjuster(new ConditionalTargetAdjuster(GiftWasPromisedCondition.TRUE, diff --git a/Mage.Sets/src/mage/cards/p/PsychicWhorl.java b/Mage.Sets/src/mage/cards/p/PsychicWhorl.java index f35c9339f29..a0dd1da2c3a 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicWhorl.java +++ b/Mage.Sets/src/mage/cards/p/PsychicWhorl.java @@ -32,7 +32,7 @@ public final class PsychicWhorl extends CardImpl { this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new SurveilEffect(2), condition, - "then if you control a Rat, surveil 2" + "Then if you control a Rat, surveil 2" )); this.getSpellAbility().addHint(hint); } diff --git a/Mage.Sets/src/mage/cards/r/RabidGnaw.java b/Mage.Sets/src/mage/cards/r/RabidGnaw.java index 5d3c98857f6..253b99df499 100644 --- a/Mage.Sets/src/mage/cards/r/RabidGnaw.java +++ b/Mage.Sets/src/mage/cards/r/RabidGnaw.java @@ -22,7 +22,7 @@ public final class RabidGnaw extends CardImpl { // Target creature you control gets +1/+0 until end of turn. Then it deals damage equal to its power to target creature you don't control. this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0)); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); - this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("then it")); + this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("Then it")); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); } diff --git a/Mage.Sets/src/mage/cards/r/RottenmouthViper.java b/Mage.Sets/src/mage/cards/r/RottenmouthViper.java index 4d55d36b158..a23d3f76b66 100644 --- a/Mage.Sets/src/mage/cards/r/RottenmouthViper.java +++ b/Mage.Sets/src/mage/cards/r/RottenmouthViper.java @@ -71,7 +71,7 @@ class RottenmouthViperEffect extends OneShotEffect{ RottenmouthViperEffect(DynamicValue blightCounterAmount) { super(Outcome.LoseLife); this.blightCounterAmount = blightCounterAmount; - this.staticText = "Then for each blight counter on it, each opponent loses 4 life unless that player sacrifices a nonland permanent or discards a card."; + this.staticText = "Then for each blight counter on it, each opponent loses 4 life unless that player sacrifices a nonland permanent of their choice or discards a card."; } private RottenmouthViperEffect(final RottenmouthViperEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/SeasonedWarrenguard.java b/Mage.Sets/src/mage/cards/s/SeasonedWarrenguard.java index 5b12cac1eb3..d4e447e51b9 100644 --- a/Mage.Sets/src/mage/cards/s/SeasonedWarrenguard.java +++ b/Mage.Sets/src/mage/cards/s/SeasonedWarrenguard.java @@ -43,7 +43,7 @@ public final class SeasonedWarrenguard extends CardImpl { // Whenever Seasoned Warrenguard attacks while you control a token, Seasoned Warrenguard gets +2/+0 until end of turn. this.addAbility(new AttacksTriggeredAbility( new BoostSourceEffect(2, 0, Duration.EndOfTurn) - ).withTriggerCondition(condition).addHint(hint)); + ).withRuleTextReplacement(false).withTriggerCondition(condition).addHint(hint)); } private SeasonedWarrenguard(final SeasonedWarrenguard card) { diff --git a/Mage.Sets/src/mage/cards/s/ShorelineLooter.java b/Mage.Sets/src/mage/cards/s/ShorelineLooter.java index a26d4ab8172..04ee4a103ff 100644 --- a/Mage.Sets/src/mage/cards/s/ShorelineLooter.java +++ b/Mage.Sets/src/mage/cards/s/ShorelineLooter.java @@ -40,7 +40,7 @@ public final class ShorelineLooter extends CardImpl { Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1)); ability.addEffect(new ConditionalOneShotEffect( new DiscardControllerEffect(1), condition, - "then discard a card unless seven or more cards are in your graveyard" + "Then discard a card unless seven or more cards are in your graveyard" )); this.addAbility(ability.setAbilityWord(AbilityWord.THRESHOLD)); } diff --git a/Mage.Sets/src/mage/cards/s/Spellgyre.java b/Mage.Sets/src/mage/cards/s/Spellgyre.java index 5a99c5e960e..1c0bfc6b358 100644 --- a/Mage.Sets/src/mage/cards/s/Spellgyre.java +++ b/Mage.Sets/src/mage/cards/s/Spellgyre.java @@ -25,7 +25,7 @@ public final class Spellgyre extends CardImpl { this.getSpellAbility().addTarget(new TargetSpell()); // * Surveil 2, then draw two cards. - this.getSpellAbility().addMode(new Mode(new SurveilEffect(2)) + this.getSpellAbility().addMode(new Mode(new SurveilEffect(2, false)) .addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then"))); } diff --git a/Mage.Sets/src/mage/cards/s/StarseerMentor.java b/Mage.Sets/src/mage/cards/s/StarseerMentor.java index dd0ae2906ae..5e4c4bb4674 100644 --- a/Mage.Sets/src/mage/cards/s/StarseerMentor.java +++ b/Mage.Sets/src/mage/cards/s/StarseerMentor.java @@ -54,7 +54,7 @@ public final class StarseerMentor extends CardImpl { "Sacrifice a nonland permanent or discard a card to prevent losing 3 life?" ) ), YouGainedOrLostLifeCondition.instance, "At the beginning of your end step, if you gained or lost life this turn, " - + "target opponent loses 3 life unless they sacrifice a nonland permanent or discard a card." + + "target opponent loses 3 life unless they sacrifice a nonland permanent of their choice or discard a card." ); ability.addTarget(new TargetOpponent()); ability.addWatcher(new PlayerGainedLifeWatcher()); diff --git a/Mage.Sets/src/mage/cards/t/ThornplateIntimidator.java b/Mage.Sets/src/mage/cards/t/ThornplateIntimidator.java index fd2921883d5..43f1b367d22 100644 --- a/Mage.Sets/src/mage/cards/t/ThornplateIntimidator.java +++ b/Mage.Sets/src/mage/cards/t/ThornplateIntimidator.java @@ -42,7 +42,7 @@ public final class ThornplateIntimidator extends CardImpl { new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_NON_LAND), new DiscardCardCost() ), "Sacrifice a nonland permanent or discard a card to prevent losing 3 life?" - )); + ).setText("target opponent loses 3 life unless they sacrifice a nonland permanent of their choice or discard a card")); ability.addTarget(new TargetOpponent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VrenTheRelentless.java b/Mage.Sets/src/mage/cards/v/VrenTheRelentless.java index 90ca31c8068..081b584c775 100644 --- a/Mage.Sets/src/mage/cards/v/VrenTheRelentless.java +++ b/Mage.Sets/src/mage/cards/v/VrenTheRelentless.java @@ -2,15 +2,16 @@ package mage.cards.v; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.replacement.CreaturesAreExiledOnDeathReplacementEffect; +import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.WardAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -31,6 +32,10 @@ import java.util.UUID; */ public final class VrenTheRelentless extends CardImpl { + private static final Hint hint = new ValueHint( + "Creatures exiled under opponents' control this turn", VrenTheRelentlessCount.instance + ); + public VrenTheRelentless(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); this.supertype.add(SuperType.LEGENDARY); @@ -49,11 +54,8 @@ public final class VrenTheRelentless extends CardImpl { // At the beginning of each end step, create X 1/1 black Rat creature tokens with "This creature gets +1/+1 for each // other Rat you control," where X is the number of creatures your opponents controlled that were exiled this turn. this.addAbility(new BeginningOfEndStepTriggeredAbility( - TargetController.ANY, new CreateTokenEffect(new VrenRatToken(), VrenTheRelentlessCount.instance) - .setText("create X 1/1 black Rat creature tokens with \"This creature gets +1/+1 for each other Rat you " + - "control,\" where X is the number of creatures your opponents controlled that were exiled this turn"), - false - ).addHint(new ValueHint("Creatures exiled under opponents' control this turn", VrenTheRelentlessCount.instance)), new VrenTheRelentlessWatcher()); + TargetController.ANY, new CreateTokenEffect(new VrenRatToken(), VrenTheRelentlessCount.instance), false + ).addHint(hint), new VrenTheRelentlessWatcher()); } private VrenTheRelentless(final VrenTheRelentless card) { @@ -72,7 +74,7 @@ enum VrenTheRelentlessCount implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { VrenTheRelentlessWatcher watcher = game.getState().getWatcher(VrenTheRelentlessWatcher.class); - return watcher == null ? 0 : watcher.getCount(sourceAbility.getControllerId()); + return watcher == null ? 0 : watcher.getCount(sourceAbility.getControllerId(), game); } @Override @@ -80,9 +82,14 @@ enum VrenTheRelentlessCount implements DynamicValue { return instance; } + @Override + public String toString() { + return "X"; + } + @Override public String getMessage() { - return ""; + return "the number of creatures that were exiled under your opponents' control this turn"; } } @@ -100,7 +107,9 @@ class VrenTheRelentlessWatcher extends Watcher { return; } ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if ((zEvent.getToZone() == Zone.EXILED && zEvent.getFromZone() == Zone.BATTLEFIELD) && zEvent.getTarget().isCreature(game)) { + if (zEvent.getToZone() == Zone.EXILED + && zEvent.getFromZone() == Zone.BATTLEFIELD + && zEvent.getTarget().isCreature(game)) { playerMap.compute(zEvent.getTarget().getControllerId(), CardUtil::setOrIncrementValue); } } @@ -111,10 +120,11 @@ class VrenTheRelentlessWatcher extends Watcher { super.reset(); } - int getCount(UUID playerId) { - return playerMap.entrySet().stream() - .filter(entry -> !entry.getKey().equals(playerId)) - .mapToInt(Map.Entry::getValue) + int getCount(UUID playerId, Game game) { + return game + .getOpponents(playerId) + .stream() + .mapToInt(uuid -> playerMap.getOrDefault(uuid, 0)) .sum(); } } diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 05056c4e059..9d1898b1c59 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -75,7 +75,7 @@ public class VerifyCardDataTest { private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class); - private static final String FULL_ABILITIES_CHECK_SET_CODES = "DRC"; // check ability text due mtgjson, can use multiple sets like MAT;CMD or * for all + private static final String FULL_ABILITIES_CHECK_SET_CODES = "BLB"; // 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/effects/common/continuous/LoseAllAbilitiesTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllAbilitiesTargetEffect.java index 614be0bd431..81431bc87d3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllAbilitiesTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAllAbilitiesTargetEffect.java @@ -51,7 +51,7 @@ public class LoseAllAbilitiesTargetEffect extends ContinuousEffectImpl { return staticText; } return getTargetPointer().describeTargets(mode.getTargets(), "it") - + " loses all abilities " + (duration.toString().isEmpty() ? "" : ' ' + duration.toString()); + + " loses all abilities" + (duration.toString().isEmpty() ? "" : ' ' + duration.toString()); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/VrenRatToken.java b/Mage/src/main/java/mage/game/permanent/token/VrenRatToken.java index 5925705fc98..c7d1f8932d0 100644 --- a/Mage/src/main/java/mage/game/permanent/token/VrenRatToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/VrenRatToken.java @@ -2,12 +2,13 @@ package mage.game.permanent.token; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; @@ -16,26 +17,23 @@ import mage.filter.predicate.mageobject.AnotherPredicate; */ public final class VrenRatToken extends TokenImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("other Rat you control"); + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.RAT, "other Rat you control"); static { - filter.add(SubType.RAT.getPredicate()); filter.add(AnotherPredicate.instance); } + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); + public VrenRatToken() { - super("Rat Token", "1/1 black Rat creature tokens with \"This creature gets +1/+1 for each other Rat you control\""); + super("Rat Token", "1/1 black Rat creature token with \"This token gets +1/+1 for each other Rat you control.\""); cardType.add(CardType.CREATURE); color.setBlack(true); subtype.add(SubType.RAT); power = new MageInt(1); toughness = new MageInt(1); - this.addAbility(new SimpleStaticAbility( - new BoostSourceEffect(new PermanentsOnBattlefieldCount(filter), - new PermanentsOnBattlefieldCount(filter), Duration.WhileOnBattlefield - ) - )); + this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield))); } private VrenRatToken(final VrenRatToken token) { diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 36778e1fde9..8cd26e37641 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -85,7 +85,7 @@ public final class CardUtil { public static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); private static final List costWords = Arrays.asList( - "put", "return", "exile", "discard", "sacrifice", "remove", "tap", "reveal", "pay", "collect" + "put", "return", "exile", "discard", "sacrifice", "remove", "tap", "reveal", "pay", "collect", "forage" ); // search set code in commands like "set_code-card_name"