From 041ad9e0367bfe42aa80bf0938a17a1cd05a3e4e Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 15 Apr 2018 11:33:57 +0200 Subject: [PATCH] [DOM] Added three cards. Some fixes to rule texts and some more minor fixes. --- .../mage/cards/b/BairdStewardOfArgive.java | 9 +- .../mage/cards/b/BoardTheWeatherlight.java | 4 +- .../src/mage/cards/d/DaringArchaeologist.java | 10 +- Mage.Sets/src/mage/cards/e/EnigmaSphinx.java | 30 ++-- .../mage/cards/k/KioraTheCrashingWave.java | 4 +- Mage.Sets/src/mage/cards/l/LongTermPlans.java | 27 +--- Mage.Sets/src/mage/cards/s/SerraDisciple.java | 10 +- .../src/mage/cards/s/ShalaiVoiceOfPlenty.java | 5 +- .../src/mage/cards/t/TatyovaBenthicDruid.java | 8 +- .../mage/cards/t/TeferiHeroOfDominaria.java | 132 ++++++++++++++++++ .../src/mage/cards/t/TeferiTimebender.java | 86 ++++++++++++ .../src/mage/cards/t/TeferisSentinel.java | 78 +++++++++++ .../mage/cards/t/TesharAncestorsApostle.java | 9 +- Mage.Sets/src/mage/cards/t/TragicPoet.java | 5 +- Mage.Sets/src/mage/sets/Dominaria.java | 5 +- .../DrawCardControllerTriggeredAbility.java | 12 +- .../mage/abilities/common/SagaAbility.java | 2 +- .../effects/common/BasicManaEffect.java | 4 +- .../effects/common/UntapLandsEffect.java | 14 +- .../keyword/HexproofFromBlackAbility.java | 9 +- .../keyword/HexproofFromWhiteAbility.java | 9 +- .../main/java/mage/filter/StaticFilters.java | 6 + .../main/java/mage/game/ZoneChangeInfo.java | 26 ++-- .../src/main/java/mage/game/ZonesHandler.java | 2 +- .../emblems/TeferiHeroOfDominariaEmblem.java | 34 +++++ Mage/src/main/java/mage/players/Library.java | 29 +++- 26 files changed, 464 insertions(+), 105 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java create mode 100644 Mage.Sets/src/mage/cards/t/TeferiTimebender.java create mode 100644 Mage.Sets/src/mage/cards/t/TeferisSentinel.java create mode 100644 Mage/src/main/java/mage/game/command/emblems/TeferiHeroOfDominariaEmblem.java diff --git a/Mage.Sets/src/mage/cards/b/BairdStewardOfArgive.java b/Mage.Sets/src/mage/cards/b/BairdStewardOfArgive.java index eaefe8e4257..0a38bac1c17 100644 --- a/Mage.Sets/src/mage/cards/b/BairdStewardOfArgive.java +++ b/Mage.Sets/src/mage/cards/b/BairdStewardOfArgive.java @@ -28,7 +28,6 @@ package mage.cards.b; import java.util.UUID; - import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -42,8 +41,7 @@ import mage.constants.SuperType; import mage.constants.Zone; /** - * @author JRHerlehy - * Created on 4/4/18. + * @author JRHerlehy Created on 4/4/18. */ public class BairdStewardOfArgive extends CardImpl { @@ -59,8 +57,9 @@ public class BairdStewardOfArgive extends CardImpl { //Vigilance this.addAbility(VigilanceAbility.getInstance()); - //Creatures can’t attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{1}"), true))); + // Creatures can’t attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackYouUnlessPayManaAllEffect(new ManaCostsImpl("{1}"), true) + .setText("Creatures can’t attack you or a planeswalker you control unless their controller pays {1} for each of those creatures"))); } public BairdStewardOfArgive(final BairdStewardOfArgive card) { diff --git a/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java b/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java index d2b19cdeeb5..d54aab7de15 100644 --- a/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java +++ b/Mage.Sets/src/mage/cards/b/BoardTheWeatherlight.java @@ -57,7 +57,9 @@ public class BoardTheWeatherlight extends CardImpl { new LookLibraryAndPickControllerEffect( new StaticValue(5), false, new StaticValue(1), filter, Zone.LIBRARY, false, true, false, Zone.HAND, true, false, false - ) + ).setText("Look at the top five cards of your library. You may reveal a historic card from among them" + + " and put it into your hand. Put the rest on the bottom of your library in random order. " + + "(Artifacts, legendaries, and Sagas are historic.)") ); } diff --git a/Mage.Sets/src/mage/cards/d/DaringArchaeologist.java b/Mage.Sets/src/mage/cards/d/DaringArchaeologist.java index 0cf36c1b06e..8b9d0bad7ec 100644 --- a/Mage.Sets/src/mage/cards/d/DaringArchaeologist.java +++ b/Mage.Sets/src/mage/cards/d/DaringArchaeologist.java @@ -34,10 +34,10 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.common.FilterArtifactCard; @@ -65,12 +65,16 @@ public class DaringArchaeologist extends CardImpl { this.toughness = new MageInt(3); // When Daring Archaeologist enters the battlefield, you may return target artifact card from your graveyard to your hand. - Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect() + .setText("you may return target artifact card from your graveyard to your hand. "), true); ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactCard("artifact card from your graveyard"))); this.addAbility(ability); // Whenever you cast a historic spell, put a +1/+1 counter on Daring Archaeologist. - this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), filter, true)); + this.addAbility(new SpellCastControllerTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)) + .setText("put a +1/+1 counter on {this}. (Artifacts, legendaries, and Sagas are historic.)"), + filter, true)); } public DaringArchaeologist(final DaringArchaeologist card) { diff --git a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java index ddfda7377a5..76c1ed45671 100644 --- a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java +++ b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java @@ -39,8 +39,8 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -57,7 +57,7 @@ import mage.players.Player; public class EnigmaSphinx extends CardImpl { public EnigmaSphinx(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}{W}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{W}{U}{B}"); this.subtype.add(SubType.SPHINX); this.power = new MageInt(5); @@ -66,7 +66,7 @@ public class EnigmaSphinx extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - // When Enigma Sphinx is put into your graveyard from the battlefield, put it into your library third from the top. + // When Enigma Sphinx is put into your graveyard from the battlefield, put it into your library third from the top. this.addAbility(new EnigmaSphinxTriggeredAbility(new EnigmaSphinxEffect())); // Cascade @@ -111,12 +111,12 @@ class EnigmaSphinxTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { ZoneChangeEvent zEvent = (ZoneChangeEvent) event; Permanent permanent = zEvent.getTarget(); - if (permanent != null && - zEvent.getToZone() == Zone.GRAVEYARD && - zEvent.getFromZone() == Zone.BATTLEFIELD && - permanent.getId().equals(this.getSourceId()) && - // 5/1/2009 If you control an Enigma Sphinx that's owned by another player, it's put into that player's - // graveyard from the battlefield, so Enigma Sphinx's middle ability won't trigger. + if (permanent != null + && zEvent.getToZone() == Zone.GRAVEYARD + && zEvent.getFromZone() == Zone.BATTLEFIELD + && permanent.getId().equals(this.getSourceId()) + && // 5/1/2009 If you control an Enigma Sphinx that's owned by another player, it's put into that player's + // graveyard from the battlefield, so Enigma Sphinx's middle ability won't trigger. permanent.getOwnerId().equals(permanent.getControllerId())) { return true; } @@ -152,20 +152,12 @@ class EnigmaSphinxEffect extends OneShotEffect { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null && card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true)) { // Move Sphinx to third position - game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() +"'s library third from the top"); + game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top"); Library lib = owner.getLibrary(); if (lib != null) { Card card1 = lib.removeFromTop(game); if (card1 != null && card1.getId().equals(source.getSourceId())) { - Card card2 = lib.removeFromTop(game); - Card card3 = lib.removeFromTop(game); - lib.putOnTop(card1, game); - if (card3 != null) { - lib.putOnTop(card3, game); - } - if (card2 != null) { - lib.putOnTop(card2, game); - } + lib.putCardThirdFromTheTop(card1, game); return true; } } diff --git a/Mage.Sets/src/mage/cards/k/KioraTheCrashingWave.java b/Mage.Sets/src/mage/cards/k/KioraTheCrashingWave.java index d2107302852..caf17737b3f 100644 --- a/Mage.Sets/src/mage/cards/k/KioraTheCrashingWave.java +++ b/Mage.Sets/src/mage/cards/k/KioraTheCrashingWave.java @@ -38,8 +38,8 @@ import mage.abilities.effects.common.continuous.PlayAdditionalLandsControllerEff import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.TargetController; import mage.filter.FilterPermanent; @@ -58,7 +58,7 @@ import mage.util.CardUtil; */ public class KioraTheCrashingWave extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("permanent an opponent control"); + private static final FilterPermanent filter = new FilterPermanent("permanent an opponent controls"); static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); diff --git a/Mage.Sets/src/mage/cards/l/LongTermPlans.java b/Mage.Sets/src/mage/cards/l/LongTermPlans.java index 9787c01cd51..fab9bae3c12 100644 --- a/Mage.Sets/src/mage/cards/l/LongTermPlans.java +++ b/Mage.Sets/src/mage/cards/l/LongTermPlans.java @@ -46,8 +46,7 @@ import mage.target.common.TargetCardInLibrary; public class LongTermPlans extends CardImpl { public LongTermPlans(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Search your library for a card, shuffle your library, then put that card third from the top. this.getSpellAbility().addEffect(new LongTermPlansEffect()); @@ -64,21 +63,21 @@ public class LongTermPlans extends CardImpl { } class LongTermPlansEffect extends OneShotEffect { - + LongTermPlansEffect() { super(Outcome.Benefit); this.staticText = "Search your library for a card, shuffle your library, then put that card third from the top"; } - + LongTermPlansEffect(final LongTermPlansEffect effect) { super(effect); } - + @Override public LongTermPlansEffect copy() { return new LongTermPlansEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); @@ -88,21 +87,7 @@ class LongTermPlansEffect extends OneShotEffect { Card card = player.getLibrary().remove(target.getFirstTarget(), game); if (card != null) { player.shuffleLibrary(source, game); - Card cardTop = null; - Card cardSecond = null; - if (player.getLibrary().hasCards()) { - cardTop = player.getLibrary().removeFromTop(game); - } - if (player.getLibrary().hasCards()) { - cardSecond = player.getLibrary().removeFromTop(game); - } - player.getLibrary().putOnTop(card, game); - if (cardSecond != null) { - player.getLibrary().putOnTop(cardSecond, game); - } - if (cardTop != null) { - player.getLibrary().putOnTop(cardTop, game); - } + player.getLibrary().putCardThirdFromTheTop(card, game); } } return true; diff --git a/Mage.Sets/src/mage/cards/s/SerraDisciple.java b/Mage.Sets/src/mage/cards/s/SerraDisciple.java index c17765a303c..e073a569320 100644 --- a/Mage.Sets/src/mage/cards/s/SerraDisciple.java +++ b/Mage.Sets/src/mage/cards/s/SerraDisciple.java @@ -1,9 +1,9 @@ package mage.cards.s; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FlyingAbility; @@ -14,8 +14,6 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.filter.common.FilterHistoricSpell; -import java.util.UUID; - public class SerraDisciple extends CardImpl { public SerraDisciple(UUID ownerId, CardSetInfo cardSetInfo) { @@ -30,16 +28,16 @@ public class SerraDisciple extends CardImpl { // Whenever you cast a historic spell, Serra Disciple gets +1/+1 until end of turn Ability ability = new SpellCastControllerTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), new FilterHistoricSpell(), false, - "Whenever you cast a historic spell, {this} gets +1/+1 until end of turn"); + "Whenever you cast a historic spell, {this} gets +1/+1 until end of turn. (Artifacts, legendaries, and Sagas are historic.)"); addAbility(ability); } - public SerraDisciple(final SerraDisciple serraDisciple){ + public SerraDisciple(final SerraDisciple serraDisciple) { super(serraDisciple); } - public SerraDisciple copy(){ + public SerraDisciple copy() { return new SerraDisciple(this); } } diff --git a/Mage.Sets/src/mage/cards/s/ShalaiVoiceOfPlenty.java b/Mage.Sets/src/mage/cards/s/ShalaiVoiceOfPlenty.java index 05640ef0fe1..e54d430ba91 100644 --- a/Mage.Sets/src/mage/cards/s/ShalaiVoiceOfPlenty.java +++ b/Mage.Sets/src/mage/cards/s/ShalaiVoiceOfPlenty.java @@ -37,14 +37,14 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControllerEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.HexproofAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; @@ -87,6 +87,7 @@ public class ShalaiVoiceOfPlenty extends CardImpl { ability.addEffect(effect); effect = new GainAbilityControlledEffect(HexproofAbility.getInstance(), Duration.WhileOnBattlefield, filter2); effect.setText("and other creatures you control have hexproof"); + ability.addEffect(effect); this.addAbility(ability); // {4}{G}{G}: Put a +1/+1 counter on each creature you control. diff --git a/Mage.Sets/src/mage/cards/t/TatyovaBenthicDruid.java b/Mage.Sets/src/mage/cards/t/TatyovaBenthicDruid.java index eb3a4ee5265..65ef0edcea4 100644 --- a/Mage.Sets/src/mage/cards/t/TatyovaBenthicDruid.java +++ b/Mage.Sets/src/mage/cards/t/TatyovaBenthicDruid.java @@ -38,7 +38,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.common.FilterLandPermanent; +import mage.filter.StaticFilters; /** * @@ -47,7 +47,7 @@ import mage.filter.common.FilterLandPermanent; public class TatyovaBenthicDruid extends CardImpl { public TatyovaBenthicDruid(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{U}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.MERFOLK, SubType.DRUID); @@ -56,8 +56,8 @@ public class TatyovaBenthicDruid extends CardImpl { this.toughness = new MageInt(3); // Whenever a land enters the battlefield under your control, you gain 1 life and draw a card. - Ability ability = new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), new FilterLandPermanent("a land")); - ability.addEffect(new DrawCardSourceControllerEffect(1)); + Ability ability = new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_LAND_A); + ability.addEffect(new DrawCardSourceControllerEffect(1).setText("and draw a card")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java b/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java new file mode 100644 index 00000000000..beb697571c7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java @@ -0,0 +1,132 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.UntapLandsEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.command.emblems.TeferiHeroOfDominariaEmblem; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetNonlandPermanent; + +/** + * + * @author LevelX2 + */ +public class TeferiHeroOfDominaria extends CardImpl { + + public TeferiHeroOfDominaria(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.TEFERI); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + + // +1: Draw a card. At the beginning of the next end step, untap two lands. + LoyaltyAbility ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility( + new UntapLandsEffect(2, false)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(delayedAbility)); + this.addAbility(ability); + + // −3: Put target nonland permanent into its owner's library third from the top. + ability = new LoyaltyAbility(new TeferiHeroOfDominariaSecondEffect(), -3); + ability.addTarget(new TargetNonlandPermanent()); + this.addAbility(ability); + + // −8: You get an emblem with "Whenever you draw a card, exile target permanent an opponent controls." + this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new TeferiHeroOfDominariaEmblem()), -8)); + } + + public TeferiHeroOfDominaria(final TeferiHeroOfDominaria card) { + super(card); + } + + @Override + public TeferiHeroOfDominaria copy() { + return new TeferiHeroOfDominaria(this); + } +} + +class TeferiHeroOfDominariaSecondEffect extends OneShotEffect { + + public TeferiHeroOfDominariaSecondEffect() { + super(Outcome.Benefit); + this.staticText = "Put target nonland permanent into its owner's library third from the top"; + } + + public TeferiHeroOfDominariaSecondEffect(final TeferiHeroOfDominariaSecondEffect effect) { + super(effect); + } + + @Override + public TeferiHeroOfDominariaSecondEffect copy() { + return new TeferiHeroOfDominariaSecondEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + Player owner = game.getPlayer(permanent.getOwnerId()); + if (owner == null) { + return false; + } + permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + Card card = owner.getLibrary().remove(permanent.getId(), game); + if (card != null) { + owner.getLibrary().putCardThirdFromTheTop(card, game); + game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top"); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TeferiTimebender.java b/Mage.Sets/src/mage/cards/t/TeferiTimebender.java new file mode 100644 index 00000000000..ea8b56d042b --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TeferiTimebender.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class TeferiTimebender extends CardImpl { + + public TeferiTimebender(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{W}{U}"); + + this.addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.TEFERI); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); + + // +2: Untap up to one target artifact or creature. + FilterPermanent filter = new FilterPermanent("artifact or creature"); + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE))); + LoyaltyAbility ability = new LoyaltyAbility(new UntapTargetEffect(), +2); + ability.addTarget(new TargetPermanent(0, 1, filter, false)); + this.addAbility(ability); + + // -3: You gain 2 life and draw two cards. + ability = new LoyaltyAbility(new GainLifeEffect(2), -3); + ability.addEffect(new DrawCardSourceControllerEffect(2).setText("and draw two cards")); + this.addAbility(ability); + + // -9: Take an extra turn after this one. + this.addAbility(new LoyaltyAbility(new AddExtraTurnControllerEffect(), -9)); + } + + public TeferiTimebender(final TeferiTimebender card) { + super(card); + } + + @Override + public TeferiTimebender copy() { + return new TeferiTimebender(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TeferisSentinel.java b/Mage.Sets/src/mage/cards/t/TeferisSentinel.java new file mode 100644 index 00000000000..63e69f507fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TeferisSentinel.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LevelX2 + */ +public class TeferisSentinel extends CardImpl { + + public TeferisSentinel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + + this.subtype.add(SubType.GOLEM); + this.power = new MageInt(2); + this.toughness = new MageInt(6); + + // As long as you control a Teferi planeswalker, Teferi's Sentinel gets +4/+0. + FilterControlledPermanent filter = new FilterControlledPermanent(); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.TEFERI)); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new ConditionalContinuousEffect( + new BoostSourceEffect(4, 0, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), + "As long as you control a Teferi planeswalker, {this} gets +4/+0"))); + } + + public TeferisSentinel(final TeferisSentinel card) { + super(card); + } + + @Override + public TeferisSentinel copy() { + return new TeferisSentinel(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TesharAncestorsApostle.java b/Mage.Sets/src/mage/cards/t/TesharAncestorsApostle.java index fa240d14585..513b9fc0ea4 100644 --- a/Mage.Sets/src/mage/cards/t/TesharAncestorsApostle.java +++ b/Mage.Sets/src/mage/cards/t/TesharAncestorsApostle.java @@ -59,7 +59,7 @@ public class TesharAncestorsApostle extends CardImpl { filter.add(new CardTypePredicate(CardType.CREATURE)); } - public TesharAncestorsApostle(UUID ownerId, CardSetInfo cardSetInfo){ + public TesharAncestorsApostle(UUID ownerId, CardSetInfo cardSetInfo) { super(ownerId, cardSetInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.BIRD); @@ -72,17 +72,18 @@ public class TesharAncestorsApostle extends CardImpl { // Whenever you cast a historic spell, return target creature card with converted mana cost 3 or less from your graveyard to the battlefield. Ability ability = new SpellCastControllerTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect() - .setText("return target creature card with converted mana cost 3 or less from your graveyard to the battlefield"), new FilterHistoricSpell(), false); + .setText("return target creature card with converted mana cost 3 or less from your graveyard to the battlefield. " + + "(Artifacts, legendaries, and Sagas are historic.)"), new FilterHistoricSpell("a historic spell"), false); ability.addTarget(new TargetCardInYourGraveyard(filter)); this.addAbility(ability); } - public TesharAncestorsApostle(final TesharAncestorsApostle TesharAncestorsApostle){ + public TesharAncestorsApostle(final TesharAncestorsApostle TesharAncestorsApostle) { super(TesharAncestorsApostle); } - public TesharAncestorsApostle copy(){ + public TesharAncestorsApostle copy() { return new TesharAncestorsApostle(this); } } diff --git a/Mage.Sets/src/mage/cards/t/TragicPoet.java b/Mage.Sets/src/mage/cards/t/TragicPoet.java index f497812b751..f1eae1ab786 100644 --- a/Mage.Sets/src/mage/cards/t/TragicPoet.java +++ b/Mage.Sets/src/mage/cards/t/TragicPoet.java @@ -56,14 +56,15 @@ public class TragicPoet extends CardImpl { } public TragicPoet(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(1); this.toughness = new MageInt(1); // {tap}, Sacrifice Tragic Poet: Return target enchantment card from your graveyard to your hand. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect() + .setText("Return target enchantment card from your graveyard to your hand"), new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetCardInYourGraveyard(filter)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/Dominaria.java b/Mage.Sets/src/mage/sets/Dominaria.java index 91ce620cd55..ee075ecc8dd 100644 --- a/Mage.Sets/src/mage/sets/Dominaria.java +++ b/Mage.Sets/src/mage/sets/Dominaria.java @@ -161,7 +161,7 @@ public class Dominaria extends ExpansionSet { cards.add(new SetCardInfo("Llanowar Elves", 168, Rarity.COMMON, mage.cards.l.LlanowarElves.class)); cards.add(new SetCardInfo("Llanowar Envoy", 169, Rarity.COMMON, mage.cards.l.LlanowarEnvoy.class)); cards.add(new SetCardInfo("Llanowar Scout", 170, Rarity.COMMON, mage.cards.l.LlanowarScout.class)); - cards.add(new SetCardInfo("Lyra Dawnbringer", 14, Rarity.MYTHIC, mage.cards.l.LyraDawnbringer.class)); + cards.add(new SetCardInfo("Lyra Dawnbringer", 26, Rarity.MYTHIC, mage.cards.l.LyraDawnbringer.class)); cards.add(new SetCardInfo("Mammoth Spider", 171, Rarity.COMMON, mage.cards.m.MammothSpider.class)); cards.add(new SetCardInfo("Marwyn, the Nurturer", 172, Rarity.RARE, mage.cards.m.MarwynTheNurturer.class)); cards.add(new SetCardInfo("Meandering River", 274, Rarity.COMMON, mage.cards.m.MeanderingRiver.class)); @@ -220,6 +220,9 @@ public class Dominaria extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 261, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Syncopate", 67, Rarity.UNCOMMON, mage.cards.s.Syncopate.class)); cards.add(new SetCardInfo("Tatyova, Benthic Druid", 206, Rarity.UNCOMMON, mage.cards.t.TatyovaBenthicDruid.class)); + cards.add(new SetCardInfo("Teferi's Sentinel", 273, Rarity.UNCOMMON, mage.cards.t.TeferisSentinel.class)); + cards.add(new SetCardInfo("Teferi, Hero of Dominaria", 207, Rarity.MYTHIC, mage.cards.t.TeferiHeroOfDominaria.class)); + cards.add(new SetCardInfo("Teferi, Timebender", 270, Rarity.MYTHIC, mage.cards.t.TeferiTimebender.class)); cards.add(new SetCardInfo("Tempest Djinn", 68, Rarity.RARE, mage.cards.t.TempestDjinn.class)); cards.add(new SetCardInfo("Teshar, Ancestor's Apostle", 36, Rarity.RARE, mage.cards.t.TesharAncestorsApostle.class)); cards.add(new SetCardInfo("Tetsuko Umezawa, Fugitive", 69, Rarity.UNCOMMON, mage.cards.t.TetsukoUmezawaFugitive.class)); diff --git a/Mage/src/main/java/mage/abilities/common/DrawCardControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DrawCardControllerTriggeredAbility.java index 0fdc859092f..149623280f7 100644 --- a/Mage/src/main/java/mage/abilities/common/DrawCardControllerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DrawCardControllerTriggeredAbility.java @@ -27,9 +27,9 @@ */ package mage.abilities.common; -import mage.constants.Zone; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -37,10 +37,14 @@ import mage.game.events.GameEvent; * * @author North */ -public class DrawCardControllerTriggeredAbility extends TriggeredAbilityImpl { +public class DrawCardControllerTriggeredAbility extends TriggeredAbilityImpl { public DrawCardControllerTriggeredAbility(Effect effect, boolean optional) { - super(Zone.BATTLEFIELD, effect, optional); + this(Zone.BATTLEFIELD, effect, optional); + } + + public DrawCardControllerTriggeredAbility(Zone zone, Effect effect, boolean optional) { + super(zone, effect, optional); } public DrawCardControllerTriggeredAbility(final DrawCardControllerTriggeredAbility ability) { @@ -66,4 +70,4 @@ public class DrawCardControllerTriggeredAbility extends TriggeredAbilityImpl { public DrawCardControllerTriggeredAbility copy() { return new DrawCardControllerTriggeredAbility(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/common/SagaAbility.java b/Mage/src/main/java/mage/abilities/common/SagaAbility.java index c72598114e1..37b2442f72e 100644 --- a/Mage/src/main/java/mage/abilities/common/SagaAbility.java +++ b/Mage/src/main/java/mage/abilities/common/SagaAbility.java @@ -173,7 +173,7 @@ class ChapterTriggeredAbility extends TriggeredAbilityImpl { } } String text = super.getRule(); - sb.append(": ").append(Character.toUpperCase(text.charAt(0)) + text.substring(1)); + sb.append(": ").append(Character.toUpperCase(text.charAt(0))).append(text.substring(1)); return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/BasicManaEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BasicManaEffect.java index 95e7faa8eac..5bcd549778a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/BasicManaEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/BasicManaEffect.java @@ -12,13 +12,13 @@ public class BasicManaEffect extends ManaEffect { public BasicManaEffect(Mana mana) { super(); this.mana = mana; - staticText = "add " + mana.toString() + " to your mana pool"; + staticText = "add " + mana.toString(); } public BasicManaEffect(ConditionalMana conditionalMana) { super(); this.mana = conditionalMana; - staticText = "add " + mana.toString() + " to your mana pool. " + conditionalMana.getDescription(); + staticText = "add " + mana.toString() + " " + conditionalMana.getDescription(); } public BasicManaEffect(final BasicManaEffect effect) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/UntapLandsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/UntapLandsEffect.java index 670c7219333..cadc38451bf 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/UntapLandsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/UntapLandsEffect.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; @@ -40,28 +41,35 @@ import mage.players.Player; import mage.target.common.TargetLandPermanent; /** - * "Untap up to X lands" effect + * "Untap (up to) X lands" effect */ public class UntapLandsEffect extends OneShotEffect { private final int amount; + private final boolean upTo; public UntapLandsEffect(int amount) { + this(amount, true); + } + + public UntapLandsEffect(int amount, boolean upTo) { super(Outcome.Untap); this.amount = amount; - staticText = "Untap up to " + amount + " lands"; + this.upTo = upTo; + staticText = "Untap " + (upTo ? "up to " : "") + amount + " lands"; } public UntapLandsEffect(final UntapLandsEffect effect) { super(effect); this.amount = effect.amount; + this.upTo = effect.upTo; } @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - TargetLandPermanent target = new TargetLandPermanent(0, amount, new FilterLandPermanent(), true); + TargetLandPermanent target = new TargetLandPermanent(upTo ? 0 : amount, amount, StaticFilters.FILTER_LAND, true); if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { // UI Shortcut: Check if any lands are already tapped. If there are equal/fewer than amount, give the option to add those in to be untapped now. diff --git a/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlackAbility.java b/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlackAbility.java index 80090d6d96b..39ed14932ea 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlackAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HexproofFromBlackAbility.java @@ -1,14 +1,13 @@ package mage.abilities.keyword; +import java.io.ObjectStreamException; import mage.abilities.MageSingleton; import mage.abilities.common.SimpleStaticAbility; import mage.constants.Zone; -import java.io.ObjectStreamException; - /** - * Hexproof from black (This creature or player can't be the target of black spells or abilities - * your opponents control.) + * Hexproof from black (This creature or player can't be the target of black + * spells or abilities your opponents control.) * * @author igoudt */ @@ -39,6 +38,6 @@ public class HexproofFromBlackAbility extends SimpleStaticAbility implements Mag @Override public String getRule() { - return "hexproof from black"; + return "hexproof from black (This creature can't be the target of black spells or abilities your opponents control.)"; } } diff --git a/Mage/src/main/java/mage/abilities/keyword/HexproofFromWhiteAbility.java b/Mage/src/main/java/mage/abilities/keyword/HexproofFromWhiteAbility.java index c7a0b6db8f1..fb535e1c50c 100644 --- a/Mage/src/main/java/mage/abilities/keyword/HexproofFromWhiteAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/HexproofFromWhiteAbility.java @@ -1,14 +1,13 @@ package mage.abilities.keyword; +import java.io.ObjectStreamException; import mage.abilities.MageSingleton; import mage.abilities.common.SimpleStaticAbility; import mage.constants.Zone; -import java.io.ObjectStreamException; - /** - * Hexproof from white (This creature or player can't be the target of white spells or abilities - * your opponents control.) + * Hexproof from white (This creature or player can't be the target of white + * spells or abilities your opponents control.) * * @author igoudt */ @@ -39,6 +38,6 @@ public class HexproofFromWhiteAbility extends SimpleStaticAbility implements Mag @Override public String getRule() { - return "hexproof from white"; + return "hexproof from white (This creature can't be the target of white spells or abilities your opponents control.)"; } } diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index e17b6cfeb9e..0632253e136 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -225,6 +225,12 @@ public final class StaticFilters { FILTER_LAND.setLockedFilter(true); } + public static final FilterLandPermanent FILTER_LAND_A = new FilterLandPermanent("a land"); + + static { + FILTER_LAND_A.setLockedFilter(true); + } + public static final FilterLandPermanent FILTER_LANDS = new FilterLandPermanent("lands"); static { diff --git a/Mage/src/main/java/mage/game/ZoneChangeInfo.java b/Mage/src/main/java/mage/game/ZoneChangeInfo.java index bfbee3a7222..fa5ab517776 100644 --- a/Mage/src/main/java/mage/game/ZoneChangeInfo.java +++ b/Mage/src/main/java/mage/game/ZoneChangeInfo.java @@ -1,17 +1,17 @@ package mage.game; -import mage.cards.MeldCard; -import mage.game.events.ZoneChangeEvent; -import mage.game.stack.Spell; - import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.cards.MeldCard; +import mage.game.events.ZoneChangeEvent; +import mage.game.stack.Spell; /** * Created by Dilnu on 9/4/16. */ public class ZoneChangeInfo { + public boolean faceDown; public ZoneChangeEvent event; @@ -35,6 +35,7 @@ public class ZoneChangeInfo { } public static class Library extends ZoneChangeInfo { + public boolean top; public Library(ZoneChangeEvent event, boolean top) { @@ -47,7 +48,7 @@ public class ZoneChangeInfo { this.top = top; } - public Library(Library info) { + public Library(final Library info) { super(info); this.top = info.top; } @@ -59,6 +60,7 @@ public class ZoneChangeInfo { } public static class Exile extends ZoneChangeInfo { + public UUID id; public String name; @@ -74,7 +76,7 @@ public class ZoneChangeInfo { this.name = name; } - public Exile(Exile info) { + public Exile(final Exile info) { super(info); this.id = info.id; this.name = info.name; @@ -87,19 +89,20 @@ public class ZoneChangeInfo { } public static class Battlefield extends ZoneChangeInfo { + public boolean tapped; - public Battlefield (ZoneChangeEvent event, boolean tapped) { + public Battlefield(ZoneChangeEvent event, boolean tapped) { super(event); this.tapped = tapped; } - public Battlefield (ZoneChangeEvent event, boolean faceDown, boolean tapped) { + public Battlefield(ZoneChangeEvent event, boolean faceDown, boolean tapped) { super(event, faceDown); this.tapped = tapped; } - public Battlefield(Battlefield info) { + public Battlefield(final Battlefield info) { super(info); this.tapped = info.tapped; } @@ -111,6 +114,7 @@ public class ZoneChangeInfo { } public static class Stack extends ZoneChangeInfo { + public Spell spell; public Stack(ZoneChangeEvent event, Spell spell) { @@ -123,7 +127,7 @@ public class ZoneChangeInfo { this.spell = spell; } - public Stack(Stack info) { + public Stack(final Stack info) { super(info); this.spell = info.spell; } @@ -135,7 +139,9 @@ public class ZoneChangeInfo { } public static class Unmelded extends ZoneChangeInfo { + List subInfo = new ArrayList<>(); + public Unmelded(ZoneChangeInfo info, Game game) { super(info.event); MeldCard meld = game.getMeldCard(info.event.getTargetId()); diff --git a/Mage/src/main/java/mage/game/ZonesHandler.java b/Mage/src/main/java/mage/game/ZonesHandler.java index 644ed9aa440..9a145c862dc 100644 --- a/Mage/src/main/java/mage/game/ZonesHandler.java +++ b/Mage/src/main/java/mage/game/ZonesHandler.java @@ -108,7 +108,7 @@ public final class ZonesHandler { "order to put on top of library (last chosen will be topmost)", cards, owner, game)) { game.getPlayer(card.getOwnerId()).getLibrary().putOnTop(card, game); } - } else { + } else { // buttom for (Card card : chooseOrder( "order to put on bottom of library (last chosen will be bottommost)", cards, owner, game)) { game.getPlayer(card.getOwnerId()).getLibrary().putOnBottom(card, game); diff --git a/Mage/src/main/java/mage/game/command/emblems/TeferiHeroOfDominariaEmblem.java b/Mage/src/main/java/mage/game/command/emblems/TeferiHeroOfDominariaEmblem.java new file mode 100644 index 00000000000..7c9447c049d --- /dev/null +++ b/Mage/src/main/java/mage/game/command/emblems/TeferiHeroOfDominariaEmblem.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.game.command.emblems; + +import mage.abilities.Ability; +import mage.abilities.common.DrawCardControllerTriggeredAbility; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.command.Emblem; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class TeferiHeroOfDominariaEmblem extends Emblem { + + // Whenever you draw a card, exile target permanent an opponent controls. + public TeferiHeroOfDominariaEmblem() { + this.setName("Emblem Teferi"); + Ability ability = new DrawCardControllerTriggeredAbility(Zone.COMMAND, new ExileTargetEffect(), false); + FilterPermanent filter = new FilterPermanent("permanent an opponent controls"); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + ability.addTarget(new TargetPermanent(filter)); + this.getAbilities().add(ability); + } + +} diff --git a/Mage/src/main/java/mage/players/Library.java b/Mage/src/main/java/mage/players/Library.java index 1b507192a45..61c4734a68f 100644 --- a/Mage/src/main/java/mage/players/Library.java +++ b/Mage/src/main/java/mage/players/Library.java @@ -27,16 +27,15 @@ */ package mage.players; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; import mage.cards.Card; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; import mage.util.RandomUtil; -import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; - /** * @author BetaSteward_at_googlemail.com */ @@ -136,6 +135,28 @@ public class Library implements Serializable { } } + public void putCardThirdFromTheTop(Card card, Game game) { + if (card != null && card.getOwnerId().equals(playerId)) { + Card cardTop = null; + Card cardSecond = null; + if (hasCards()) { + cardTop = removeFromTop(game); + } + if (hasCards()) { + cardSecond = removeFromTop(game); + } + putOnTop(card, game); + if (cardSecond != null) { + putOnTop(cardSecond, game); + } + if (cardTop != null) { + putOnTop(cardTop, game); + } + } else { + game.getPlayer(card.getOwnerId()).getLibrary().putCardThirdFromTheTop(card, game); + } + } + public void putOnBottom(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { card.setZone(Zone.LIBRARY, game);