diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java index 6b0f0dab25..7281e662c8 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/MTGO1v1Commander.java @@ -36,17 +36,20 @@ public class MTGO1v1Commander extends Commander { public MTGO1v1Commander() { super("MTGO 1v1 Commander"); banned.add("Ancestral Recall"); - banned.add("Arcum Dagsson"); banned.add("Back to Basics"); banned.add("Balance"); + banned.add("Baral, Chief of Compliance"); banned.add("Bazaar of Baghdad"); banned.add("Black Lotus"); banned.add("Braids, Cabal Minion"); banned.add("Brainstorm"); banned.add("Channel"); banned.add("Derevi, Empyrial Tactician"); + banned.add("Demonic Tutor"); banned.add("Dig Through Time"); banned.add("Edric, Spymaster of Trest"); + banned.add("Emrakul, the Aeons Torn"); + banned.add("Enlightened Tutor"); banned.add("Entomb"); banned.add("Fastbond"); banned.add("Food Chain"); @@ -55,6 +58,7 @@ public class MTGO1v1Commander extends Commander { banned.add("Griselbrand"); banned.add("Hermit Druid"); banned.add("Humility"); + banned.add("Imperial Seal"); banned.add("Karakas"); banned.add("Library of Alexandria"); banned.add("Mana Crypt"); @@ -68,6 +72,7 @@ public class MTGO1v1Commander extends Commander { banned.add("Mox Pearl"); banned.add("Mox Ruby"); banned.add("Mox Sapphire"); + banned.add("Mystical Tutor"); banned.add("Natural Order"); banned.add("Necropotence"); banned.add("Oath of Druids"); @@ -88,8 +93,8 @@ public class MTGO1v1Commander extends Commander { banned.add("Treachery"); banned.add("Treasure Cruise"); banned.add("Vial Smasher the Fierce"); + banned.add("Vampiric Tutor"); banned.add("Yamgmoth's Bargain"); - banned.add("Yisan, the Wanderer Bard"); banned.add("Zur the Enchanter"); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/a/ActOfAggression.java b/Mage.Sets/src/mage/cards/a/ActOfAggression.java index 0c17193e5e..5e05507247 100644 --- a/Mage.Sets/src/mage/cards/a/ActOfAggression.java +++ b/Mage.Sets/src/mage/cards/a/ActOfAggression.java @@ -54,12 +54,11 @@ public class ActOfAggression extends CardImpl { } public ActOfAggression(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R/P}{R/P}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R/P}{R/P}"); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public ActOfAggression(final ActOfAggression card) { diff --git a/Mage.Sets/src/mage/cards/a/ActOfTreason.java b/Mage.Sets/src/mage/cards/a/ActOfTreason.java index c402523712..bed4e24e0c 100644 --- a/Mage.Sets/src/mage/cards/a/ActOfTreason.java +++ b/Mage.Sets/src/mage/cards/a/ActOfTreason.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.a; import java.util.UUID; @@ -46,16 +45,14 @@ import mage.target.common.TargetCreaturePermanent; public class ActOfTreason extends CardImpl { public ActOfTreason(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // Gain control of target creature until end of turn. Untap that creature. // It gains haste until end of turn. (It can attack and {T} this turn.) this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public ActOfTreason(final ActOfTreason card) { diff --git a/Mage.Sets/src/mage/cards/a/AltarGolem.java b/Mage.Sets/src/mage/cards/a/AltarGolem.java index 551314c24d..40a7fad949 100644 --- a/Mage.Sets/src/mage/cards/a/AltarGolem.java +++ b/Mage.Sets/src/mage/cards/a/AltarGolem.java @@ -53,18 +53,18 @@ import mage.target.common.TargetControlledCreaturePermanent; /** * * @author jeffwadsworth - + * */ public class AltarGolem extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control"); - + static { filter.add(Predicates.not(new TappedPredicate())); } public AltarGolem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{7}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); this.subtype.add(SubType.GOLEM); this.power = new MageInt(0); @@ -72,17 +72,17 @@ public class AltarGolem extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - + // Altar Golem's power and toughness are each equal to the number of creatures on the battlefield. - DynamicValue amount = new PermanentsOnBattlefieldCount(new FilterCreaturePermanent("creatures in play")); + DynamicValue amount = new PermanentsOnBattlefieldCount(new FilterCreaturePermanent("creatures on the battlefield")); this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(amount, Duration.EndOfGame))); - + // Altar Golem doesn't untap during your untap step. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); - + // Tap five untapped creatures you control: Untap Altar Golem. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(5, 5, filter, true)))); - + } public AltarGolem(final AltarGolem card) { diff --git a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java index 1177fc15e2..9b0993799e 100644 --- a/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java +++ b/Mage.Sets/src/mage/cards/b/BattlefieldThaumaturge.java @@ -55,7 +55,7 @@ import mage.util.CardUtil; public class BattlefieldThaumaturge extends CardImpl { public BattlefieldThaumaturge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.HUMAN, SubType.WIZARD); this.power = new MageInt(2); @@ -79,10 +79,9 @@ public class BattlefieldThaumaturge extends CardImpl { class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEffectImpl { - public BattlefieldThaumaturgeSpellsCostReductionEffect() { super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); - this.staticText = "Each instant and sorcery spell you cast costs 1 less to cast for each creature it targets"; + this.staticText = "Each instant and sorcery spell you cast costs {1} less to cast for each creature it targets"; } protected BattlefieldThaumaturgeSpellsCostReductionEffect(BattlefieldThaumaturgeSpellsCostReductionEffect effect) { @@ -92,9 +91,9 @@ class BattlefieldThaumaturgeSpellsCostReductionEffect extends CostModificationEf @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { Set creaturesTargeted = new HashSet<>(); - for (Target target: abilityToModify.getTargets()) { - for (UUID uuid: target.getTargets()) { - Permanent permanent = game.getPermanent(uuid); + for (Target target : abilityToModify.getTargets()) { + for (UUID uuid : target.getTargets()) { + Permanent permanent = game.getPermanent(uuid); if (permanent != null && permanent.isCreature()) { creaturesTargeted.add(permanent.getId()); } diff --git a/Mage.Sets/src/mage/cards/b/BlindWithAnger.java b/Mage.Sets/src/mage/cards/b/BlindWithAnger.java index a63a7e97b4..076f4b9666 100644 --- a/Mage.Sets/src/mage/cards/b/BlindWithAnger.java +++ b/Mage.Sets/src/mage/cards/b/BlindWithAnger.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.b; import java.util.UUID; @@ -42,7 +41,6 @@ import mage.constants.SuperType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SupertypePredicate; -import mage.target.Target; import mage.target.common.TargetCreaturePermanent; /** @@ -57,14 +55,13 @@ public class BlindWithAnger extends CardImpl { } public BlindWithAnger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); this.subtype.add(SubType.ARCANE); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - Target target = new TargetCreaturePermanent(filter); - this.getSpellAbility().addTarget(target); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap target nonlegendary creature")); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); } public BlindWithAnger(final BlindWithAnger card) { diff --git a/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java b/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java index b83b30f684..4ea155477d 100644 --- a/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java +++ b/Mage.Sets/src/mage/cards/b/BloodcrazedHoplite.java @@ -61,7 +61,7 @@ public class BloodcrazedHoplite extends CardImpl { } public BloodcrazedHoplite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN, SubType.SOLDIER); this.power = new MageInt(2); @@ -88,7 +88,7 @@ public class BloodcrazedHoplite extends CardImpl { class BloodcrazedHopliteTriggeredAbility extends TriggeredAbilityImpl { public BloodcrazedHopliteTriggeredAbility() { - super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); + super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), false); } public BloodcrazedHopliteTriggeredAbility(BloodcrazedHopliteTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/b/BonethornValesk.java b/Mage.Sets/src/mage/cards/b/BonethornValesk.java index 6af8e310eb..ebaa60b72f 100644 --- a/Mage.Sets/src/mage/cards/b/BonethornValesk.java +++ b/Mage.Sets/src/mage/cards/b/BonethornValesk.java @@ -53,7 +53,7 @@ public class BonethornValesk extends CardImpl { this.toughness = new MageInt(2); // Whenever a permanent is turned face up, Bonethorn Valesk deals 1 damage to target creature or player. - Ability ability = new TurnedFaceUpAllTriggeredAbility(new DamageTargetEffect(1), new FilterPermanent()); + Ability ability = new TurnedFaceUpAllTriggeredAbility(new DamageTargetEffect(1), new FilterPermanent("a permanent")); ability.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CavalryMaster.java b/Mage.Sets/src/mage/cards/c/CavalryMaster.java index ca06f4981a..6d20173064 100644 --- a/Mage.Sets/src/mage/cards/c/CavalryMaster.java +++ b/Mage.Sets/src/mage/cards/c/CavalryMaster.java @@ -46,15 +46,15 @@ import mage.filter.predicate.mageobject.AbilityPredicate; * @author Plopman */ public class CavalryMaster extends CardImpl { - + static final private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures you control with flanking"); - - static{ + + static { filter.add(new AbilityPredicate(FlankingAbility.class)); } - + public CavalryMaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.KNIGHT); @@ -64,7 +64,10 @@ public class CavalryMaster extends CardImpl { // Flanking this.addAbility(new FlankingAbility()); // Other creatures you control with flanking have flanking. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, true))); + this.addAbility(new SimpleStaticAbility( + Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, true) + .setText("Other creatures you control with flanking have flanking.") + )); } public CavalryMaster(final CavalryMaster card) { diff --git a/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java b/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java index e45ae7966d..9207df79dd 100644 --- a/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java +++ b/Mage.Sets/src/mage/cards/c/ChariotOfVictory.java @@ -52,13 +52,13 @@ import mage.constants.Zone; public class ChariotOfVictory extends CardImpl { public ChariotOfVictory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature has first strike, trample, and haste. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT)); Effect effect = new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.EQUIPMENT); - effect.setText(", trample"); + effect.setText(", trample,"); ability.addEffect(effect); effect = new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.EQUIPMENT); effect.setText("and haste"); diff --git a/Mage.Sets/src/mage/cards/c/ChillHaunting.java b/Mage.Sets/src/mage/cards/c/ChillHaunting.java index 4a9dfd5fff..77610b404d 100644 --- a/Mage.Sets/src/mage/cards/c/ChillHaunting.java +++ b/Mage.Sets/src/mage/cards/c/ChillHaunting.java @@ -50,7 +50,7 @@ public class ChillHaunting extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); // As an additional cost to cast Chill Haunting, exile X creature cards from your graveyard. - this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("cards from your graveyard"), true)); + this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard("creature cards from your graveyard"), true)); // Target creature gets -X/-X until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java index 626aceb445..bf022a10d5 100644 --- a/Mage.Sets/src/mage/cards/c/CloakAndDagger.java +++ b/Mage.Sets/src/mage/cards/c/CloakAndDagger.java @@ -51,18 +51,19 @@ import mage.filter.predicate.mageobject.SubtypePredicate; public class CloakAndDagger extends CardImpl { private static final FilterPermanent filter = new FilterCreaturePermanent("a Rogue creature"); + static { filter.add(new SubtypePredicate(SubType.ROGUE)); } public CloakAndDagger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.ROGUE); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+0 and has shroud. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0)); - ability.addEffect(new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.EQUIPMENT)); + ability.addEffect(new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.EQUIPMENT).setText("and has shroud")); this.addAbility(ability); // Whenever a Rogue creature enters the battlefield, you may attach Cloak and Dagger to it. this.addAbility(new EntersBattlefieldAllTriggeredAbility( diff --git a/Mage.Sets/src/mage/cards/c/ColossalHeroics.java b/Mage.Sets/src/mage/cards/c/ColossalHeroics.java index bcad9fda9e..3dd6608302 100644 --- a/Mage.Sets/src/mage/cards/c/ColossalHeroics.java +++ b/Mage.Sets/src/mage/cards/c/ColossalHeroics.java @@ -45,14 +45,13 @@ import mage.target.common.TargetCreaturePermanent; public class ColossalHeroics extends CardImpl { public ColossalHeroics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); // Strive - Colossal Heroics costs {1}{G} more to cast for each target beyond the first. this.addAbility(new StriveAbility("{1}{G}")); // Any number of target creatures each get +2/+2 until end of turn. Untap those creatures. - Effect effect = new BoostTargetEffect(2,2, Duration.EndOfTurn); - effect.setText("Any number of target creatures each get +2/+2"); + Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); + effect.setText("Any number of target creatures each get +2/+2 until end of turn."); this.getSpellAbility().addEffect(effect); effect = new UntapTargetEffect(); effect.setText("Untap those creatures"); diff --git a/Mage.Sets/src/mage/cards/c/ConqueringManticore.java b/Mage.Sets/src/mage/cards/c/ConqueringManticore.java index 21b369bbd5..64e6ab9ad0 100644 --- a/Mage.Sets/src/mage/cards/c/ConqueringManticore.java +++ b/Mage.Sets/src/mage/cards/c/ConqueringManticore.java @@ -41,6 +41,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; /** @@ -49,8 +52,14 @@ import mage.target.common.TargetCreaturePermanent; */ public class ConqueringManticore extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + public ConqueringManticore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.MANTICORE); this.power = new MageInt(5); @@ -59,9 +68,9 @@ public class ConqueringManticore extends CardImpl { this.addAbility(FlyingAbility.getInstance()); Ability ability = new EntersBattlefieldTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), false); - ability.addEffect(new UntapTargetEffect()); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - ability.addTarget(new TargetCreaturePermanent()); + ability.addEffect(new UntapTargetEffect().setText("Untap that creature")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DakraMystic.java b/Mage.Sets/src/mage/cards/d/DakraMystic.java index 18ff2b5fa9..3c9b890b5c 100644 --- a/Mage.Sets/src/mage/cards/d/DakraMystic.java +++ b/Mage.Sets/src/mage/cards/d/DakraMystic.java @@ -52,7 +52,7 @@ import mage.players.Player; public class DakraMystic extends CardImpl { public DakraMystic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add(SubType.MERFOLK); this.subtype.add(SubType.WIZARD); @@ -63,8 +63,7 @@ public class DakraMystic extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DakraMysticEffect(), new ManaCostsImpl("{U}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - - + } public DakraMystic(final DakraMystic card) { @@ -78,38 +77,38 @@ public class DakraMystic extends CardImpl { } class DakraMysticEffect extends OneShotEffect { - + public DakraMysticEffect() { super(Outcome.Detriment); - this.staticText = "Each player reveals the top card of his or her library. You may put the revealed cards into their owners graveyard. If you don't, each player draws a card"; + this.staticText = "Each player reveals the top card of his or her library. You may put the revealed cards into their owners' graveyard. If you don't, each player draws a card"; } - + public DakraMysticEffect(final DakraMysticEffect effect) { super(effect); } - + @Override public DakraMysticEffect copy() { return new DakraMysticEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && player.getLibrary().hasCards()) { player.revealCards(player.getLogName(), new CardsImpl(player.getLibrary().getFromTop(game)), game); } } if (controller.chooseUse(outcome, "Put revealed cards into graveyard?", source, game)) { - for(UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); if (player != null && player.getLibrary().hasCards()) { player.moveCards(player.getLibrary().getFromTop(game), Zone.GRAVEYARD, source, game); } - } + } } else { new DrawCardAllEffect(1).apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/d/DementiaSliver.java b/Mage.Sets/src/mage/cards/d/DementiaSliver.java index 97d586ff79..8e5cfb838b 100644 --- a/Mage.Sets/src/mage/cards/d/DementiaSliver.java +++ b/Mage.Sets/src/mage/cards/d/DementiaSliver.java @@ -51,7 +51,7 @@ import mage.target.common.TargetOpponent; * @author fireshoes */ public class DementiaSliver extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("All Slivers"); static { @@ -59,7 +59,7 @@ public class DementiaSliver extends CardImpl { } public DementiaSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(3); this.toughness = new MageInt(3); @@ -70,7 +70,12 @@ public class DementiaSliver extends CardImpl { gainedAbility.addTarget(new TargetOpponent()); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(gainedAbility, Duration.WhileOnBattlefield, filter, - "All Slivers have \"{T}: Name a card. Target opponent reveals a card at random from his or her hand. If it's the named card, that player discards it\""))); + "All Slivers have \"{T}: Choose a card name. " + + "Target opponent reveals a card at random from his or her hand." + + " If that card has the chosen name, that player discards it." + + " Activate this ability only during your turn.\"" + ) + )); } public DementiaSliver(final DementiaSliver card) { @@ -98,7 +103,7 @@ class DementiaSliverEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY); if (opponent != null && sourceObject != null && !cardName.isEmpty()) { if (!opponent.getHand().isEmpty()) { Cards revealed = new CardsImpl(); @@ -121,4 +126,4 @@ class DementiaSliverEffect extends OneShotEffect { return new DementiaSliverEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DictateOfErebos.java b/Mage.Sets/src/mage/cards/d/DictateOfErebos.java index 87cb1a626f..4efc724617 100644 --- a/Mage.Sets/src/mage/cards/d/DictateOfErebos.java +++ b/Mage.Sets/src/mage/cards/d/DictateOfErebos.java @@ -45,19 +45,19 @@ import mage.filter.predicate.permanent.ControllerPredicate; */ public class DictateOfErebos extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature you control"); static { filter.add(new ControllerPredicate(TargetController.YOU)); } public DictateOfErebos(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); // Flash this.addAbility(FlashAbility.getInstance()); // Whenever a creature you control dies, each opponent sacrifices a creature. - this.addAbility(new DiesCreatureTriggeredAbility(new SacrificeOpponentsEffect(new FilterControlledCreaturePermanent("a creature")), false, filter)); + this.addAbility(new DiesCreatureTriggeredAbility(new SacrificeOpponentsEffect(new FilterControlledCreaturePermanent("creature")), false, filter)); } public DictateOfErebos(final DictateOfErebos card) { diff --git a/Mage.Sets/src/mage/cards/d/DominusOfFealty.java b/Mage.Sets/src/mage/cards/d/DominusOfFealty.java index 3572e5c2ea..dd6b778533 100644 --- a/Mage.Sets/src/mage/cards/d/DominusOfFealty.java +++ b/Mage.Sets/src/mage/cards/d/DominusOfFealty.java @@ -51,17 +51,16 @@ import mage.target.TargetPermanent; public class DominusOfFealty extends CardImpl { public DominusOfFealty(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U/R}{U/R}{U/R}{U/R}{U/R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}{U/R}{U/R}{U/R}{U/R}"); this.subtype.add(SubType.SPIRIT); this.subtype.add(SubType.AVATAR); - this.power = new MageInt(4); this.toughness = new MageInt(4); this.addAbility(FlyingAbility.getInstance()); Ability ability = new BeginningOfUpkeepTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), TargetController.YOU, true); - ability.addEffect(new UntapTargetEffect()); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new UntapTargetEffect().setText("If you do, untap it")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and it gains haste until end of turn")); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EldraziObligator.java b/Mage.Sets/src/mage/cards/e/EldraziObligator.java index 79660d4410..e3d9337d31 100644 --- a/Mage.Sets/src/mage/cards/e/EldraziObligator.java +++ b/Mage.Sets/src/mage/cards/e/EldraziObligator.java @@ -55,7 +55,7 @@ import mage.target.common.TargetCreaturePermanent; public class EldraziObligator extends CardImpl { public EldraziObligator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.ELDRAZI); this.power = new MageInt(3); this.toughness = new MageInt(1); @@ -65,15 +65,15 @@ public class EldraziObligator extends CardImpl { // Haste this.addAbility(HasteAbility.getInstance()); - + DoIfCostPaid costPaidEffect = new DoIfCostPaid(new GainControlTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}{C}")); Effect untapEffect = new UntapTargetEffect(); - untapEffect.setText("Untap that creature"); + untapEffect.setText("untap that creature,"); Effect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - hasteEffect.setText("It gains haste until end of turn"); + hasteEffect.setText("and it gains haste until end of turn"); costPaidEffect.addEffect(untapEffect); - costPaidEffect.addEffect(hasteEffect); - + costPaidEffect.addEffect(hasteEffect); + // When you cast Eldrazi Obligator, you may pay {1}{C}. If you do, gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. Ability ability = new CastSourceTriggeredAbility(costPaidEffect); diff --git a/Mage.Sets/src/mage/cards/e/Evangelize.java b/Mage.Sets/src/mage/cards/e/Evangelize.java index 74ad62887d..c9209a99c3 100644 --- a/Mage.Sets/src/mage/cards/e/Evangelize.java +++ b/Mage.Sets/src/mage/cards/e/Evangelize.java @@ -53,7 +53,7 @@ public class Evangelize extends CardImpl { // Gain control of target creature of an opponent's choice that he or she controls. GainControlTargetEffect effect = new GainControlTargetEffect(Duration.EndOfGame); - effect.setText("Gain control of target creature of an opponent's choice that he or she controls"); + effect.setText("Gain control of target creature of an opponent's choice he or she controls"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addTarget(new TargetOpponentsChoicePermanent(1, 1, filter, false, true)); } diff --git a/Mage.Sets/src/mage/cards/f/FirewakeSliver.java b/Mage.Sets/src/mage/cards/f/FirewakeSliver.java index 3fcef064a9..fe0ec2a538 100644 --- a/Mage.Sets/src/mage/cards/f/FirewakeSliver.java +++ b/Mage.Sets/src/mage/cards/f/FirewakeSliver.java @@ -53,32 +53,32 @@ import mage.target.common.TargetCreaturePermanent; */ public class FirewakeSliver extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("All sliver creatures"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("All Sliver creatures"); private static final FilterCreaturePermanent targetSliverFilter = new FilterCreaturePermanent("Sliver"); static { filter.add(new SubtypePredicate(SubType.SLIVER)); targetSliverFilter.add(new SubtypePredicate(SubType.SLIVER)); } - + public FirewakeSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); // All Sliver creatures have haste. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false))); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, false))); + // All Slivers have "{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn." - Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2,2,Duration.EndOfTurn), new GenericManaCost(1)); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 2, Duration.EndOfTurn), new GenericManaCost(1)); gainedAbility.addCost(new SacrificeSourceCost()); gainedAbility.addTarget(new TargetCreaturePermanent(targetSliverFilter)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect( gainedAbility, Duration.WhileOnBattlefield, - filter, "All Slivers have \"{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn.\""))); - + filter, "All Slivers have \"{1}, Sacrifice this permanent: Target Sliver creature gets +2/+2 until end of turn.\""))); + } public FirewakeSliver(final FirewakeSliver card) { diff --git a/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java b/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java index d9decea82e..b49857fe67 100644 --- a/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java +++ b/Mage.Sets/src/mage/cards/f/FlagstonesOfTrokair.java @@ -53,14 +53,14 @@ public class FlagstonesOfTrokair extends CardImpl { } public FlagstonesOfTrokair(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.LAND},""); + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); addSuperType(SuperType.LEGENDARY); // {tap}: Add {W} to your mana pool. this.addAbility(new WhiteManaAbility()); // When Flagstones of Trokair is put into a graveyard from the battlefield, you may search your library for a Plains card and put it onto the battlefield tapped. If you do, shuffle your library. - this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(FILTER), true, true), true)); + this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(FILTER), true, false), true)); } public FlagstonesOfTrokair(final FlagstonesOfTrokair card) { diff --git a/Mage.Sets/src/mage/cards/f/FlashConscription.java b/Mage.Sets/src/mage/cards/f/FlashConscription.java index ae2ec3f576..91e9cf345b 100644 --- a/Mage.Sets/src/mage/cards/f/FlashConscription.java +++ b/Mage.Sets/src/mage/cards/f/FlashConscription.java @@ -59,11 +59,14 @@ public class FlashConscription extends CardImpl { // Untap target creature and gain control of it until end of turn. That creature gains haste until end of turn. If {W} was spent to cast Flash Conscription, the creature gains "Whenever this creature deals combat damage, you gain that much life" until end of turn. this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("That creature gains haste until end of turn")); this.getSpellAbility().addEffect(new ConditionalContinuousEffect( new GainAbilityTargetEffect(new FlashConscriptionTriggeredAbility(), Duration.EndOfTurn), - new ManaWasSpentCondition(ColoredManaSymbol.W), "If {W} was spent to cast {this}, the creature gains \"Whenever this creature deals combat damage, you gain that much life\" until end of turn")); + new ManaWasSpentCondition(ColoredManaSymbol.W), + "If {W} was spent to cast {this}, the creature gains " + + "\"Whenever this creature deals combat damage, you gain that much life\" until end of turn" + )); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java b/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java index 6ed51dca07..b70542b911 100644 --- a/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java +++ b/Mage.Sets/src/mage/cards/f/FlowstoneChanneler.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; @@ -43,7 +43,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreaturePermanent; /** @@ -69,7 +68,7 @@ public class FlowstoneChanneler extends CardImpl { ability.addEffect(effect); ability.addTarget(new TargetCreaturePermanent()); ability.addCost(new TapSourceCost()); - ability.addCost(new DiscardTargetCost(new TargetCardInHand())); + ability.addCost(new DiscardCardCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java index f09aa782e3..888a7e4ca1 100644 --- a/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java +++ b/Mage.Sets/src/mage/cards/f/FoeRazerRegent.java @@ -67,7 +67,7 @@ public class FoeRazerRegent extends CardImpl { } public FoeRazerRegent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); this.subtype.add(SubType.DRAGON); this.power = new MageInt(4); this.toughness = new MageInt(5); @@ -118,8 +118,8 @@ class FoeRazerRegentTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (permanent != null && permanent.getControllerId().equals(getControllerId())) { - for (Effect effect: this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent, game)); } return true; } diff --git a/Mage.Sets/src/mage/cards/g/Goatnapper.java b/Mage.Sets/src/mage/cards/g/Goatnapper.java index dd0e2dba9a..aaed048196 100644 --- a/Mage.Sets/src/mage/cards/g/Goatnapper.java +++ b/Mage.Sets/src/mage/cards/g/Goatnapper.java @@ -57,7 +57,7 @@ public class Goatnapper extends CardImpl { } public Goatnapper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.ROGUE); @@ -65,8 +65,8 @@ public class Goatnapper extends CardImpl { this.toughness = new MageInt(2); Ability ability = new EntersBattlefieldTriggeredAbility(new UntapTargetEffect(), false); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java b/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java index 16147bfc0f..112f0a02ca 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java +++ b/Mage.Sets/src/mage/cards/g/GoblinSkycutter.java @@ -48,7 +48,7 @@ import mage.target.common.TargetCreaturePermanent; /** * * @author LoneFox - + * */ public class GoblinSkycutter extends CardImpl { @@ -59,7 +59,7 @@ public class GoblinSkycutter extends CardImpl { } public GoblinSkycutter(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.GOBLIN); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(2); @@ -67,7 +67,7 @@ public class GoblinSkycutter extends CardImpl { // Sacrifice Goblin Skycutter: Goblin Skycutter deals 2 damage to target creature with flying. That creature loses flying until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new SacrificeSourceCost()); - ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn)); + ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn).setText("that creature loses flying until end of turn")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Godsend.java b/Mage.Sets/src/mage/cards/g/Godsend.java index 580494ee00..c47dbf04cb 100644 --- a/Mage.Sets/src/mage/cards/g/Godsend.java +++ b/Mage.Sets/src/mage/cards/g/Godsend.java @@ -63,7 +63,7 @@ import mage.util.CardUtil; public class Godsend extends CardImpl { public Godsend(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.EQUIPMENT); @@ -195,7 +195,7 @@ class GodsendRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { public GodsendRuleModifyingEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Opponents can't cast cards with the same name as cards exiled with {this}"; + staticText = "Your opponents can't cast cards with the same name as cards exiled with {this}"; } public GodsendRuleModifyingEffect(final GodsendRuleModifyingEffect effect) { diff --git a/Mage.Sets/src/mage/cards/g/Greenseeker.java b/Mage.Sets/src/mage/cards/g/Greenseeker.java index 9f0a7e6ece..4b873b29bb 100644 --- a/Mage.Sets/src/mage/cards/g/Greenseeker.java +++ b/Mage.Sets/src/mage/cards/g/Greenseeker.java @@ -51,7 +51,7 @@ import java.util.UUID; public class Greenseeker extends CardImpl { public Greenseeker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SPELLSHAPER); this.power = new MageInt(1); @@ -59,8 +59,8 @@ public class Greenseeker extends CardImpl { // {G}, {tap}, Discard a card: Search your library for a basic land card, reveal it, and put it into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), - new ManaCostsImpl("{G}")); + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(1, 1, StaticFilters.FILTER_BASIC_LAND_CARD), true, true), + new ManaCostsImpl("{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/h/HauntingWind.java b/Mage.Sets/src/mage/cards/h/HauntingWind.java index 447bded4d1..4533661fbb 100644 --- a/Mage.Sets/src/mage/cards/h/HauntingWind.java +++ b/Mage.Sets/src/mage/cards/h/HauntingWind.java @@ -29,7 +29,10 @@ package mage.cards.h; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -37,19 +40,20 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; +import mage.target.targetpointer.FixedTarget; /** * - * @author MarcoMarin + * @author TheElk801 */ public class HauntingWind extends CardImpl { public HauntingWind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); // Whenever an artifact becomes tapped or a player activates an artifact's ability without {tap} in its activation cost, Haunting Wind deals 1 damage to that artifact's controller. - - this.addAbility(new AbilityActivatedTriggeredAbility2()); + this.addAbility(new HauntingWindTriggeredAbility()); } public HauntingWind(final HauntingWind card) { @@ -62,36 +66,68 @@ public class HauntingWind extends CardImpl { } } -class AbilityActivatedTriggeredAbility2 extends TriggeredAbilityImpl { +class HauntingWindTriggeredAbility extends TriggeredAbilityImpl { - AbilityActivatedTriggeredAbility2() { - super(Zone.BATTLEFIELD, new DamageControllerEffect(1)); + HauntingWindTriggeredAbility() { + super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); } - AbilityActivatedTriggeredAbility2(final AbilityActivatedTriggeredAbility2 ability) { + HauntingWindTriggeredAbility(final HauntingWindTriggeredAbility ability) { super(ability); } @Override - public AbilityActivatedTriggeredAbility2 copy() { - return new AbilityActivatedTriggeredAbility2(this); + public HauntingWindTriggeredAbility copy() { + return new HauntingWindTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY || - event.getType() == GameEvent.EventType.TAPPED; + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY + || event.getType() == GameEvent.EventType.TAPPED; } @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent isArtifact = game.getPermanent(event.getSourceId()); - return isArtifact != null && isArtifact.isArtifact(); - + if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null) { + return false; + } + boolean triggerable = true; + for (Cost cost : stackAbility.getCosts()) { + if (cost instanceof TapSourceCost) { + triggerable = false; + break; + } + } + if (!triggerable) { + return false; + } + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent.getControllerId(), game)); + } + return true; + } + if (event.getType() == GameEvent.EventType.TAPPED) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent.getControllerId(), game)); + } + return true; + } + return false; } @Override public String getRule() { - return "Whenever an artifact becomes tapped or a player activates an artifact's ability without {tap} in its activation cost, Haunting Wind deals 1 damage to that artifact's controller."; + return "Whenever an artifact becomes tapped or a player activates an artifact's ability without {T} in its activation cost, {this} deals 1 damage to that artifact's controller."; } } diff --git a/Mage.Sets/src/mage/cards/h/Hubris.java b/Mage.Sets/src/mage/cards/h/Hubris.java index 0c8751cc88..cb4cb55983 100644 --- a/Mage.Sets/src/mage/cards/h/Hubris.java +++ b/Mage.Sets/src/mage/cards/h/Hubris.java @@ -52,7 +52,7 @@ import mage.target.common.TargetCreaturePermanent; public class Hubris extends CardImpl { public Hubris(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // Return target creature and all Auras attached to it to their owners' hand. this.getSpellAbility().addEffect(new HubrisReturnEffect()); @@ -80,7 +80,7 @@ class HubrisReturnEffect extends OneShotEffect { public HubrisReturnEffect() { super(Outcome.Benefit); - this.staticText = "Return target creature and all Auras attached to it to their owners' hand"; + this.staticText = "Return target creature and all Auras attached to it to their owners' hands"; } public HubrisReturnEffect(final HubrisReturnEffect effect) { diff --git a/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java b/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java index 44def69dd4..3d978e13d6 100644 --- a/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java +++ b/Mage.Sets/src/mage/cards/k/KariZevsExpertise.java @@ -63,8 +63,8 @@ public class KariZevsExpertise extends CardImpl { // Gain control of target creature or Vehicle until end of turn. Untap it. It gains haste until end of turn. this.getSpellAbility().addTarget(new TargetPermanent(filter)); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gans haste until end of turn.")); // You may cast a card with converted mana cost 2 or less from your hand without paying its mana cost. this.getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(2)); diff --git a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java index 06287397b1..2aee7e8829 100644 --- a/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java +++ b/Mage.Sets/src/mage/cards/k/KrovikanWhispers.java @@ -68,7 +68,7 @@ public class KrovikanWhispers extends CardImpl { this.addAbility(ability); // Cumulative upkeep-Pay {U} or {B}. - this.addAbility(new CumulativeUpkeepAbility(new OrCost(new ManaCostsImpl("{U}"), new ManaCostsImpl("{B}"), "Pay {U} or pay {B}"))); + this.addAbility(new CumulativeUpkeepAbility(new OrCost(new ManaCostsImpl("{U}"), new ManaCostsImpl("{B}"), "{U} or {B}"))); // You control enchanted creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); diff --git a/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java b/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java index edb409c372..8a19cbb2d2 100644 --- a/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java +++ b/Mage.Sets/src/mage/cards/l/LaunchTheFleet.java @@ -55,7 +55,7 @@ public class LaunchTheFleet extends CardImpl { // Until end of turn, any number of target creatures each gain "Whenever this creature attacks, create a 1/1 white Soldier token tapped and attacking." this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); Effect effect = new GainAbilityTargetEffect(new AttacksTriggeredAbility(new CreateTokenEffect(new SoldierToken(), 1, true, true), false), Duration.EndOfTurn); - effect.setText("Until end of turn, any number of target creatures each gain \"Whenever this creature attacks, create a 1/1 white Soldier token tapped and attacking.\""); + effect.setText("Until end of turn, any number of target creatures each gain \"Whenever this creature attacks, create a 1/1 white Soldier creature token that's tapped and attacking.\""); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/l/LightningSerpent.java b/Mage.Sets/src/mage/cards/l/LightningSerpent.java index 37e36d2d72..c567141b31 100644 --- a/Mage.Sets/src/mage/cards/l/LightningSerpent.java +++ b/Mage.Sets/src/mage/cards/l/LightningSerpent.java @@ -29,8 +29,8 @@ package mage.cards.l; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.keyword.HasteAbility; @@ -39,8 +39,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.counters.CounterType; +import mage.game.events.GameEvent; /** * @@ -49,7 +49,7 @@ import mage.counters.CounterType; public class LightningSerpent extends CardImpl { public LightningSerpent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{X}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{R}"); this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.SERPENT); this.power = new MageInt(2); @@ -62,7 +62,7 @@ public class LightningSerpent extends CardImpl { // Lightning Serpent enters the battlefield with X +1/+0 counters on it. this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.P1P0.createInstance()))); // At the beginning of the end step, sacrifice Lightning Serpent. - this.addAbility(new BeginningOfEndStepTriggeredAbility(new SacrificeSourceEffect(), TargetController.ANY, false)); + this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect())); } public LightningSerpent(final LightningSerpent card) { diff --git a/Mage.Sets/src/mage/cards/l/LightningStorm.java b/Mage.Sets/src/mage/cards/l/LightningStorm.java index c69e97fc88..0c7c4cd07b 100644 --- a/Mage.Sets/src/mage/cards/l/LightningStorm.java +++ b/Mage.Sets/src/mage/cards/l/LightningStorm.java @@ -69,7 +69,7 @@ public class LightningStorm extends CardImpl { new LightningStormAddCounterEffect(), new DiscardTargetCost(new TargetCardInHand(new FilterLandCard("a land card")))); ability.setMayActivate(TargetController.ANY); - ability.addEffect(new InfoEffect("Any player may activate this ability but only if {this} is on the stack")); + ability.addEffect(new InfoEffect(" Any player may activate this ability but only if {this} is on the stack")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java index 0e1abb3cca..c04355a0ba 100644 --- a/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java +++ b/Mage.Sets/src/mage/cards/l/LimDulTheNecromancer.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; */ public class LimDulTheNecromancer extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature an opponent controls"); private static final FilterPermanent filter2 = new FilterPermanent("Zombie"); static { @@ -67,7 +67,7 @@ public class LimDulTheNecromancer extends CardImpl { } public LimDulTheNecromancer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java b/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java index 3c84e6ae22..aab52ad541 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheScroll.java @@ -57,7 +57,7 @@ import mage.target.common.TargetCreatureOrPlayer; public class MagusOfTheScroll extends CardImpl { public MagusOfTheScroll(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); this.power = new MageInt(1); @@ -85,7 +85,7 @@ class MagusOfTheScrollEffect extends OneShotEffect { public MagusOfTheScrollEffect() { super(Outcome.Neutral); - staticText = "Reveal a card at random from your hand. If it's the named card, {this} deals 2 damage to target creature or player"; + staticText = ", then reveal a card at random from your hand. If it's the named card, {this} deals 2 damage to target creature or player"; } public MagusOfTheScrollEffect(final MagusOfTheScrollEffect effect) { @@ -126,4 +126,4 @@ class MagusOfTheScrollEffect extends OneShotEffect { public MagusOfTheScrollEffect copy() { return new MagusOfTheScrollEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java b/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java index 718cfcd57f..3decdc220e 100644 --- a/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java +++ b/Mage.Sets/src/mage/cards/m/MangaraOfCorondor.java @@ -59,7 +59,7 @@ public class MangaraOfCorondor extends CardImpl { // {T}: Exile Mangara of Corondor and target permanent. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileSourceEffect(), new TapSourceCost()); - ability.addEffect(new ExileTargetEffect()); + ability.addEffect(new ExileTargetEffect().setText("and target permanent")); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MetallicMastery.java b/Mage.Sets/src/mage/cards/m/MetallicMastery.java index 9849c373d6..a6e3dc76e1 100644 --- a/Mage.Sets/src/mage/cards/m/MetallicMastery.java +++ b/Mage.Sets/src/mage/cards/m/MetallicMastery.java @@ -36,9 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; /** * @@ -46,20 +44,14 @@ import mage.target.TargetPermanent; */ public class MetallicMastery extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("artifact"); - - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - public MetallicMastery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); - - this.getSpellAbility().addTarget(new TargetPermanent(filter)); + // Gain control of target artifact until end of turn. Untap that artifact. It gains haste until end of turn. + this.getSpellAbility().addTarget(new TargetArtifactPermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that artifact")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); } public MetallicMastery(final MetallicMastery card) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorUniverse.java b/Mage.Sets/src/mage/cards/m/MirrorUniverse.java index fe8b1ba141..aae1fd8ea1 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorUniverse.java +++ b/Mage.Sets/src/mage/cards/m/MirrorUniverse.java @@ -55,7 +55,7 @@ public class MirrorUniverse extends CardImpl { Zone.BATTLEFIELD, new ExchangeLifeTargetEffect(), new TapSourceCost(), - new IsStepCondition(PhaseStep.UPKEEP), + new IsStepCondition(PhaseStep.UPKEEP, true), null); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetOpponent()); diff --git a/Mage.Sets/src/mage/cards/m/MogissWarhound.java b/Mage.Sets/src/mage/cards/m/MogissWarhound.java index d4138b8534..1d5ce89a0a 100644 --- a/Mage.Sets/src/mage/cards/m/MogissWarhound.java +++ b/Mage.Sets/src/mage/cards/m/MogissWarhound.java @@ -51,7 +51,7 @@ import mage.constants.Zone; public class MogissWarhound extends CardImpl { public MogissWarhound(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HOUND); this.power = new MageInt(2); @@ -62,13 +62,13 @@ public class MogissWarhound extends CardImpl { // Mogis's Warhound attacks each turn if able. this.addAbility(new AttacksEachCombatStaticAbility()); // Enchanted creature gets +2/+2 and attacks each turn if able. - Effect effect = new BoostEnchantedEffect(2,2,Duration.WhileOnBattlefield); + Effect effect = new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +2/+2"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); effect = new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA); - effect.setText("and attacks each turn if able"); + effect.setText("and attacks each combat if able"); ability.addEffect(effect); - this.addAbility(ability); + this.addAbility(ability); } public MogissWarhound(final MogissWarhound card) { diff --git a/Mage.Sets/src/mage/cards/m/Molder.java b/Mage.Sets/src/mage/cards/m/Molder.java index 3969ed8f67..303dd0f33c 100644 --- a/Mage.Sets/src/mage/cards/m/Molder.java +++ b/Mage.Sets/src/mage/cards/m/Molder.java @@ -49,17 +49,17 @@ import mage.target.TargetPermanent; public class Molder extends CardImpl { public Molder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}"); // Destroy target artifact or enchantment with converted mana cost X. It can't be regenerated. You gain X life. - this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); this.getSpellAbility().addTarget(new TargetPermanent(new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"))); this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue())); } @Override public void adjustTargets(Ability ability, Game game) { - if(ability instanceof SpellAbility) { + if (ability instanceof SpellAbility) { ability.getTargets().clear(); int xValue = ability.getManaCostsToPay().getX(); FilterArtifactOrEnchantmentPermanent filter = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment with converted mana cost X"); diff --git a/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java b/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java index 0b59350e95..e4d18bdc96 100644 --- a/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java +++ b/Mage.Sets/src/mage/cards/m/MwonvuliAcidMoss.java @@ -46,14 +46,17 @@ import mage.target.common.TargetCardInLibrary; */ public class MwonvuliAcidMoss extends CardImpl { - public MwonvuliAcidMoss(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}{G}"); - - FilterLandCard filterForest = new FilterLandCard(); + private static final FilterLandCard filterForest = new FilterLandCard("Forest card"); + + static { filterForest.add(new SubtypePredicate(SubType.FOREST)); - + } + + public MwonvuliAcidMoss(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + // Destroy target land. Search your library for a Forest card and put that card onto the battlefield tapped. Then shuffle your library. - this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(new FilterLandPermanent())); this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filterForest), true, true)); } @@ -67,4 +70,3 @@ public class MwonvuliAcidMoss extends CardImpl { return new MwonvuliAcidMoss(this); } } - diff --git a/Mage.Sets/src/mage/cards/n/NessianGameWarden.java b/Mage.Sets/src/mage/cards/n/NessianGameWarden.java index fe78091f32..9f6511ef2c 100644 --- a/Mage.Sets/src/mage/cards/n/NessianGameWarden.java +++ b/Mage.Sets/src/mage/cards/n/NessianGameWarden.java @@ -57,7 +57,7 @@ import mage.target.TargetCard; public class NessianGameWarden extends CardImpl { public NessianGameWarden(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.BEAST); this.power = new MageInt(4); @@ -87,7 +87,7 @@ class NessianGameWardenEffect extends OneShotEffect { public NessianGameWardenEffect() { super(Outcome.DrawCard); - this.staticText = "look at the top X cards of your library, where X is the number of forests you control. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order"; + this.staticText = "look at the top X cards of your library, where X is the number of Forests you control. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order"; } public NessianGameWardenEffect(final NessianGameWardenEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java index 04a6129f22..946b574a2a 100644 --- a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java +++ b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java @@ -57,22 +57,21 @@ public class NivmagusElemental extends CardImpl { static { filter.add(new ControllerPredicate(TargetController.YOU)); filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY))); + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY))); } public NivmagusElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U/R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}"); this.subtype.add(SubType.ELEMENTAL); - this.power = new MageInt(1); this.toughness = new MageInt(2); // Exile an instant or sorcery spell you control: Put two +1/+1 counters on Nivmagus Elemental. (That spell won't resolve.) - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)),new ExileFromStackCost(new TargetSpell(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ExileFromStackCost(new TargetSpell(filter))); this.addAbility(ability); - + } public NivmagusElemental(final NivmagusElemental card) { diff --git a/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java b/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java index a4957f0577..ab624558fc 100644 --- a/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java +++ b/Mage.Sets/src/mage/cards/o/OgreGeargrabber.java @@ -62,14 +62,14 @@ public class OgreGeargrabber extends CardImpl { } public OgreGeargrabber(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.OGRE); this.subtype.add(SubType.WARRIOR); this.power = new MageInt(4); this.toughness = new MageInt(4); - Ability ability = new AttacksTriggeredAbility(new OgreGeargrabberEffect1(), false); - ability.addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); + Ability ability = new AttacksTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn), false); + ability.addEffect(new OgreGeargrabberEffect1()); ability.addTarget(new TargetPermanent(1, 1, filter, false)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PendelhavenElder.java b/Mage.Sets/src/mage/cards/p/PendelhavenElder.java index f35e1bdf70..ea1ff6e889 100644 --- a/Mage.Sets/src/mage/cards/p/PendelhavenElder.java +++ b/Mage.Sets/src/mage/cards/p/PendelhavenElder.java @@ -52,6 +52,7 @@ import mage.filter.predicate.permanent.ControllerPredicate; public class PendelhavenElder extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each 1/1 creature you control"); + static { filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, 1)); filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, 1)); @@ -59,14 +60,17 @@ public class PendelhavenElder extends CardImpl { } public PendelhavenElder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.ELF); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(1); this.toughness = new MageInt(1); // {tap}: Each 1/1 creature you control gets +1/+2 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 2, Duration.EndOfTurn, filter, false), new TapSourceCost())); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 2, Duration.EndOfTurn, filter, false) + .setText("Each 1/1 creature you control gets +1/+2 until end of turn."), + new TapSourceCost() + )); } public PendelhavenElder(final PendelhavenElder card) { diff --git a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java index 44d0bafbb6..1314189669 100644 --- a/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java +++ b/Mage.Sets/src/mage/cards/p/PharikaGodOfAffliction.java @@ -91,7 +91,7 @@ class PharikaExileEffect extends OneShotEffect { public PharikaExileEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Exile target creature card from a graveyard. It's owner creates a 1/1 black and green Snake enchantment creature token with deathtouch"; + staticText = "Exile target creature card from a graveyard. Its owner creates a 1/1 black and green Snake enchantment creature token with deathtouch"; } public PharikaExileEffect(final PharikaExileEffect effect) { diff --git a/Mage.Sets/src/mage/cards/p/Powerleech.java b/Mage.Sets/src/mage/cards/p/Powerleech.java index 6b46809e8e..ed876daebf 100644 --- a/Mage.Sets/src/mage/cards/p/Powerleech.java +++ b/Mage.Sets/src/mage/cards/p/Powerleech.java @@ -29,6 +29,8 @@ package mage.cards.p; import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,18 +39,20 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; +import mage.players.Player; /** * - * @author MarcoMarin + * @author TheElk801 */ public class Powerleech extends CardImpl { public Powerleech(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}{G}"); // Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {tap} in its activation cost, you gain 1 life. - this.addAbility(new AbilityActivatedTriggeredAbility3()); + this.addAbility(new PowerleechTriggeredAbility()); } public Powerleech(final Powerleech card) { @@ -60,37 +64,67 @@ public class Powerleech extends CardImpl { return new Powerleech(this); } } -class AbilityActivatedTriggeredAbility3 extends TriggeredAbilityImpl { - AbilityActivatedTriggeredAbility3() { +class PowerleechTriggeredAbility extends TriggeredAbilityImpl { + + PowerleechTriggeredAbility() { super(Zone.BATTLEFIELD, new GainLifeEffect(1)); } - AbilityActivatedTriggeredAbility3(final AbilityActivatedTriggeredAbility3 ability) { + PowerleechTriggeredAbility(final PowerleechTriggeredAbility ability) { super(ability); } @Override - public AbilityActivatedTriggeredAbility3 copy() { - return new AbilityActivatedTriggeredAbility3(this); + public PowerleechTriggeredAbility copy() { + return new PowerleechTriggeredAbility(this); } @Override public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY || - event.getType() == GameEvent.EventType.TAPPED; + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY + || event.getType() == GameEvent.EventType.TAPPED; } @Override public boolean checkTrigger(GameEvent event, Game game) { - Permanent isArtifact = game.getPermanent(event.getSourceId()); - return isArtifact != null && isArtifact.isArtifact() && - !isArtifact.getControllerId().equals(this.getControllerId()); - + Player player = game.getPlayer(controllerId); + if (player == null) { + return false; + } + if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null) { + return false; + } + boolean triggerable = true; + for (Cost cost : stackAbility.getCosts()) { + if (cost instanceof TapSourceCost) { + triggerable = false; + break; + } + } + if (!triggerable) { + return false; + } + return player.hasOpponent(permanent.getControllerId(), game); + } + if (event.getType() == GameEvent.EventType.TAPPED) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null || !permanent.isArtifact()) { + return false; + } + return player.hasOpponent(permanent.getControllerId(), game); + } + return false; } @Override public String getRule() { - return "Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {tap} in its activation cost, you gain 1 life."; + return "Whenever an artifact an opponent controls becomes tapped or an opponent activates an artifact's ability without {T} in its activation cost, you gain 1 life."; } } diff --git a/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java b/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java index 181e72eae5..eaf69c3c93 100644 --- a/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java +++ b/Mage.Sets/src/mage/cards/p/PrismaticGeoscope.java @@ -29,19 +29,20 @@ package mage.cards.p; import java.util.UUID; import mage.Mana; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.dynamicvalue.common.DomainValue; import mage.abilities.mana.DynamicManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; import mage.constants.CardType; /** * * @author fireshoes */ - public class PrismaticGeoscope extends CardImpl { public PrismaticGeoscope(UUID ownerId, CardSetInfo setInfo) { @@ -51,8 +52,13 @@ public class PrismaticGeoscope extends CardImpl { this.addAbility(new EntersBattlefieldTappedAbility()); // Domain — {T}: Add X mana in any combination of colors to your mana pool, where X is the number of basic land types among lands you control. - this.addAbility(new DynamicManaAbility(new Mana(0,0,0,0,0,0,1, 0), new DomainValue(), new TapSourceCost(), - "Add X mana in any combination of colors to your mana pool, where X is the number of basic land types among lands you control.")); + Ability ability = new DynamicManaAbility( + new Mana(0, 0, 0, 0, 0, 0, 1, 0), new DomainValue(), new TapSourceCost(), + "Add X mana in any combination of colors to your mana pool," + + " where X is the number of basic land types among lands you control." + ); + ability.setAbilityWord(AbilityWord.DOMAIN); + this.addAbility(ability); } public PrismaticGeoscope(final PrismaticGeoscope card) { diff --git a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java index 9755ae63ac..437e494ceb 100644 --- a/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java +++ b/Mage.Sets/src/mage/cards/p/PropheticFlamespeaker.java @@ -58,7 +58,7 @@ import mage.target.targetpointer.FixedTarget; public class PropheticFlamespeaker extends CardImpl { public PropheticFlamespeaker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.SHAMAN); @@ -87,7 +87,7 @@ class PropheticFlamespeakerExileEffect extends OneShotEffect { public PropheticFlamespeakerExileEffect() { super(Outcome.Detriment); - this.staticText = "Exile the top card of your library. You may play it this turn"; + this.staticText = "exile the top card of your library. You may play it this turn"; } public PropheticFlamespeakerExileEffect(final PropheticFlamespeakerExileEffect effect) { @@ -142,7 +142,7 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - return source.getControllerId().equals(affectedControllerId) && - objectId.equals(getTargetPointer().getFirst(game, source)); + return source.getControllerId().equals(affectedControllerId) + && objectId.equals(getTargetPointer().getFirst(game, source)); } } diff --git a/Mage.Sets/src/mage/cards/r/Reiterate.java b/Mage.Sets/src/mage/cards/r/Reiterate.java index a2b8feeeba..867267f8f2 100644 --- a/Mage.Sets/src/mage/cards/r/Reiterate.java +++ b/Mage.Sets/src/mage/cards/r/Reiterate.java @@ -33,9 +33,7 @@ import mage.abilities.keyword.BuybackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterSpell; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.StaticFilters; import mage.target.TargetSpell; /** @@ -43,23 +41,15 @@ import mage.target.TargetSpell; * @author fireshoes */ public class Reiterate extends CardImpl { - - private static final FilterSpell filter = new FilterSpell(); - - static { - filter.add(Predicates.or( - new CardTypePredicate(CardType.INSTANT), - new CardTypePredicate(CardType.SORCERY))); - } public Reiterate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{R}"); // Buyback {3} this.addAbility(new BuybackAbility("{3}")); - + // Copy target instant or sorcery spell. You may choose new targets for the copy. - this.getSpellAbility().addTarget(new TargetSpell(filter)); + this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_INSTANT_OR_SORCERY_SPELL)); this.getSpellAbility().addEffect(new CopyTargetSpellEffect()); } diff --git a/Mage.Sets/src/mage/cards/r/ReveilleSquad.java b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java index 3c7aa5d44c..fc79bb682b 100644 --- a/Mage.Sets/src/mage/cards/r/ReveilleSquad.java +++ b/Mage.Sets/src/mage/cards/r/ReveilleSquad.java @@ -92,7 +92,12 @@ class ReveilleSquadTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return game.getCombat().getDefenders().contains(controllerId); + for (UUID attackerId : game.getCombat().getAttackers()) { + if (game.getCombat().getDefenderId(attackerId).equals(controllerId)) { + return true; + } + } + return false; } @Override diff --git a/Mage.Sets/src/mage/cards/r/RiptideChimera.java b/Mage.Sets/src/mage/cards/r/RiptideChimera.java index 487b25e6ed..a8cc3869ac 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideChimera.java +++ b/Mage.Sets/src/mage/cards/r/RiptideChimera.java @@ -48,14 +48,13 @@ import mage.filter.predicate.mageobject.CardTypePredicate; public class RiptideChimera extends CardImpl { private static final FilterControlledPermanent filter = new FilterControlledPermanent("an enchantment you control"); - + static { filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); } - - + public RiptideChimera(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.CHIMERA); this.power = new MageInt(3); @@ -65,7 +64,7 @@ public class RiptideChimera extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // At the beginning of your upkeep, return an enchantment you control to its owner's hand. Effect effect = new ReturnToHandChosenControlledPermanentEffect(filter, 1); - effect.setText("return an enchanment you control to its owner's hand"); + effect.setText("return an enchantment you control to its owner's hand"); this.addAbility(new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java index 32466b5951..5d59286f57 100644 --- a/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java +++ b/Mage.Sets/src/mage/cards/r/RitualOfTheReturned.java @@ -71,7 +71,7 @@ class RitualOfTheReturnedExileEffect extends OneShotEffect { public RitualOfTheReturnedExileEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "Exile target creature card from your graveyard. Create a black Zombie creature token with power equal to the exiled card's power and toughness equal to the exiled card's toughness"; + this.staticText = "Exile target creature card from your graveyard. Create a black Zombie creature token. Its power is equal to that card's power and its toughness is equal to that card's toughness."; } public RitualOfTheReturnedExileEffect(final RitualOfTheReturnedExileEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java b/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java index 4224b95321..e8cc9eae1a 100644 --- a/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java +++ b/Mage.Sets/src/mage/cards/s/ScarwoodTreefolk.java @@ -42,16 +42,14 @@ import mage.constants.SubType; */ public class ScarwoodTreefolk extends CardImpl { - private static final String staticText = "{this} enters the battlefield tapped"; - public ScarwoodTreefolk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.TREEFOLK); this.power = new MageInt(3); this.toughness = new MageInt(5); // Scarwood Treefolk enters the battlefield tapped. - this.addAbility(new EntersBattlefieldAbility(new TapSourceEffect(), staticText)); + this.addAbility(new EntersBattlefieldAbility(new TapSourceEffect(), "tapped")); } public ScarwoodTreefolk(final ScarwoodTreefolk card) { diff --git a/Mage.Sets/src/mage/cards/s/ScreechingSliver.java b/Mage.Sets/src/mage/cards/s/ScreechingSliver.java index 410b3bb91d..6062928272 100644 --- a/Mage.Sets/src/mage/cards/s/ScreechingSliver.java +++ b/Mage.Sets/src/mage/cards/s/ScreechingSliver.java @@ -52,7 +52,7 @@ public class ScreechingSliver extends CardImpl { private static final FilterPermanent filter = new FilterPermanent(SubType.SLIVER, "All Slivers"); public ScreechingSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); @@ -63,7 +63,7 @@ public class ScreechingSliver extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, - filter, "All Sliver creatures have \"{T}: Target player puts the top card of his or her library into his or her graveyard.\""))); + filter, "All Slivers have \"{T}: Target player puts the top card of his or her library into his or her graveyard.\""))); } public ScreechingSliver(final ScreechingSliver card) { diff --git a/Mage.Sets/src/mage/cards/s/ScrybRanger.java b/Mage.Sets/src/mage/cards/s/ScrybRanger.java index 02046aa557..cf02647b4f 100644 --- a/Mage.Sets/src/mage/cards/s/ScrybRanger.java +++ b/Mage.Sets/src/mage/cards/s/ScrybRanger.java @@ -53,13 +53,14 @@ import mage.target.common.TargetCreaturePermanent; */ public class ScrybRanger extends CardImpl { - private static final FilterControlledLandPermanent filterForest = new FilterControlledLandPermanent("Forest"); + private static final FilterControlledLandPermanent filterForest = new FilterControlledLandPermanent("a Forest"); + static { filterForest.add(new SubtypePredicate(SubType.FOREST)); } public ScrybRanger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.FAERIE); this.power = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/s/SetessanTactics.java b/Mage.Sets/src/mage/cards/s/SetessanTactics.java index 05a5d4b4c6..cee3c7f116 100644 --- a/Mage.Sets/src/mage/cards/s/SetessanTactics.java +++ b/Mage.Sets/src/mage/cards/s/SetessanTactics.java @@ -58,20 +58,19 @@ public class SetessanTactics extends CardImpl { } public SetessanTactics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // Strive - Setessan Tactics costs G more to cast for each target beyond the first. this.addAbility(new StriveAbility("{G}")); // Until end of turn, any number of target creatures each get +1/+1 and gain "T: This creature fights another target creature." this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE)); - Effect effect = new BoostTargetEffect(1,1, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("Until end of turn, any number of target creatures each get +1/+1"); this.getSpellAbility().addEffect(effect); Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new FightTargetSourceEffect(), new TapSourceCost()); gainedAbility.addTarget(new TargetCreaturePermanent(filter)); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(gainedAbility, Duration.EndOfTurn, - "and gain \"T: This creature fights another target creature.\"")); + "and gain \"{T}: This creature fights another target creature.\"")); } public SetessanTactics(final SetessanTactics card) { diff --git a/Mage.Sets/src/mage/cards/s/SidewinderSliver.java b/Mage.Sets/src/mage/cards/s/SidewinderSliver.java index a550eb520d..2feea699fc 100644 --- a/Mage.Sets/src/mage/cards/s/SidewinderSliver.java +++ b/Mage.Sets/src/mage/cards/s/SidewinderSliver.java @@ -48,20 +48,23 @@ import mage.filter.predicate.mageobject.SubtypePredicate; public class SidewinderSliver extends CardImpl { static final private FilterCreaturePermanent filter = new FilterCreaturePermanent("All Sliver creatures"); - - static{ + + static { filter.add(new SubtypePredicate(SubType.SLIVER)); } - + public SidewinderSliver(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.SLIVER); this.power = new MageInt(1); this.toughness = new MageInt(1); // All Sliver creatures have flanking. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, false))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityAllEffect(new FlankingAbility(), Duration.WhileOnBattlefield, filter, false) + .setText("all Slivers have flanking") + )); } public SidewinderSliver(final SidewinderSliver card) { diff --git a/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java b/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java index a05a6a3986..9433de0741 100644 --- a/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java +++ b/Mage.Sets/src/mage/cards/s/SlaveOfBolas.java @@ -54,12 +54,12 @@ import mage.target.targetpointer.FixedTarget; public class SlaveOfBolas extends CardImpl { public SlaveOfBolas(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U/R}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U/R}{B}"); // Gain control of target creature. Untap that creature. It gains haste until end of turn. Sacrifice it at the beginning of the next end step. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.getSpellAbility().addEffect(new SlaveOfBolasEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/s/SpellSwindle.java b/Mage.Sets/src/mage/cards/s/SpellSwindle.java index ff0a1baae8..a956b52b36 100644 --- a/Mage.Sets/src/mage/cards/s/SpellSwindle.java +++ b/Mage.Sets/src/mage/cards/s/SpellSwindle.java @@ -69,7 +69,7 @@ class SpellSwindleEffect extends OneShotEffect { public SpellSwindleEffect() { super(Outcome.Detriment); staticText = "Counter target spell. Create X colorless Treasure artifact tokens, where X is that spell's converted mana cost. " - + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool\""; + + "They have \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool.\""; } public SpellSwindleEffect(final SpellSwindleEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java b/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java index bb1977c5a4..2b708e2376 100644 --- a/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java +++ b/Mage.Sets/src/mage/cards/s/SpinalEmbrace.java @@ -66,7 +66,7 @@ public class SpinalEmbrace extends CardImpl { } public SpinalEmbrace(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}{B}"); // Cast Spinal Embrace only during combat. this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT)); @@ -77,7 +77,7 @@ public class SpinalEmbrace extends CardImpl { Effect effect = new GainControlTargetEffect(Duration.EndOfTurn); effect.setText("and gain control of it"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn")); this.getSpellAbility().addEffect(new SpinalEmbraceAddDelayedEffect()); } diff --git a/Mage.Sets/src/mage/cards/s/Spirespine.java b/Mage.Sets/src/mage/cards/s/Spirespine.java index 056814ee38..84e2e02ffd 100644 --- a/Mage.Sets/src/mage/cards/s/Spirespine.java +++ b/Mage.Sets/src/mage/cards/s/Spirespine.java @@ -51,7 +51,7 @@ import mage.constants.Zone; public class Spirespine extends CardImpl { public Spirespine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT,CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(4); @@ -61,12 +61,12 @@ public class Spirespine extends CardImpl { this.addAbility(new BestowAbility(this, "{4}{G}")); // Spirespine blocks each turn if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BlocksIfAbleSourceEffect(Duration.WhileOnBattlefield))); - // Enchanted creature gets +4/+1 and blocks each turn if able. - Effect effect = new BoostEnchantedEffect(4,1, Duration.WhileOnBattlefield); + // Enchanted creature gets +4/+1 and blocks each combat if able. + Effect effect = new BoostEnchantedEffect(4, 1, Duration.WhileOnBattlefield); effect.setText("Enchanted creature gets +4/+1"); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); effect = new BlocksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA); - effect.setText("and blocks each turn if able"); + effect.setText("and blocks each combat if able"); ability.addEffect(effect); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java index eec83b174c..c62904dbd1 100644 --- a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java +++ b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java @@ -60,7 +60,7 @@ public class StormFleetAerialist extends CardImpl { // Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.instance, - "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); } diff --git a/Mage.Sets/src/mage/cards/s/StranglingSoot.java b/Mage.Sets/src/mage/cards/s/StranglingSoot.java index a0d58fff08..e0d40c4eb8 100644 --- a/Mage.Sets/src/mage/cards/s/StranglingSoot.java +++ b/Mage.Sets/src/mage/cards/s/StranglingSoot.java @@ -45,7 +45,7 @@ import mage.target.common.TargetCreaturePermanent; */ public class StranglingSoot extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with toughess 3 or less"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with toughness 3 or less"); static { filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, 4)); diff --git a/Mage.Sets/src/mage/cards/s/SurgingAether.java b/Mage.Sets/src/mage/cards/s/SurgingAether.java index ccb530ace5..79d406787f 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingAether.java +++ b/Mage.Sets/src/mage/cards/s/SurgingAether.java @@ -45,7 +45,7 @@ public class SurgingAether extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); // Return target permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SurgingDementia.java b/Mage.Sets/src/mage/cards/s/SurgingDementia.java index dfe6b8e92c..d24c284691 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingDementia.java +++ b/Mage.Sets/src/mage/cards/s/SurgingDementia.java @@ -42,10 +42,10 @@ import mage.target.TargetPlayer; public class SurgingDementia extends CardImpl { public SurgingDementia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); // Target player discards a card. this.getSpellAbility().getEffects().add(new DiscardTargetEffect(1)); diff --git a/Mage.Sets/src/mage/cards/s/SurgingFlame.java b/Mage.Sets/src/mage/cards/s/SurgingFlame.java index 07ab76ed79..2a7b218a35 100644 --- a/Mage.Sets/src/mage/cards/s/SurgingFlame.java +++ b/Mage.Sets/src/mage/cards/s/SurgingFlame.java @@ -42,10 +42,11 @@ import mage.target.common.TargetCreatureOrPlayer; public class SurgingFlame extends CardImpl { public SurgingFlame(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); // Ripple 4 - this.addAbility(new RippleAbility(4)); + this.addAbility(new RippleAbility(4).setRuleAtTheTop(true)); + // Surging Flame deals 2 damage to target creature or player. this.getSpellAbility().addEffect(new DamageTargetEffect(2)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); diff --git a/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java b/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java index a5499529a0..e5a2333fac 100644 --- a/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java +++ b/Mage.Sets/src/mage/cards/s/SwarmbornGiant.java @@ -56,7 +56,7 @@ import mage.game.events.GameEvent.EventType; public class SwarmbornGiant extends CardImpl { public SwarmbornGiant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); this.subtype.add(SubType.GIANT); this.power = new MageInt(6); @@ -67,13 +67,13 @@ public class SwarmbornGiant extends CardImpl { // {4}{G}{G}: Monstrosity 2. this.addAbility(new MonstrosityAbility("{4}{G}{G}", 2)); - + // As long as Swarmborn Giant is monstrous, it has reach. Ability ability = new SimpleStaticAbility( Zone.BATTLEFIELD, new ConditionalContinuousEffect(new GainAbilitySourceEffect(ReachAbility.getInstance(), Duration.WhileOnBattlefield), - MonstrousCondition.instance, - "As long as {this} is monstrous, it has reach")); + MonstrousCondition.instance, + "As long as {this} is monstrous, it has reach")); this.addAbility(ability); } @@ -118,6 +118,6 @@ class SwarmbornGiantTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever you're dealt combat damage, " + super.getRule(); + return "When you're dealt combat damage, " + super.getRule(); } } diff --git a/Mage.Sets/src/mage/cards/t/Threaten.java b/Mage.Sets/src/mage/cards/t/Threaten.java index 6dfbd42c48..99759fa85d 100644 --- a/Mage.Sets/src/mage/cards/t/Threaten.java +++ b/Mage.Sets/src/mage/cards/t/Threaten.java @@ -45,11 +45,11 @@ import mage.target.common.TargetCreaturePermanent; public class Threaten extends CardImpl { public Threaten(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap target creature")); + this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn).setText("and gain control of it until end of turn")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("It gains haste until end of turn.")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/t/TraitorousBlood.java b/Mage.Sets/src/mage/cards/t/TraitorousBlood.java index 81f5feb49b..f240d5a7e4 100644 --- a/Mage.Sets/src/mage/cards/t/TraitorousBlood.java +++ b/Mage.Sets/src/mage/cards/t/TraitorousBlood.java @@ -46,15 +46,14 @@ import mage.target.common.TargetCreaturePermanent; public class TraitorousBlood extends CardImpl { public TraitorousBlood(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}{R}"); // Gain control of target creature until end of turn. Untap it. It gains trample and haste until end of turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn).setText("It gains trample")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and hast until end of turn")); } public TraitorousBlood(final TraitorousBlood card) { diff --git a/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java b/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java index bf08200c80..cda61457d7 100644 --- a/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java +++ b/Mage.Sets/src/mage/cards/t/TraitorousInstinct.java @@ -46,14 +46,13 @@ import mage.target.common.TargetCreaturePermanent; public class TraitorousInstinct extends CardImpl { public TraitorousInstinct(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect()); - this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn).setText("Until end of turn, it gets +2/+0")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("and gains haste")); } public TraitorousInstinct(final TraitorousInstinct card) { diff --git a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java index 128d109df8..87525a45d8 100644 --- a/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java +++ b/Mage.Sets/src/mage/cards/v/VesuvanShapeshifter.java @@ -72,9 +72,6 @@ public class VesuvanShapeshifter extends CardImpl { this.power = new MageInt(0); this.toughness = new MageInt(0); - // Morph {1}{U} - this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}"))); - // As Vesuvan Shapeshifter turned face up, may choose another creature. If you do, until Vesuvan Shapeshifter is turned face down, it becomes a copy of that creature Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new AsTurnedFaceUpEffect(new VesuvanShapeshifterEffect(), false)); ability.setWorksFaceDown(true); @@ -91,6 +88,9 @@ public class VesuvanShapeshifter extends CardImpl { effect = new VesuvanShapeshifterFaceDownEffect(); ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, true); this.addAbility(ability); + + // Morph {1}{U} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{U}"))); } public VesuvanShapeshifter(final VesuvanShapeshifter card) { diff --git a/Mage.Sets/src/mage/cards/v/VexingSphinx.java b/Mage.Sets/src/mage/cards/v/VexingSphinx.java index 3a1f7376c2..d5908b2b31 100644 --- a/Mage.Sets/src/mage/cards/v/VexingSphinx.java +++ b/Mage.Sets/src/mage/cards/v/VexingSphinx.java @@ -30,7 +30,7 @@ package mage.cards.v; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DiesTriggeredAbility; -import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.keyword.FlyingAbility; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -40,7 +40,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; -import mage.target.common.TargetCardInHand; /** * @@ -59,7 +58,7 @@ public class VexingSphinx extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Cumulative upkeep-Discard a card. - this.addAbility(new CumulativeUpkeepAbility(new DiscardTargetCost(new TargetCardInHand()))); + this.addAbility(new CumulativeUpkeepAbility(new DiscardCardCost())); // When Vexing Sphinx dies, draw a card for each age counter on it. this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(new CountersSourceCount(CounterType.AGE)))); diff --git a/Mage.Sets/src/mage/cards/w/WheelOfFate.java b/Mage.Sets/src/mage/cards/w/WheelOfFate.java index fa76391cce..4dd0bd1ae0 100644 --- a/Mage.Sets/src/mage/cards/w/WheelOfFate.java +++ b/Mage.Sets/src/mage/cards/w/WheelOfFate.java @@ -43,7 +43,7 @@ import mage.constants.CardType; public class WheelOfFate extends CardImpl { public WheelOfFate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},""); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); this.color.setRed(true); @@ -51,7 +51,7 @@ public class WheelOfFate extends CardImpl { this.addAbility(new SuspendAbility(4, new ManaCostsImpl("{1}{R}"), this)); // Each player discards his or her hand, then draws seven cards. this.getSpellAbility().addEffect(new DiscardHandAllEffect()); - this.getSpellAbility().addEffect(new DrawCardAllEffect(7)); + this.getSpellAbility().addEffect(new DrawCardAllEffect(7).setText(", then draws seven cards")); } public WheelOfFate(final WheelOfFate card) { diff --git a/Mage.Sets/src/mage/cards/w/WormwoodDryad.java b/Mage.Sets/src/mage/cards/w/WormwoodDryad.java index b82f938a24..3751876afd 100644 --- a/Mage.Sets/src/mage/cards/w/WormwoodDryad.java +++ b/Mage.Sets/src/mage/cards/w/WormwoodDryad.java @@ -50,7 +50,7 @@ import mage.constants.Zone; public class WormwoodDryad extends CardImpl { public WormwoodDryad(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.DRYAD); this.power = new MageInt(3); this.toughness = new MageInt(1); @@ -58,13 +58,13 @@ public class WormwoodDryad extends CardImpl { // {G}: Wormwood Dryad gains forestwalk until end of turn and deals 1 damage to you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new ForestwalkAbility(false), Duration.EndOfTurn), new ManaCostsImpl("{G}")); - ability.addEffect(new DamageControllerEffect(1)); + ability.addEffect(new DamageControllerEffect(1).setText("and deals 1 damage to you")); this.addAbility(ability); // {B}: Wormwood Dryad gains swampwalk until end of turn and deals 1 damage to you. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(new SwampwalkAbility(false), Duration.EndOfTurn), new ManaCostsImpl("{B}")); - ability.addEffect(new DamageControllerEffect(1)); + ability.addEffect(new DamageControllerEffect(1).setText("and deals 1 damage to you")); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/SpellAbility.java b/Mage/src/main/java/mage/abilities/SpellAbility.java index 7c6228f5ce..f09f246b7f 100644 --- a/Mage/src/main/java/mage/abilities/SpellAbility.java +++ b/Mage/src/main/java/mage/abilities/SpellAbility.java @@ -97,9 +97,11 @@ public class SpellAbility extends ActivatedAbilityImpl { return false; } // fix for Gitaxian Probe and casting opponent's spells - if (!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game) - && !controllerId.equals(playerId) && getZone() != Zone.HAND) { - return false; + if (!game.getContinuousEffects().asThough(getSourceId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, playerId, game)) { + Card card = game.getCard(sourceId); + if (!(card != null && card.getOwnerId() == playerId)) { + return false; + } } // Check if rule modifying events prevent to cast the spell in check playable mode if (this.isCheckPlayableMode()) { diff --git a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java index 3d474b252a..9fc545d982 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/IsStepCondition.java @@ -59,7 +59,7 @@ public class IsStepCondition implements Condition { public String toString() { StringBuilder sb = new StringBuilder("during "); if (onlyDuringYourSteps) { - sb.append("your "); + sb.append("your ").append(phaseStep.getStepText()); } else if (phaseStep == PhaseStep.UPKEEP) { sb.append("any upkeep step"); } else { diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java index 28576b5eed..5f692b1a26 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java @@ -61,10 +61,15 @@ public class ExileFromStackCost extends CostImpl { if (spellToExile == null) { return false; } - spellToExile.moveToExile(null, "", ability.getSourceId(), game); + String spellName = spellToExile.getName(); + if (spellToExile.isCopy()) { + game.getStack().remove(spellToExile); + } else { + spellToExile.moveToExile(null, "", ability.getSourceId(), game); + } paid = true; if (!game.isSimulation()) { - game.informPlayers(player.getLogName() + " exiles " + spellToExile.getName() + " (as costs)"); + game.informPlayers(player.getLogName() + " exiles " + spellName + " (as costs)"); } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java index 14803dfc47..633d8a0bd3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java @@ -63,7 +63,9 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { staticText = "Add " + (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "") + " mana " - + (oneChoice ? "of any one color" : "in any combination of colors") + + (oneChoice ? "of any" + + (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one") + + " color" : "in any combination of colors") + " to your mana pool. " + manaBuilder.getRule(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 56c2b43515..a6c556be36 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -277,14 +277,14 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect { if (tapped && !attacking) { sb.append("tapped "); } - sb.append("token"); + sb.append("token that's a copy of target creature"); } else { sb.append(number); sb.append(" "); if (tapped && !attacking) { sb.append("tapped "); } - sb.append("tokens"); + sb.append("tokens that are copies of target creature"); } if (attacking) { sb.append(" that are"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java index a1167c7f02..aa07e5bdd0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventDamageToTargetEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import mage.constants.Duration; @@ -45,23 +44,23 @@ public class PreventDamageToTargetEffect extends PreventionEffectImpl { public PreventDamageToTargetEffect(Duration duration) { this(duration, false); } - + public PreventDamageToTargetEffect(Duration duration, boolean onlyCombat) { this(duration, Integer.MAX_VALUE, onlyCombat); } - + public PreventDamageToTargetEffect(Duration duration, int amount) { this(duration, amount, false); } - + public PreventDamageToTargetEffect(Duration duration, int amount, boolean onlyCombat) { super(duration, amount, onlyCombat); } - + public PreventDamageToTargetEffect(Duration duration, boolean onlyCombat, boolean consumable, DynamicValue amountToPreventDynamic) { super(duration, 0, onlyCombat, consumable, amountToPreventDynamic); } - + public PreventDamageToTargetEffect(final PreventDamageToTargetEffect effect) { super(effect); } @@ -83,9 +82,9 @@ public class PreventDamageToTargetEffect extends PreventionEffectImpl { } StringBuilder sb = new StringBuilder(); if (amountToPrevent == Integer.MAX_VALUE) { - sb.append("Prevent all damage that would be dealt to target "); + sb.append("prevent all damage that would be dealt to target "); } else { - sb.append("Prevent the next ").append(amountToPrevent).append(" damage that would be dealt to target "); + sb.append("prevent the next ").append(amountToPrevent).append(" damage that would be dealt to target "); } sb.append(mode.getTargets().get(0).getTargetName()); if (!duration.toString().isEmpty()) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java index 27b2e0c149..717a3426b5 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutTopCardOfLibraryIntoGraveTargetEffect.java @@ -75,7 +75,7 @@ public class PutTopCardOfLibraryIntoGraveTargetEffect extends OneShotEffect { } private String setText() { - StringBuilder sb = new StringBuilder("Target player puts the top "); + StringBuilder sb = new StringBuilder("target player puts the top "); if (numberCards.toString().equals("1")) { sb.append(" card"); } else { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java index 2ab4c45591..ad80dffa49 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandTargetEffect.java @@ -27,7 +27,9 @@ */ package mage.abilities.effects.common; +import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import java.util.UUID; import mage.MageObject; @@ -38,6 +40,7 @@ import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; +import mage.game.stack.Spell; import mage.players.Player; import mage.target.Target; import mage.util.CardUtil; @@ -74,12 +77,15 @@ public class ReturnToHandTargetEffect extends OneShotEffect { if (controller == null) { return false; } + List copyIds = new ArrayList<>(); Set cards = new LinkedHashSet<>(); if (multitargetHandling) { for (Target target : source.getTargets()) { for (UUID targetId : target.getTargets()) { MageObject mageObject = game.getObject(targetId); - if (mageObject instanceof Card) { + if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { + copyIds.add(targetId); + } else if (mageObject instanceof Card) { cards.add((Card) mageObject); } } @@ -88,10 +94,17 @@ public class ReturnToHandTargetEffect extends OneShotEffect { for (UUID targetId : targetPointer.getTargets(game, source)) { MageObject mageObject = game.getObject(targetId); if (mageObject != null) { - cards.add((Card) mageObject); + if (mageObject instanceof Spell && ((Spell) mageObject).isCopy()) { + copyIds.add(targetId); + } else { + cards.add((Card) mageObject); + } } } } + for (UUID copyId : copyIds) { + game.getStack().remove(game.getSpell(copyId)); + } return controller.moveCards(cards, Zone.HAND, source, game); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java index cca02db55a..08ca0c506f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TapAllTargetPlayerControlsEffect.java @@ -80,6 +80,6 @@ public class TapAllTargetPlayerControlsEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "tap all " + filter.getMessage() + " target " + mode.getTargets().get(0).getMessage() + " controls"; + return "tap all " + filter.toString() + " target " + mode.getTargets().get(0).getMessage() + " controls"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java index 988c75ff76..c7dd2cf8c2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleAttachedEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.combat; import mage.abilities.Ability; @@ -38,12 +37,11 @@ import mage.game.permanent.Permanent; /** * @author LevelX2 */ - public class BlocksIfAbleAttachedEffect extends RequirementEffect { public BlocksIfAbleAttachedEffect(Duration duration, AttachmentType attachmentType) { super(duration); - this.staticText = attachmentType.verb() + " creature blocks each turn if able"; + this.staticText = attachmentType.verb() + " creature blocks each combat if able"; } public BlocksIfAbleAttachedEffect(final BlocksIfAbleAttachedEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java index 97e46cc571..1fda34c497 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/BlocksIfAbleSourceEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.combat; import mage.abilities.Ability; @@ -39,7 +38,6 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ - public class BlocksIfAbleSourceEffect extends RequirementEffect { public BlocksIfAbleSourceEffect(Duration duration) { @@ -78,7 +76,7 @@ public class BlocksIfAbleSourceEffect extends RequirementEffect { @Override public String getText(Mode mode) { - return "{this} blocks each turn if able."; + return "{this} blocks each combat if able."; } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java index 7f1c8b1de7..c03f59a035 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/MustBeBlockedByAtLeastOneTargetEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.combat; import java.util.UUID; @@ -35,35 +34,32 @@ import mage.constants.Duration; import mage.game.Game; import mage.game.permanent.Permanent; - /** * !! This effect does only support one target. * * * http://tappedout.net/mtg-questions/must-be-blocked-if-able-effect-makes-other-attacking-creatures-essentially-unblockable/ * - * When you Declare Blockers, you choose an arrangement for your blockers, - * then check to see if there are any restrictions or requirements. + * When you Declare Blockers, you choose an arrangement for your blockers, then + * check to see if there are any restrictions or requirements. * - * If any restrictions are violated, the block is illegal. (For example, - * trying to block with Sightless Ghoul) - * If any requirements are violated, the least possible number of requirements - * must be violated, otherwise the block is illegal. (For example, your opponent - * control two creatures that he has cast Deadly Allure on, but you control only - * one creature. Blocking either one will violate a requirement, "This creature - * must be blocked this turn if able", but it will also violate the least - * possible number of requirements, thus it is legal.) - * If the block is illegal, the game state backs up and you declare blockers - * again. (Note that while you can, in some cases, circumvent requirements - * such as "This creature must be blocked" or "This creature must block - * any attacking creature" you can never circumvent restrictions: "This creature - * can't block" or "Only one creature may block this turn.") - * Because you declare ALL your blockers at once, THEN check for - * restrictions/requirements, you may block Deadly Allure'd creatures - * with only one creature, if you choose. - * This still works with Lure: This card sets up a requirement that ALL - * creatures must block it if able. Any block that violates more than - * the minimum number of requirements is still illegal. + * If any restrictions are violated, the block is illegal. (For example, trying + * to block with Sightless Ghoul) If any requirements are violated, the least + * possible number of requirements must be violated, otherwise the block is + * illegal. (For example, your opponent control two creatures that he has cast + * Deadly Allure on, but you control only one creature. Blocking either one will + * violate a requirement, "This creature must be blocked this turn if able", but + * it will also violate the least possible number of requirements, thus it is + * legal.) If the block is illegal, the game state backs up and you declare + * blockers again. (Note that while you can, in some cases, circumvent + * requirements such as "This creature must be blocked" or "This creature must + * block any attacking creature" you can never circumvent restrictions: "This + * creature can't block" or "Only one creature may block this turn.") Because + * you declare ALL your blockers at once, THEN check for + * restrictions/requirements, you may block Deadly Allure'd creatures with only + * one creature, if you choose. This still works with Lure: This card sets up a + * requirement that ALL creatures must block it if able. Any block that violates + * more than the minimum number of requirements is still illegal. * * @author LevelX2 */ @@ -75,7 +71,7 @@ public class MustBeBlockedByAtLeastOneTargetEffect extends RequirementEffect { public MustBeBlockedByAtLeastOneTargetEffect(Duration duration) { super(duration); - staticText = "Target creature must be blocked this turn if able"; + staticText = "target creature must be blocked this turn if able"; } public MustBeBlockedByAtLeastOneTargetEffect(final MustBeBlockedByAtLeastOneTargetEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java b/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java index 797a5edcf9..5be2bb16f2 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/search/SearchTargetGraveyardHandLibraryForCardNameAndExileEffect.java @@ -129,7 +129,7 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect @Override public String getText(Mode mode) { StringBuilder sb = new StringBuilder(); - sb.append("Search ").append(this.searchWhatText); + sb.append("search ").append(this.searchWhatText); sb.append(" graveyard, hand, and library for "); sb.append(this.searchForText); sb.append(" and exile them. Then that player shuffles his or her library"); diff --git a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java index f24a1a8817..42144532db 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CumulativeUpkeepAbility.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.OrCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; @@ -70,9 +71,11 @@ public class CumulativeUpkeepAbility extends BeginningOfUpkeepTriggeredAbility { @Override public String getRule() { - StringBuilder sb = new StringBuilder("Cumulative upkeep "); - if (!(cumulativeCost instanceof ManaCost)) { - sb.append("— "); + StringBuilder sb = new StringBuilder("Cumulative upkeep"); + if (!(cumulativeCost instanceof ManaCost || cumulativeCost instanceof OrCost)) { + sb.append("—"); + } else { + sb.append(' '); } sb.append(cumulativeCost.getText()); return sb.toString(); diff --git a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java index c8a4aefa48..8d082c8076 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmbalmAbility.java @@ -105,23 +105,24 @@ class EmbalmEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) - token.getColor(game).setColor(ObjectColor.WHITE); - if (!token.hasSubtype(SubType.ZOMBIE, game)) { - token.getSubtype(game).add(0, SubType.ZOMBIE); - } - token.getManaCost().clear(); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); - // Probably it makes sense to remove also the Embalm ability (it's not shown on the token cards). - // Also it can never get active or? But it's not mentioned in the reminder text. - return true; + if (card == null) { + return false; } - - return false; + Player controller = game.getPlayer(card.getOwnerId()); + if (controller == null) { + return false; + } + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.WHITE); + if (!token.hasSubtype(SubType.ZOMBIE, game)) { + token.getSubtype(game).add(0, SubType.ZOMBIE); + } + token.getManaCost().clear(); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EMBALMED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); + token.putOntoBattlefield(1, game, source.getSourceId(), controller.getId(), false, false, null); + // Probably it makes sense to remove also the Embalm ability (it's not shown on the token cards). + // Also it can never get active or? But it's not mentioned in the reminder text. + return true; } - } diff --git a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java index dd46c9d9d7..c25c06d639 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EternalizeAbility.java @@ -59,11 +59,11 @@ public class EternalizeAbility extends ActivatedAbilityImpl { this.timing = TimingRule.SORCERY; setRule(cost, card); } - + public EternalizeAbility(Cost cost, Card card, String rule) { this(cost, card); this.rule = rule; - } + } public EternalizeAbility(final EternalizeAbility ability) { super(ability); @@ -110,26 +110,27 @@ class EternalizeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Card card = game.getCard(source.getSourceId()); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null) { - EmptyToken token = new EmptyToken(); - CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) - token.getColor(game).setColor(ObjectColor.BLACK); - if (!token.hasSubtype(SubType.ZOMBIE, game)) { - token.getSubtype(game).add(0, SubType.ZOMBIE); - } - token.getManaCost().clear(); - token.removePTCDA(); - token.getPower().modifyBaseValue(4); - token.getToughness().modifyBaseValue(4); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); - token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), false, false, null); - // Probably it makes sense to remove also the Eternalize ability (it's not shown on the token cards). - // Also it can never get active or? But it's not mentioned in the reminder text. - return true; + if (card == null) { + return false; } - - return false; + Player controller = game.getPlayer(card.getOwnerId()); + if (controller == null) { + return false; + } + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(card); // needed so that entersBattlefied triggered abilities see the attributes (e.g. Master Biomancer) + token.getColor(game).setColor(ObjectColor.BLACK); + if (!token.hasSubtype(SubType.ZOMBIE, game)) { + token.getSubtype(game).add(0, SubType.ZOMBIE); + } + token.getManaCost().clear(); + token.removePTCDA(); + token.getPower().modifyBaseValue(4); + token.getToughness().modifyBaseValue(4); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ETERNALIZED_CREATURE, token.getId(), source.getSourceId(), controller.getId())); + token.putOntoBattlefield(1, game, source.getSourceId(), controller.getId(), false, false, null); + // Probably it makes sense to remove also the Eternalize ability (it's not shown on the token cards). + // Also it can never get active or? But it's not mentioned in the reminder text. + return true; } - } diff --git a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java index d8df61ca87..ce887d86e0 100644 --- a/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/FlankingAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import mage.abilities.TriggeredAbilityImpl; @@ -11,12 +10,9 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; - /** * @author Plopman */ - - public class FlankingAbility extends TriggeredAbilityImpl { public FlankingAbility() { @@ -37,9 +33,8 @@ public class FlankingAbility extends TriggeredAbilityImpl { if (event.getTargetId().equals(this.getSourceId())) { Permanent permanent = game.getPermanent(event.getSourceId()); if (permanent != null) { - boolean hasFlankingAbility = - permanent.getAbilities().stream().anyMatch(ability -> ability instanceof FlankingAbility); - + boolean hasFlankingAbility + = permanent.getAbilities().stream().anyMatch(ability -> ability instanceof FlankingAbility); if (!hasFlankingAbility) { for (Effect effect : this.getEffects()) { @@ -54,7 +49,7 @@ public class FlankingAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Flanking"; + return "flanking"; } @Override @@ -62,5 +57,4 @@ public class FlankingAbility extends TriggeredAbilityImpl { return new FlankingAbility(this); } - } diff --git a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java index 557236e5ca..dfe545198c 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MorphAbility.java @@ -138,7 +138,11 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost break; } } - sb.append(morphCosts.getText()).append(' '); + sb.append(morphCosts.getText()); + if (!(morphCosts.get(morphCosts.size() - 1) instanceof ManaCosts)) { + sb.append('.'); + } + sb.append(' '); if (megamorph) { sb.append(REMINDER_TEXT_MEGA); } else { diff --git a/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java b/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java index 29fde94fe9..b35919daa5 100644 --- a/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/RampageAbility.java @@ -46,7 +46,7 @@ public class RampageAbility extends BecomesBlockedTriggeredAbility { public RampageAbility(int amount) { super(null, false); - rule = "rampage " + amount + "(Whenever this creature becomes blocked, it gets +" + rule = "rampage " + amount + " (Whenever this creature becomes blocked, it gets +" + amount + "/+" + amount + " until end of turn for each creature blocking it beyond the first.)"; RampageValue rv = new RampageValue(amount); this.addEffect(new BoostSourceEffect(rv, rv, Duration.EndOfTurn, true)); diff --git a/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java b/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java index 667e4aa22f..2573570731 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ShadowAbility.java @@ -12,10 +12,12 @@ import mage.game.permanent.Permanent; /** * "Shadow" keyword + * * @author Loki */ public class ShadowAbility extends EvasionAbility implements MageSingleton { - private static final ShadowAbility instance = new ShadowAbility(); + + private static final ShadowAbility instance = new ShadowAbility(); private Object readResolve() throws ObjectStreamException { return instance; @@ -31,7 +33,7 @@ public class ShadowAbility extends EvasionAbility implements MageSingleton { @Override public String getRule() { - return "Shadow (This creature can block or be blocked by only creatures with shadow.)"; + return "shadow (This creature can block or be blocked by only creatures with shadow.)"; } @Override diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 60c7d931a3..84695fd94f 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -59,7 +59,7 @@ public final class StaticFilters { public static final FilterCreaturePermanent FILTER_PERMANENT_A_CREATURE = new FilterCreaturePermanent("a creature"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURES = new FilterCreaturePermanent("creatures"); public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_GOBLINS = new FilterCreaturePermanent(SubType.GOBLIN, "Goblin creatures"); - public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "Sliver creatures"); + public static final FilterCreaturePermanent FILTER_PERMANENT_CREATURE_SLIVERS = new FilterCreaturePermanent(SubType.SLIVER, "all Sliver creatures"); public static final FilterPlaneswalkerPermanent FILTER_PERMANENT_PLANESWALKER = new FilterPlaneswalkerPermanent(); public static final FilterPermanent FILTER_PERMANENT_NON_LAND = new FilterNonlandPermanent(); diff --git a/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java b/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java index 813ae0951d..5dce07ed4c 100644 --- a/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java +++ b/Mage/src/main/java/mage/target/common/TargetOpponentsChoicePermanent.java @@ -6,6 +6,7 @@ package mage.target.common; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.constants.Outcome; import mage.filter.FilterPermanent; @@ -49,7 +50,7 @@ public class TargetOpponentsChoicePermanent extends TargetPermanent { if (opponentId != null) { if (permanent != null) { if (source != null) { - boolean canSourceControllerTarget = true; + boolean canSourceControllerTarget = true; if (!isNotTarget()) { if (!permanent.canBeTargetedBy(game.getObject(source.getId()), controllerId, game) || !permanent.canBeTargetedBy(game.getObject(source.getSourceId()), controllerId, game)) { @@ -70,6 +71,33 @@ public class TargetOpponentsChoicePermanent extends TargetPermanent { return super.chooseTarget(outcome, getOpponentId(playerId, source, game), source, game); } + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + MageObject sourceObject = game.getObject(sourceId); + Player player = game.getPlayer(sourceControllerId); + if (sourceObject == null || player == null) { + return false; + } + int counter; + for (UUID oppId : game.getState().getPlayersInRange(player.getId(), game)) { + counter = 0; + Player opp = game.getPlayer(oppId); + if (opp != null && player.hasOpponent(opp.getId(), game)) { + for (Permanent perm : game.getBattlefield().getActivePermanents(opp.getId(), game)) { + if (!targets.containsKey(perm.getId()) + && filter.match(perm, sourceId, opp.getId(), game) + && perm.canBeTargetedBy(sourceObject, sourceControllerId, game)) { + counter++; + if (counter >= minNumberOfTargets) { + return true; + } + } + } + } + } + return false; + } + @Override public TargetOpponentsChoicePermanent copy() { return new TargetOpponentsChoicePermanent(this); diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index 1f20dfa9a9..15cf441444 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -90,6 +90,7 @@ Grand Prix|GrandPrix| Guildpact|Guildpact| Guru|Guru| HASCON Promo 2017|HasconPromo2017| +Heroes of the Realm|HeroesOfTheRealm| Homelands|Homelands| Hour of Devastation|HourOfDevastation| Ice Age|IceAge| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 50afc19e1c..1152e94dc2 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32693,3 +32693,6 @@ Mountain|Duel Decks: Mind vs. Might|62|L||Basic Land - Mountain|||{T}: Add {R} t Forest|Duel Decks: Mind vs. Might|63|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| Forest|Duel Decks: Mind vs. Might|64|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| Forest|Duel Decks: Mind vs. Might|65|L||Basic Land - Forest|||{T}: Add {G} to your mana pool.| +Chandra, Gremlin Wrangler|Heroes of the Realm|1|M|{2}{R}{R}|Legendary Planeswalker - Chandra|3||+1: Create a 2/2 red Gremlin creature token.$-2:Chandra, Gremlin Wrangler deals X damage to target creature or player, where X is the number of Gremlins you control.| +Dungeon Master|Heroes of the Realm|1|M|{2}{W}{U}|Legendary Planeswalker - Dungeon Master|||+1: Target opponent creates a 1/1 black Skeleton creature token with “When this creature dies, each opponent loses 2 life.”$+1: Roll a d20. If you roll a 1, skip your next turn. If you roll a 12 or higher, draw a card.$-6: You get an adventuring party. (Your party is a 3/3 red Fighter with first strike, a 1/1 white Cleric with lifelink, a 2/2 black Rogue with hexproof, and a 1/1 blue Wizard with flying.)| +Nira, Hellkite Duelist|Heroes of the Realm|3|M|{W}{U}{B}{R}{G}|Legendary Creature — Dragon|6|6|Flash$Flying, trample, haste$When Nira, Hellkite Duelist enters the battlefield, the next time you would lose the game this turn, instead draw three cards and your life total becomes 5.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index f5b538022d..e5bd417a30 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -93,6 +93,7 @@ Gatecrash|GTC| Guru|GUR| Premium Deck Series: Slivers|H09| Homelands|HML| +Heroes of the Realm|HOTR| Planechase|HOP| Hour of Devastation|HOU| Ice Age|ICE|