diff --git a/Mage.Sets/src/mage/cards/a/AngelicProtector.java b/Mage.Sets/src/mage/cards/a/AngelicProtector.java index ae9f03b3fe7..ad299601664 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicProtector.java +++ b/Mage.Sets/src/mage/cards/a/AngelicProtector.java @@ -1,7 +1,5 @@ - package mage.cards.a; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesTargetTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -12,21 +10,24 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author North */ public final class AngelicProtector extends CardImpl { public AngelicProtector(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.subtype.add(SubType.ANGEL); this.power = new MageInt(2); this.toughness = new MageInt(2); this.addAbility(FlyingAbility.getInstance()); - this.addAbility(new BecomesTargetTriggeredAbility(new BoostSourceEffect(0, 3, Duration.EndOfTurn))); + this.addAbility(new BecomesTargetTriggeredAbility( + new BoostSourceEffect(0, 3, Duration.EndOfTurn) + ).setTriggerPhrase("Whenever {this} becomes the target of a spell or ability, ")); } private AngelicProtector(final AngelicProtector card) { diff --git a/Mage.Sets/src/mage/cards/a/AshcoatOfTheShadowSwarm.java b/Mage.Sets/src/mage/cards/a/AshcoatOfTheShadowSwarm.java index a7c99d724fa..ed2f83887de 100644 --- a/Mage.Sets/src/mage/cards/a/AshcoatOfTheShadowSwarm.java +++ b/Mage.Sets/src/mage/cards/a/AshcoatOfTheShadowSwarm.java @@ -8,7 +8,7 @@ import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MillCardsControllerEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.cards.CardImpl; @@ -48,14 +48,15 @@ public final class AshcoatOfTheShadowSwarm extends CardImpl { // Whenever Ashcoat of the Shadow Swarm attacks or blocks, other Rats you control // get +X/+X until end of turn, where X is the number of Rats you control. - this.addAbility(new AttacksOrBlocksTriggeredAbility(new BoostControlledEffect( + this.addAbility(new AttacksOrBlocksTriggeredAbility(new BoostAllEffect( xValue, xValue, Duration.EndOfTurn, filter, true ), false).addHint(hint)); // At the beginning of your end step, you may mill four cards. If you do, // return up to two Rat creature cards from your graveyard to your hand. - Ability ability = new BeginningOfEndStepTriggeredAbility(new MillCardsControllerEffect(4), - TargetController.YOU, true); + Ability ability = new BeginningOfEndStepTriggeredAbility( + new MillCardsControllerEffect(4), TargetController.YOU, true + ); ability.addEffect(new AshcoatEffect()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AuntieBlyteBadInfluence.java b/Mage.Sets/src/mage/cards/a/AuntieBlyteBadInfluence.java index a7c94ea0955..fdcc9039fad 100644 --- a/Mage.Sets/src/mage/cards/a/AuntieBlyteBadInfluence.java +++ b/Mage.Sets/src/mage/cards/a/AuntieBlyteBadInfluence.java @@ -21,6 +21,7 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; +import mage.target.common.TargetAnyTarget; import java.util.UUID; @@ -50,6 +51,7 @@ public final class AuntieBlyteBadInfluence extends CardImpl { ); ability.addCost(new TapSourceCost()); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } @@ -68,7 +70,7 @@ class AuntieBlyteBadInfluenceTriggeredAbility extends TriggeredAbilityImpl { AuntieBlyteBadInfluenceTriggeredAbility() { super(Zone.BATTLEFIELD, new AddCountersSourceEffect( CounterType.P1P1.createInstance(0), SavedDamageValue.MANY, false - )); + ).setText("put that many +1/+1 counters on {this}")); setTriggerPhrase("Whenever a source you control deals damage to you, "); } diff --git a/Mage.Sets/src/mage/cards/b/Blisterpod.java b/Mage.Sets/src/mage/cards/b/Blisterpod.java index 8f637bff6f7..e1f14ff77bc 100644 --- a/Mage.Sets/src/mage/cards/b/Blisterpod.java +++ b/Mage.Sets/src/mage/cards/b/Blisterpod.java @@ -1,10 +1,7 @@ - package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.keyword.DevoidAbility; import mage.cards.CardImpl; @@ -13,8 +10,9 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.game.permanent.token.EldraziScionToken; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Blisterpod extends CardImpl { @@ -27,10 +25,10 @@ public final class Blisterpod extends CardImpl { // Devoid this.addAbility(new DevoidAbility(this.color)); + // When Blisterpod dies, create a 1/1 colorless Eldrazi Scion creature token. It has "Sacrifice this creature: Add {C}." - Effect effect = new CreateTokenEffect(new EldraziScionToken()); - effect.setText("Create a 1/1 colorless Eldrazi Scion creature token. It has \"Sacrifice this creature: Add {C}.\""); - this.addAbility(new DiesSourceTriggeredAbility(effect, false)); + this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new EldraziScionToken()) + .setText("create a 1/1 colorless Eldrazi Scion creature token. It has \"Sacrifice this creature: Add {C}.\""), false)); } private Blisterpod(final Blisterpod card) { diff --git a/Mage.Sets/src/mage/cards/b/BorderlandMarauder.java b/Mage.Sets/src/mage/cards/b/BorderlandMarauder.java index 2efb0c0dd61..93027e6949b 100644 --- a/Mage.Sets/src/mage/cards/b/BorderlandMarauder.java +++ b/Mage.Sets/src/mage/cards/b/BorderlandMarauder.java @@ -1,7 +1,5 @@ - package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -11,21 +9,24 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; +import java.util.UUID; + /** - * * @author Quercitron */ public final class BorderlandMarauder extends CardImpl { public BorderlandMarauder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN, SubType.WARRIOR); this.power = new MageInt(1); this.toughness = new MageInt(2); // Whenever Borderland Marauder attacks, it gets +2/+0 until end of turn. - this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn), false)); + this.addAbility(new AttacksTriggeredAbility( + new BoostSourceEffect(2, 0, Duration.EndOfTurn, "it"), false + )); } private BorderlandMarauder(final BorderlandMarauder card) { diff --git a/Mage.Sets/src/mage/cards/b/BrazenCannonade.java b/Mage.Sets/src/mage/cards/b/BrazenCannonade.java index f466ea7fda9..911429fb089 100644 --- a/Mage.Sets/src/mage/cards/b/BrazenCannonade.java +++ b/Mage.Sets/src/mage/cards/b/BrazenCannonade.java @@ -1,67 +1,57 @@ package mage.cards.b; -import java.util.UUID; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; import mage.abilities.Ability; -import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.BeginningOfPostCombatMainTriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.condition.common.RaidCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.ExileTopXMayPlayUntilEndOfTurnEffect; import mage.abilities.hint.common.RaidHint; -import mage.constants.AbilityWord; -import mage.constants.TargetController; -import mage.filter.common.FilterAttackingCreature; -import mage.watchers.common.PlayerAttackedWatcher; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.RestrictionEffect; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeOpponentsEffect; -import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.filter.common.FilterAttackingCreature; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.watchers.common.PlayerAttackedWatcher; + +import java.util.UUID; /** - * * @author @stwalsh4118 */ public final class BrazenCannonade extends CardImpl { - private static final FilterAttackingCreature filter = new FilterAttackingCreature("an attacking creature"); + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("an attacking creature you control"); + + static { + filter.add(AttackingPredicate.instance); + } public BrazenCannonade(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); - // Whenever an attacking creature you control dies, Brazen Cannonade deals 2 damage to each opponent. - Ability ability = new DiesCreatureTriggeredAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), false, filter); - this.addAbility(ability); + this.addAbility(new DiesCreatureTriggeredAbility( + new DamagePlayersEffect(2, TargetController.OPPONENT), false, filter + )); // Raid -- At the beginning of your postcombat main phase, if you attacked with a creature this turn, exile the top card of your library. Until end of combat on your next turn, you may play that card. - Ability raidAbility = new ConditionalInterveningIfTriggeredAbility(new BeginningOfPostCombatMainTriggeredAbility(new ExileTopXMayPlayUntilEndOfTurnEffect(1, false, Duration.UntilYourNextEndCombatStep), TargetController.YOU, false), - RaidCondition.instance, - "At the beginning of your postcombat main phase, " - + "if you attacked with a creature this turn, " - + "exile the top card of your library. " - + "Until end of combat on your next turn, " - + "you may play that card."); - raidAbility.setAbilityWord(AbilityWord.RAID); - raidAbility.addHint(RaidHint.instance); - this.addAbility(raidAbility, new PlayerAttackedWatcher()); + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new BeginningOfPostCombatMainTriggeredAbility( + new ExileTopXMayPlayUntilEndOfTurnEffect( + 1, false, Duration.UntilYourNextEndCombatStep + ), TargetController.YOU, false + ), RaidCondition.instance, "At the beginning of your postcombat main phase, " + + "if you attacked with a creature this turn, exile the top card of your library. " + + "Until end of combat on your next turn, you may play that card." + ); + this.addAbility(ability.setAbilityWord(AbilityWord.RAID).addHint(RaidHint.instance), new PlayerAttackedWatcher()); } private BrazenCannonade(final BrazenCannonade card) { diff --git a/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java b/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java index fe43aa93677..c42c59ed255 100644 --- a/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java +++ b/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java @@ -47,7 +47,7 @@ public final class ChainsOfCustody extends CardImpl { // ward 2 this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( new WardAbility(new GenericManaCost(2), true), AttachmentType.AURA - ))); + ).setText("enchanted creature has ward {2}. (Whenever it becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)"))); } private ChainsOfCustody(final ChainsOfCustody card) { diff --git a/Mage.Sets/src/mage/cards/c/ConductorOfCacophony.java b/Mage.Sets/src/mage/cards/c/ConductorOfCacophony.java index d174f8f15f7..7431c694616 100644 --- a/Mage.Sets/src/mage/cards/c/ConductorOfCacophony.java +++ b/Mage.Sets/src/mage/cards/c/ConductorOfCacophony.java @@ -25,7 +25,7 @@ import java.util.UUID; */ public final class ConductorOfCacophony extends CardImpl { - private static final FilterPermanent filter = new FilterCreaturePermanent("each other creature"); + private static final FilterPermanent filter = new FilterCreaturePermanent("other creature"); static { filter.add(AnotherPredicate.instance); diff --git a/Mage.Sets/src/mage/cards/c/Creeperhulk.java b/Mage.Sets/src/mage/cards/c/Creeperhulk.java index 2bd3b201b78..13ff5c0038b 100644 --- a/Mage.Sets/src/mage/cards/c/Creeperhulk.java +++ b/Mage.Sets/src/mage/cards/c/Creeperhulk.java @@ -1,31 +1,28 @@ - package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Creeperhulk extends CardImpl { public Creeperhulk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); this.subtype.add(SubType.PLANT); this.subtype.add(SubType.ELEMENTAL); @@ -34,12 +31,17 @@ public final class Creeperhulk extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); + // {1}{G}: Until end of turn, target creature you control has base power and toughness 5/5 and gains trample. - Effect effect = new SetBasePowerToughnessTargetEffect(5,5, Duration.EndOfTurn); - effect.setText("Until end of turn, target creature you control has base power and toughness 5/5"); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}{G}")); + Ability ability = new SimpleActivatedAbility( + new SetBasePowerToughnessTargetEffect(5, 5, Duration.EndOfTurn) + .setText("Until end of turn, target creature you control has base power and toughness 5/5"), + new ManaCostsImpl<>("{1}{G}") + ); + ability.addEffect(new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, "and gains trample" + )); ability.addTarget(new TargetControlledCreaturePermanent()); - ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, "and gains Trample")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CruelSadist.java b/Mage.Sets/src/mage/cards/c/CruelSadist.java index 8bdc715edac..74893c8170a 100644 --- a/Mage.Sets/src/mage/cards/c/CruelSadist.java +++ b/Mage.Sets/src/mage/cards/c/CruelSadist.java @@ -1,7 +1,5 @@ - package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,26 +9,25 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ColoredManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; 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.ColoredManaSymbol; -import mage.constants.Zone; +import mage.constants.SubType; import mage.counters.CounterType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author emerald000 */ public final class CruelSadist extends CardImpl { public CruelSadist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ASSASSIN); @@ -38,15 +35,18 @@ public final class CruelSadist extends CardImpl { this.toughness = new MageInt(1); // {B}, {T}, Pay 1 life: Put a +1/+1 counter on Cruel Sadist. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ColoredManaCost(ColoredManaSymbol.B)); + Ability ability = new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), + new ColoredManaCost(ColoredManaSymbol.B) + ); ability.addCost(new TapSourceCost()); ability.addCost(new PayLifeCost(1)); this.addAbility(ability); - + // {2}{B}, {T}, Remove X +1/+1 counters from Cruel Sadist: Cruel Sadist deals X damage to target creature. - Effect effect = new DamageTargetEffect(RemovedCountersForCostValue.instance); - effect.setText("{this} deals X damage to target creature"); - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}{B}")); + ability = new SimpleActivatedAbility( + new DamageTargetEffect(RemovedCountersForCostValue.instance, "it"), new ManaCostsImpl<>("{2}{B}") + ); ability.addCost(new TapSourceCost()); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.P1P1.createInstance())); ability.addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/d/DeemWorthy.java b/Mage.Sets/src/mage/cards/d/DeemWorthy.java index 17b1a80cf49..c7957683df1 100644 --- a/Mage.Sets/src/mage/cards/d/DeemWorthy.java +++ b/Mage.Sets/src/mage/cards/d/DeemWorthy.java @@ -1,8 +1,5 @@ - - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.CycleTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -13,30 +10,30 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; /** - * * @author Darkside- */ public final class DeemWorthy extends CardImpl { - public DeemWorthy (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}"); + public DeemWorthy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}"); - // Deem Worthy deals 7 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(7)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - - //Cycling {3}{R} + + // Cycling {3}{R} this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{3}{R}"))); + // When you cycle Deem Worthy, you may have it deal 2 damage to target creature. - Ability ability = new CycleTriggeredAbility(new DamageTargetEffect(2),true); + Ability ability = new CycleTriggeredAbility(new DamageTargetEffect(2).setText("it deal 2 damage to target creature"), true); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } - public DeemWorthy (final DeemWorthy card) { + public DeemWorthy(final DeemWorthy card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/d/DiscipleOfPerdition.java b/Mage.Sets/src/mage/cards/d/DiscipleOfPerdition.java index 813d4a095ff..b2b552ccf05 100644 --- a/Mage.Sets/src/mage/cards/d/DiscipleOfPerdition.java +++ b/Mage.Sets/src/mage/cards/d/DiscipleOfPerdition.java @@ -34,10 +34,10 @@ public final class DiscipleOfPerdition extends CardImpl { // When Disciple of Perdition dies, choose one. If you have exactly 13 life, you may choose both. // * You draw a card and you lose 1 life. - Ability ability = new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1), false); - ability.getModes().setChooseText("Choose one. If you have exactly 13 life, you may choose both."); + Ability ability = new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1, "you"), false); + ability.getModes().setChooseText("choose one. If you have exactly 13 life, you may choose both."); ability.getModes().setMoreCondition(DiscipleOfPerditionCondition.instance); - ability.addEffect(new LoseLifeSourceControllerEffect(1)); + ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); // * Exile target opponent's graveyard. That player loses 1 life. ability.addMode(new Mode(new ExileGraveyardAllTargetPlayerEffect() diff --git a/Mage.Sets/src/mage/cards/e/Enlarge.java b/Mage.Sets/src/mage/cards/e/Enlarge.java index a2b0038f263..365268ac1d1 100644 --- a/Mage.Sets/src/mage/cards/e/Enlarge.java +++ b/Mage.Sets/src/mage/cards/e/Enlarge.java @@ -1,8 +1,6 @@ package mage.cards.e; -import java.util.UUID; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; @@ -13,22 +11,25 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Enlarge extends CardImpl { public Enlarge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}"); // Target creature gets +7/+7 and gains trample until end of turn. It must be blocked this turn if able. - this.getSpellAbility().addEffect(new BoostTargetEffect(7,7, Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); - Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn); - effect.setText("It must be blocked this turn if able"); - this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addEffect(new BoostTargetEffect( + 7, 7, Duration.EndOfTurn + ).setText("target creature gets +7/+7")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains trample until end of turn")); + this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn) + .setText("It must be blocked this turn if able")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/f/FesteringEvil.java b/Mage.Sets/src/mage/cards/f/FesteringEvil.java index 1dc1add7282..4f3a9afe5d7 100644 --- a/Mage.Sets/src/mage/cards/f/FesteringEvil.java +++ b/Mage.Sets/src/mage/cards/f/FesteringEvil.java @@ -1,7 +1,5 @@ - package mage.cards.f; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -12,22 +10,26 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.TargetController; -import mage.constants.Zone; + +import java.util.UUID; /** - * * @author fireshoes */ public final class FesteringEvil extends CardImpl { public FesteringEvil(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); // At the beginning of your upkeep, Festering Evil deals 1 damage to each creature and each player. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DamageEverythingEffect(1), TargetController.YOU, false)); - + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new DamageEverythingEffect(1), TargetController.YOU, false + )); + // {B}{B}, Sacrifice Festering Evil: Festering Evil deals 3 damage to each creature and each player. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(3), new ManaCostsImpl<>("{B}{B}")); + Ability ability = new SimpleActivatedAbility( + new DamageEverythingEffect(3, "it"), new ManaCostsImpl<>("{B}{B}") + ); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/Fireslinger.java b/Mage.Sets/src/mage/cards/f/Fireslinger.java index 11a3414fc3f..d0312a29d12 100644 --- a/Mage.Sets/src/mage/cards/f/Fireslinger.java +++ b/Mage.Sets/src/mage/cards/f/Fireslinger.java @@ -1,7 +1,5 @@ - package mage.cards.f; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -12,24 +10,24 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author Loki */ public final class Fireslinger extends CardImpl { public Fireslinger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(1); this.toughness = new MageInt(1); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); - ability.addEffect(new DamageControllerEffect(1)); + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost()); + ability.addEffect(new DamageControllerEffect(1).setText("and 1 damage to you")); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java index 9a6431cad32..485f95d4f93 100644 --- a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java +++ b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java @@ -38,7 +38,7 @@ public final class Gigantoplasm extends CardImpl { // You may have Gigantoplasm enter the battlefield as a copy of any creature on the battlefield, except it has "{X}: This creature has base power and toughness X/X." Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new GigantoplasmCopyApplier()); - effect.setText("a copy of any creature on the battlefield, except it has \"{X}: This creature has base power and toughness X/X.\""); + effect.setText("as a copy of any creature on the battlefield, except it has \"{X}: This creature has base power and toughness X/X.\""); this.addAbility(new EntersBattlefieldAbility(effect, true)); } diff --git a/Mage.Sets/src/mage/cards/g/GnawingZombie.java b/Mage.Sets/src/mage/cards/g/GnawingZombie.java index 1ccc00ed40e..84bfcd43a3f 100644 --- a/Mage.Sets/src/mage/cards/g/GnawingZombie.java +++ b/Mage.Sets/src/mage/cards/g/GnawingZombie.java @@ -1,7 +1,5 @@ - package mage.cards.g; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -14,12 +12,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; import mage.target.TargetPlayer; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + +import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; + /** - * * @author LevelX2 */ public final class GnawingZombie extends CardImpl { @@ -33,7 +33,7 @@ public final class GnawingZombie extends CardImpl { // {1}{B}, Sacrifice a creature: Target player loses 1 life and you gain 1 life. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1), new ManaCostsImpl<>("{1}{B}")); - ability.addEffect(new GainLifeEffect(1)); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addTarget(new TargetPlayer()); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GorgingVulture.java b/Mage.Sets/src/mage/cards/g/GorgingVulture.java index 23690844522..263917dbd53 100644 --- a/Mage.Sets/src/mage/cards/g/GorgingVulture.java +++ b/Mage.Sets/src/mage/cards/g/GorgingVulture.java @@ -49,7 +49,7 @@ class GorgingVultureEffect extends OneShotEffect { GorgingVultureEffect() { super(Outcome.Benefit); - staticText = "mill four cards. You gain 1 life for each creature card put into your graveyard this way."; + staticText = "mill four cards. You gain 1 life for each creature card milled this way."; } private GorgingVultureEffect(final GorgingVultureEffect effect) { diff --git a/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java b/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java index 73e95363a93..09a4d0f410b 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java +++ b/Mage.Sets/src/mage/cards/j/JaceArcaneStrategist.java @@ -42,7 +42,7 @@ public final class JaceArcaneStrategist extends CardImpl { // -7: Creatures you control can't be blocked this turn. this.addAbility(new LoyaltyAbility(new CantBeBlockedAllEffect( - StaticFilters.FILTER_CONTROLLED_CREATURE, Duration.EndOfTurn + StaticFilters.FILTER_CONTROLLED_CREATURES, Duration.EndOfTurn ), -7)); } diff --git a/Mage.Sets/src/mage/cards/j/JacesScrutiny.java b/Mage.Sets/src/mage/cards/j/JacesScrutiny.java index 155f58ea6c4..5bfa8a9c496 100644 --- a/Mage.Sets/src/mage/cards/j/JacesScrutiny.java +++ b/Mage.Sets/src/mage/cards/j/JacesScrutiny.java @@ -1,7 +1,5 @@ - package mage.cards.j; -import java.util.UUID; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.keyword.InvestigateEffect; import mage.cards.CardImpl; @@ -10,21 +8,22 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author fireshoes */ public final class JacesScrutiny extends CardImpl { public JacesScrutiny(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Target creature gets -4/-0 until end of turn. getSpellAbility().addEffect(new BoostTargetEffect(-4, -0, Duration.EndOfTurn)); getSpellAbility().addTarget(new TargetCreaturePermanent()); // Investigate - getSpellAbility().addEffect(new InvestigateEffect()); + getSpellAbility().addEffect(new InvestigateEffect().concatBy("
")); } private JacesScrutiny(final JacesScrutiny card) { diff --git a/Mage.Sets/src/mage/cards/k/KiboUktabiPrince.java b/Mage.Sets/src/mage/cards/k/KiboUktabiPrince.java index 598e5afd3db..ba93d34aff5 100644 --- a/Mage.Sets/src/mage/cards/k/KiboUktabiPrince.java +++ b/Mage.Sets/src/mage/cards/k/KiboUktabiPrince.java @@ -27,7 +27,7 @@ import java.util.UUID; public final class KiboUktabiPrince extends CardImpl { private static final FilterPermanent filter - = new FilterControlledCreaturePermanent("creature you control that's an Ape or Monkey"); + = new FilterControlledCreaturePermanent("creature you control that's an Ape or a Monkey"); private static final FilterPermanent filter2 = new FilterArtifactPermanent("an artifact an opponent controls"); diff --git a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java index 63fee125b88..79df2cbeb21 100644 --- a/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java +++ b/Mage.Sets/src/mage/cards/l/LookoutsDispersal.java @@ -8,6 +8,7 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -23,20 +24,23 @@ import java.util.UUID; */ public final class LookoutsDispersal extends CardImpl { - private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Pirate"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("you control a Pirate"); static { filter.add(SubType.PIRATE.getPredicate()); } + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); + private static final Hint hint = new ConditionHint(condition, "You control a Pirate"); + public LookoutsDispersal(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Lookout's Dispersal costs {1} less to cast if you control a Pirate. - Condition condition = new PermanentsOnTheBattlefieldCondition(filter); + Ability ability = new SimpleStaticAbility(Zone.ALL, new SpellCostReductionSourceEffect(1, condition)); ability.setRuleAtTheTop(true); - ability.addHint(new ConditionHint(condition, "You control a Pirate")); + ability.addHint(hint); this.addAbility(ability); // Counter target spell unless its controller pays {4}. diff --git a/Mage.Sets/src/mage/cards/l/LumengridSentinel.java b/Mage.Sets/src/mage/cards/l/LumengridSentinel.java index 62a408ddc51..c0d07b4eb70 100644 --- a/Mage.Sets/src/mage/cards/l/LumengridSentinel.java +++ b/Mage.Sets/src/mage/cards/l/LumengridSentinel.java @@ -1,10 +1,8 @@ - package mage.cards.l; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -12,11 +10,12 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledArtifactPermanent; +import mage.filter.StaticFilters; import mage.target.TargetPermanent; +import java.util.UUID; + /** - * * @author fireshoes */ public final class LumengridSentinel extends CardImpl { @@ -32,7 +31,9 @@ public final class LumengridSentinel extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever an artifact enters the battlefield under your control, you may tap target permanent. - Ability ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new FilterControlledArtifactPermanent("an artifact"), true); + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, new TapTargetEffect(), StaticFilters.FILTER_PERMANENT_ARTIFACT_AN, true + ); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MirrorImage.java b/Mage.Sets/src/mage/cards/m/MirrorImage.java index e45a870f885..783fe376477 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorImage.java +++ b/Mage.Sets/src/mage/cards/m/MirrorImage.java @@ -26,8 +26,7 @@ public final class MirrorImage extends CardImpl { // You may have Mirror Image enter the battlefield as a copy of any creature you control. this.addAbility(new EntersBattlefieldAbility( new CopyPermanentEffect(StaticFilters.FILTER_CONTROLLED_CREATURE) - .setText("you may have {this} enter the battlefield " - + "as a copy of a creature you control"), + .setText("as a copy of a creature you control"), true )); } diff --git a/Mage.Sets/src/mage/cards/m/MonkeyCage.java b/Mage.Sets/src/mage/cards/m/MonkeyCage.java index 206b4325c6d..294c003e25f 100644 --- a/Mage.Sets/src/mage/cards/m/MonkeyCage.java +++ b/Mage.Sets/src/mage/cards/m/MonkeyCage.java @@ -1,11 +1,8 @@ - package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -18,8 +15,9 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.ApeToken; +import java.util.UUID; + /** - * * @author LoneFox */ public final class MonkeyCage extends CardImpl { @@ -28,8 +26,10 @@ public final class MonkeyCage extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); // When a creature enters the battlefield, sacrifice Monkey Cage and create X 2/2 green Ape creature tokens, where X is that creature's converted mana cost. - Ability ability = new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceEffect(), - StaticFilters.FILTER_PERMANENT_A_CREATURE, false, SetTargetPointer.PERMANENT, ""); + Ability ability = new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new SacrificeSourceEffect(), StaticFilters.FILTER_PERMANENT_A_CREATURE, + false, SetTargetPointer.PERMANENT, null + ).setTriggerPhrase("When a creature enters the battlefield, "); ability.addEffect(new MonkeyCageEffect()); this.addAbility(ability); } @@ -62,10 +62,10 @@ class MonkeyCageEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent creature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); - if (creature != null) { - int cmc = creature.getManaValue(); - return new CreateTokenEffect(new ApeToken(), cmc).apply(game, source); + if (creature == null) { + return false; } - return false; + int cmc = creature.getManaValue(); + return cmc > 0 && new ApeToken().putOntoBattlefield(cmc, game, source); } } diff --git a/Mage.Sets/src/mage/cards/m/MoodmarkPainter.java b/Mage.Sets/src/mage/cards/m/MoodmarkPainter.java index 98c91f2c0a0..dfc65510fbb 100644 --- a/Mage.Sets/src/mage/cards/m/MoodmarkPainter.java +++ b/Mage.Sets/src/mage/cards/m/MoodmarkPainter.java @@ -1,6 +1,5 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; @@ -10,17 +9,18 @@ import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.MenaceAbility; -import mage.constants.AbilityWord; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class MoodmarkPainter extends CardImpl { @@ -39,7 +39,7 @@ public final class MoodmarkPainter extends CardImpl { new GainAbilityTargetEffect( new MenaceAbility(false), Duration.EndOfTurn - ).setText("target creature gains menace."), + ).setText("target creature gains menace"), false); // target creature gains menace and gets +X/+0 until end of turn, // where X is the number of creature cards in your graveyard. diff --git a/Mage.Sets/src/mage/cards/m/MoonlightHunt.java b/Mage.Sets/src/mage/cards/m/MoonlightHunt.java index fefa370eb28..43afb96001b 100644 --- a/Mage.Sets/src/mage/cards/m/MoonlightHunt.java +++ b/Mage.Sets/src/mage/cards/m/MoonlightHunt.java @@ -50,7 +50,7 @@ class MoonlightHuntEffect extends OneShotEffect { MoonlightHuntEffect() { super(Outcome.Damage); - this.staticText = "Choose target creature you don't control. Each creature you control that's a Wolf or Werewolf deals damage equal to its power to that creature"; + this.staticText = "Choose target creature you don't control. Each creature you control that's a Wolf or a Werewolf deals damage equal to its power to that creature"; } private MoonlightHuntEffect(final MoonlightHuntEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NoEscape.java b/Mage.Sets/src/mage/cards/n/NoEscape.java index 9b128b9469b..c59a2ca305f 100644 --- a/Mage.Sets/src/mage/cards/n/NoEscape.java +++ b/Mage.Sets/src/mage/cards/n/NoEscape.java @@ -34,7 +34,7 @@ public final class NoEscape extends CardImpl { this.getSpellAbility().addTarget(new TargetSpell(filter)); // Scry 1. - this.getSpellAbility().addEffect(new ScryEffect(1, false)); + this.getSpellAbility().addEffect(new ScryEffect(1, false).concatBy("
")); } private NoEscape(final NoEscape card) { diff --git a/Mage.Sets/src/mage/cards/o/Overgrowth.java b/Mage.Sets/src/mage/cards/o/Overgrowth.java index 298546daecc..f1a9140d222 100644 --- a/Mage.Sets/src/mage/cards/o/Overgrowth.java +++ b/Mage.Sets/src/mage/cards/o/Overgrowth.java @@ -35,7 +35,7 @@ public final class Overgrowth extends CardImpl { // Whenever enchanted land is tapped for mana, its controller adds {G}{G}. this.addAbility(new EnchantedTappedTriggeredManaAbility(new AddManaToManaPoolTargetControllerEffect( Mana.GreenMana(2), "their" - ))); + ).setText("its controller adds an additional {G}{G}"))); } private Overgrowth(final Overgrowth card) { diff --git a/Mage.Sets/src/mage/cards/p/PiratedCopy.java b/Mage.Sets/src/mage/cards/p/PiratedCopy.java index fcdabe53f8a..83b8e8ee5fd 100644 --- a/Mage.Sets/src/mage/cards/p/PiratedCopy.java +++ b/Mage.Sets/src/mage/cards/p/PiratedCopy.java @@ -46,7 +46,7 @@ public final class PiratedCopy extends CardImpl { } @Override - public String toString() { + public String getText() { return ", except it's a Pirate in addition to its other types and it has \"Whenever this creature " + "or another creature with the same name deals combat damage to a player, you may draw a card.\""; } diff --git a/Mage.Sets/src/mage/cards/p/PressForAnswers.java b/Mage.Sets/src/mage/cards/p/PressForAnswers.java index 67b07070255..eb273332f8f 100644 --- a/Mage.Sets/src/mage/cards/p/PressForAnswers.java +++ b/Mage.Sets/src/mage/cards/p/PressForAnswers.java @@ -1,8 +1,6 @@ package mage.cards.p; -import java.util.UUID; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.keyword.InvestigateEffect; @@ -11,25 +9,23 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class PressForAnswers extends CardImpl { public PressForAnswers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); // Tap target creature. It doesn't untap during its controller's next untap step. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new TapTargetEffect()); this.getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect("It")); - // Investigate. (Create a colorless Clue artifact token with "2, Sacrifice this artifact: Draw a card.") - Effect effect = new InvestigateEffect(); - effect.setText("
Investigate. (Create a colorless Clue artifact token with \"2, Sacrifice this artifact: Draw a card.\")"); - this.getSpellAbility().addEffect(effect); - + // Investigate. + this.getSpellAbility().addEffect(new InvestigateEffect().concatBy("
")); } private PressForAnswers(final PressForAnswers card) { diff --git a/Mage.Sets/src/mage/cards/r/RuthlessDisposal.java b/Mage.Sets/src/mage/cards/r/RuthlessDisposal.java index b388fe9c942..0bc8be6060f 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessDisposal.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessDisposal.java @@ -1,24 +1,19 @@ - package mage.cards.r; -import java.util.UUID; -import mage.abilities.costs.Cost; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.CompositeCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.FilterCard; -import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; -import mage.target.common.TargetCardInHand; -import mage.target.common.TargetControlledCreaturePermanent; +import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class RuthlessDisposal extends CardImpl { @@ -27,17 +22,16 @@ public final class RuthlessDisposal extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // As an additional cost to cast Ruthless Disposal, discard a card and sacrifice a creature. - this.getSpellAbility().addCost(new DiscardTargetCost(new TargetCardInHand(new FilterCard("a card")))); - Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); - cost.setText("as an additional cost to cast this spell, sacrifice a creature"); - this.getSpellAbility().addCost(cost); + this.getSpellAbility().addCost(new CompositeCost( + new DiscardCardCost(), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), + "discard a card and sacrifice a creature" + )); // Two target creatures each get -13/-13 until end of turn. - Effect effect = new BoostTargetEffect(-13, -13, Duration.EndOfTurn); - effect.setText("Two target creatures each get -13/-13 until end of turn"); + this.getSpellAbility().addEffect(new BoostTargetEffect(-13, -13, Duration.EndOfTurn) + .setText("Two target creatures each get -13/-13 until end of turn")); this.getSpellAbility().addTarget(new TargetCreaturePermanent(2)); - this.getSpellAbility().addEffect(effect); - } private RuthlessDisposal(final RuthlessDisposal card) { diff --git a/Mage.Sets/src/mage/cards/s/SagesReverie.java b/Mage.Sets/src/mage/cards/s/SagesReverie.java index 280baed9ec0..21cef4d98da 100644 --- a/Mage.Sets/src/mage/cards/s/SagesReverie.java +++ b/Mage.Sets/src/mage/cards/s/SagesReverie.java @@ -1,21 +1,22 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicate; import mage.game.Game; @@ -23,20 +24,26 @@ import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author emerald000 */ public final class SagesReverie extends CardImpl { - - private static final FilterControlledPermanent filter = new FilterControlledPermanent("aura you control that's attached to a creature"); + + private static final FilterPermanent filter = new FilterControlledPermanent( + SubType.AURA, "Aura you control that's attached to a creature" + ); + static { - filter.add(SubType.AURA.getPredicate()); - filter.add(new SagesReveriePredicate()); + filter.add(SagesReveriePredicate.instance); } + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter); + private static final Hint hint = new ValueHint("Auras you control that are attached to creatures", xValue); + public SagesReverie(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); this.subtype.add(SubType.AURA); // Enchant creature @@ -45,12 +52,12 @@ public final class SagesReverie extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget); this.addAbility(ability); - + // When Sage's Reverie enters the battlefield, draw a card for each aura you control that's attached to a creature. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(new PermanentsOnBattlefieldCount(filter)))); - + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(xValue))); + // Enchanted creature gets +1/+1 for each aura you control that's attached to a creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(new PermanentsOnBattlefieldCount(filter), new PermanentsOnBattlefieldCount(filter)))); + this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(xValue, xValue)).addHint(hint)); } private SagesReverie(final SagesReverie card) { @@ -63,12 +70,12 @@ public final class SagesReverie extends CardImpl { } } -class SagesReveriePredicate implements Predicate { +enum SagesReveriePredicate implements Predicate { + instance; @Override public boolean apply(Permanent input, Game game) { - UUID attachedTo = input.getAttachedTo(); - Permanent attachedToPermanent = game.getPermanent(attachedTo); + Permanent attachedToPermanent = game.getPermanent(input.getAttachedTo()); return attachedToPermanent != null && attachedToPermanent.isCreature(game); } diff --git a/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java b/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java index 39736d64df8..bf97d9ab2e3 100644 --- a/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java +++ b/Mage.Sets/src/mage/cards/s/SvyelunOfSeaAndSky.java @@ -19,7 +19,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; import java.util.UUID; @@ -29,7 +28,7 @@ import java.util.UUID; */ public final class SvyelunOfSeaAndSky extends CardImpl { - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.MERFOLK); + private static final FilterPermanent filter = new FilterPermanent(SubType.MERFOLK, "Merfolk"); static { filter.add(AnotherPredicate.instance); diff --git a/Mage.Sets/src/mage/cards/s/SynchronizedEviction.java b/Mage.Sets/src/mage/cards/s/SynchronizedEviction.java index b6235460788..32193164dcd 100644 --- a/Mage.Sets/src/mage/cards/s/SynchronizedEviction.java +++ b/Mage.Sets/src/mage/cards/s/SynchronizedEviction.java @@ -57,7 +57,7 @@ enum SynchronizedEvictionCondition implements Condition { @Override public String toString() { - return "you control two or more creatures that share a creature type"; + return "you control at least two creatures that share a creature type"; } } diff --git a/Mage.Sets/src/mage/cards/t/TalonOfPain.java b/Mage.Sets/src/mage/cards/t/TalonOfPain.java index 3ab198b481e..7e1923e33db 100644 --- a/Mage.Sets/src/mage/cards/t/TalonOfPain.java +++ b/Mage.Sets/src/mage/cards/t/TalonOfPain.java @@ -42,7 +42,7 @@ public final class TalonOfPain extends CardImpl { this.addAbility(new TalonOfPainTriggeredAbility()); // {X}, {T}, Remove X charge counters from Talon of Pain: Talon of Pain deals X damage to any target. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.REGULAR), new ManaCostsImpl<>("{X}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.REGULAR, "it"), new ManaCostsImpl<>("{X}")); ability.addCost(new TapSourceCost()); ability.addCost(new TalonOfPainRemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance())); ability.addTarget(new TargetAnyTarget()); diff --git a/Mage.Sets/src/mage/cards/t/TaskForce.java b/Mage.Sets/src/mage/cards/t/TaskForce.java index 2d4b1d49362..96774aca663 100644 --- a/Mage.Sets/src/mage/cards/t/TaskForce.java +++ b/Mage.Sets/src/mage/cards/t/TaskForce.java @@ -1,33 +1,33 @@ - - package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesTargetTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; /** - * * @author Backfir3 */ public final class TaskForce extends CardImpl { public TaskForce(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.REBEL); this.power = new MageInt(1); this.toughness = new MageInt(3); - // Whenever Task Force becomes the target of a spell or ability, it gets +0/+3 until end of turn. - this.addAbility(new BecomesTargetTriggeredAbility(new BoostSourceEffect(0, 3, Duration.EndOfTurn))); + // Whenever Task Force becomes the target of a spell or ability, it gets +0/+3 until end of turn. + this.addAbility(new BecomesTargetTriggeredAbility( + new BoostSourceEffect(0, 3, Duration.EndOfTurn, "it") + ).setTriggerPhrase("Whenever {this} becomes the target of a spell or ability, ")); } private TaskForce(final TaskForce card) { diff --git a/Mage.Sets/src/mage/cards/t/TezzeretArtificeMaster.java b/Mage.Sets/src/mage/cards/t/TezzeretArtificeMaster.java index d84a8477d72..a9448e1271f 100644 --- a/Mage.Sets/src/mage/cards/t/TezzeretArtificeMaster.java +++ b/Mage.Sets/src/mage/cards/t/TezzeretArtificeMaster.java @@ -9,7 +9,6 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.hint.common.MetalcraftHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; @@ -37,12 +36,9 @@ public final class TezzeretArtificeMaster extends CardImpl { this.addAbility(new LoyaltyAbility(new ConditionalOneShotEffect( new DrawCardSourceControllerEffect(2), new DrawCardSourceControllerEffect(1), - MetalcraftCondition.instance, - "Draw a card. If you control three or " - + "more artifacts, draw two cards instead" - ), 0) - .setAbilityWord(AbilityWord.METALCRAFT) - .addHint(MetalcraftHint.instance)); + MetalcraftCondition.instance, "Draw a card. " + + "If you control three or more artifacts, draw two cards instead" + ), 0).addHint(MetalcraftHint.instance)); // −9: You get an emblem with "At the beginning of your end step, search your library for a permanent card, put it into the battlefield, then shuffle your library." this.addAbility(new LoyaltyAbility( diff --git a/Mage.Sets/src/mage/cards/v/VedalkenEngineer.java b/Mage.Sets/src/mage/cards/v/VedalkenEngineer.java index f4f3ae2a841..2af48a67544 100644 --- a/Mage.Sets/src/mage/cards/v/VedalkenEngineer.java +++ b/Mage.Sets/src/mage/cards/v/VedalkenEngineer.java @@ -19,6 +19,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; +import mage.util.CardUtil; import java.util.ArrayList; import java.util.List; @@ -90,7 +91,7 @@ class VedalkenEngineerEffect extends ManaEffect { super(); this.amount = amount; this.manaBuilder = manaBuilder; - staticText = "Add " + amount + " mana of any one color. " + manaBuilder.getRule(); + staticText = "Add " + CardUtil.numberToText(amount) + " mana of any one color. " + manaBuilder.getRule(); } public VedalkenEngineerEffect(final VedalkenEngineerEffect effect) { diff --git a/Mage.Sets/src/mage/cards/v/ViashinoPyromancer.java b/Mage.Sets/src/mage/cards/v/ViashinoPyromancer.java index 3f9e23bb65f..b284f72fae9 100644 --- a/Mage.Sets/src/mage/cards/v/ViashinoPyromancer.java +++ b/Mage.Sets/src/mage/cards/v/ViashinoPyromancer.java @@ -1,18 +1,18 @@ package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.target.common.TargetPlayerOrPlaneswalker; +import java.util.UUID; + /** - * * @author TheElk801 */ public final class ViashinoPyromancer extends CardImpl { @@ -26,7 +26,7 @@ public final class ViashinoPyromancer extends CardImpl { this.toughness = new MageInt(1); // When Viashino Pyromancer enters the battlefield, it deals 2 damage to target player or planeswalker. - Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2)); + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2, "it")); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/z/ZaskSkitteringSwarmlord.java b/Mage.Sets/src/mage/cards/z/ZaskSkitteringSwarmlord.java index dbf22c119c2..20a78654e1e 100644 --- a/Mage.Sets/src/mage/cards/z/ZaskSkitteringSwarmlord.java +++ b/Mage.Sets/src/mage/cards/z/ZaskSkitteringSwarmlord.java @@ -59,8 +59,9 @@ public final class ZaskSkitteringSwarmlord extends CardImpl { // {1}{B/G}: Target Insect gets +1/+0 and gains deathtouch until end of turn. SimpleActivatedAbility ability2 = new SimpleActivatedAbility( - Zone.BATTLEFIELD, new BoostTargetEffect(1, 0, Duration.EndOfTurn) - .setText("Target Insect gets +1/0"), new ManaCostsImpl<>("{1}{B/G}") + new BoostTargetEffect(1, 0, Duration.EndOfTurn) + .setText("Target Insect gets +1/+0"), + new ManaCostsImpl<>("{1}{B/G}") ); ability2.addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn) .setText(" and gains deathtouch until end of turn")); diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 82273c43f49..a292572cc17 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -58,7 +58,7 @@ public class VerifyCardDataTest { private static final Logger logger = Logger.getLogger(VerifyCardDataTest.class); - private static final String FULL_ABILITIES_CHECK_SET_CODE = "ONE"; // check all abilities and output cards with wrong abilities texts; + private static final String FULL_ABILITIES_CHECK_SET_CODE = "J22"; // check all abilities and output cards with wrong abilities texts; private static final boolean CHECK_ONLY_ABILITIES_TEXT = false; // use when checking text locally, suppresses unnecessary checks and output messages private static final boolean AUTO_FIX_SAMPLE_DECKS = false; // debug only: auto-fix sample decks by test_checkSampleDecks test run @@ -87,18 +87,13 @@ public class VerifyCardDataTest { "plainswalk", "islandwalk", "swampwalk", "mountainwalk", "forestwalk", "myriad", "prowess", "convoke" ); - private static final List doubleWords = new ArrayList<>(); + private static final List doubleNumbers = new ArrayList<>(); { - // numbers for (int i = 1; i <= 9; i++) { String s = CardUtil.numberToText(i).toLowerCase(Locale.ENGLISH); - doubleWords.add(s + " " + s); + doubleNumbers.add(s + " " + s); } - - // additional checks - doubleWords.add(" an an "); - doubleWords.add(" a a "); } static { @@ -284,7 +279,7 @@ public class VerifyCardDataTest { } @Test - public void test_verifyCards() { + public void test_verifyCards() throws IOException { int cardIndex = 0; for (Card card : CardScanner.getAllCards()) { cardIndex++; @@ -1689,15 +1684,15 @@ public class VerifyCardDataTest { fail(card, "abilities", "mutate cards aren't implemented and shouldn't be available"); } - // special check: duplicated words in ability text (wrong target/filter usage) + // special check: duplicated numbers in ability text (wrong target/filter usage) // example: You may exile __two two__ blue cards // possible fixes: // - remove numbers from filter's text // - use target.getDescription() in ability instead target.getTargetName() for (String rule : card.getRules()) { - for (String doubleNumber : doubleWords) { - if (rule.toLowerCase(Locale.ENGLISH).contains(doubleNumber)) { - fail(card, "abilities", "duplicated numbers/words: " + rule); + for (String doubleNumber : doubleNumbers) { + if (rule.contains(doubleNumber)) { + fail(card, "abilities", "duplicated numbers: " + rule); } } } @@ -1797,29 +1792,18 @@ public class VerifyCardDataTest { } @Test - public void test_showCardInfo() { - // debug only: show direct card info from class file without db-recreate - // - search by card name: Spark Double - // - search by class name: SparkDouble - // - multiple searches: name1;class2;name3 - String cardSearches = "Spark Double"; + public void test_showCardInfo() throws Exception { + // debug only: show direct card info (takes it from class file, not from db repository) + // can check multiple cards at once, example: name1;name2;name3 + String cardNames = "Spark Double"; CardScanner.scan(); - Arrays.stream(cardSearches.split(";")).forEach(searchName -> { - searchName = searchName.trim(); - CardInfo cardInfo = CardRepository.instance.findCard(searchName); + Arrays.stream(cardNames.split(";")).forEach(cardName -> { + cardName = cardName.trim(); + CardSetInfo testSet = new CardSetInfo(cardName, "test", "123", Rarity.COMMON); + CardInfo cardInfo = CardRepository.instance.findCard(cardName); if (cardInfo == null) { - String searchClass = String.format("mage.cards.%s.%s", - searchName.substring(0, 1).toLowerCase(Locale.ENGLISH), - searchName); - cardInfo = CardRepository.instance.findCardsByClass(searchClass) - .stream() - .findFirst() - .orElse(null); + Assert.fail("Can't find card name: " + cardName); } - if (cardInfo == null) { - Assert.fail("Can't find card by name or class: " + searchName); - } - CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), "test", "123", Rarity.COMMON); Card card = CardImpl.createCard(cardInfo.getClassName(), testSet); System.out.println(); System.out.println(card.getName() + " " + card.getManaCost().getText()); @@ -2213,12 +2197,11 @@ public class VerifyCardDataTest { @Test public void test_checkCardConstructors() { - // create all cards, can catch additional verify and runtime checks from abilities and effects - // example: wrong code usage errors Collection errorsList = new ArrayList<>(); Collection sets = Sets.getInstance().values(); for (ExpansionSet set : sets) { for (ExpansionSet.SetCardInfo setInfo : set.getSetCardInfo()) { + // catch cards creation errors and report (e.g. on wrong card code or construction checks fail) try { Card card = CardImpl.createCard(setInfo.getCardClass(), new CardSetInfo(setInfo.getName(), set.getCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo())); diff --git a/Mage/src/main/java/mage/abilities/common/DrawNthCardTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DrawNthCardTriggeredAbility.java index 458a507294d..1265b781146 100644 --- a/Mage/src/main/java/mage/abilities/common/DrawNthCardTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DrawNthCardTriggeredAbility.java @@ -11,6 +11,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import mage.util.CardUtil; import mage.watchers.Watcher; import java.util.*; @@ -82,11 +83,11 @@ public class DrawNthCardTriggeredAbility extends TriggeredAbilityImpl { public String generateTriggerPhrase() { switch (targetController) { case YOU: - return "Whenever you draw your second card each turn, "; + return "Whenever you draw your " + CardUtil.numberToOrdinalText(cardNumber) + " card each turn, "; case ACTIVE: - return "Whenever a player draws their second card during their turn, "; + return "Whenever a player draws their " + CardUtil.numberToOrdinalText(cardNumber) + " card during their turn, "; case OPPONENT: - return "Whenever an opponent draws their second card each turn, "; + return "Whenever an opponent draws their " + CardUtil.numberToOrdinalText(cardNumber) + " card each turn, "; default: throw new IllegalArgumentException("TargetController " + targetController + " not supported"); } @@ -122,10 +123,10 @@ class DrawCardWatcher extends Watcher { super.reset(); drawMap.clear(); } - + static boolean checkEvent(UUID playerId, GameEvent event, Game game, int cardNumber) { Map> drawMap = game.getState().getWatcher(DrawCardWatcher.class).drawMap; return drawMap.containsKey(playerId) && Objects.equals(drawMap.get(playerId).size(), cardNumber) && event.getId().equals(drawMap.get(playerId).get(cardNumber - 1)); } - + }