diff --git a/Mage.Client/src/main/java/mage/client/cards/BigCard.java b/Mage.Client/src/main/java/mage/client/cards/BigCard.java index 6265dc288a9..75fa5508789 100644 --- a/Mage.Client/src/main/java/mage/client/cards/BigCard.java +++ b/Mage.Client/src/main/java/mage/client/cards/BigCard.java @@ -161,6 +161,7 @@ public class BigCard extends JComponent { } public void addJXPanel(UUID cardId, JXPanel jxPanel) { + this.cardId = cardId; bigImage = null; synchronized (this) { if (this.panel != null) { remove(this.panel); } diff --git a/Mage.Common/src/mage/utils/MageVersion.java b/Mage.Common/src/mage/utils/MageVersion.java index 5e79ba1e3ed..bc712e76d26 100644 --- a/Mage.Common/src/mage/utils/MageVersion.java +++ b/Mage.Common/src/mage/utils/MageVersion.java @@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable { public final static int MAGE_VERSION_MAJOR = 1; public final static int MAGE_VERSION_MINOR = 4; public final static int MAGE_VERSION_PATCH = 4; - public final static String MAGE_VERSION_MINOR_PATCH = "v8"; + public final static String MAGE_VERSION_MINOR_PATCH = "v9"; public final static String MAGE_VERSION_INFO = ""; private final int major; diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ShardsOfAlaraBlock.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ShardsOfAlaraBlock.java index 44fc5e3e6b3..c8915b5a8b1 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ShardsOfAlaraBlock.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/ShardsOfAlaraBlock.java @@ -37,7 +37,7 @@ import mage.cards.decks.Constructed; public class ShardsOfAlaraBlock extends Constructed { public ShardsOfAlaraBlock() { - super("Constructed - Shards Of Alara Block"); + super("Constructed - Shards of Alara Block"); setCodes.add("ALA"); setCodes.add("CON"); setCodes.add("ARB"); diff --git a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java index 16bc181405a..af33a411bba 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java +++ b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java @@ -41,7 +41,6 @@ import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.common.FilterArtifactCard; import mage.filter.predicate.mageobject.AnotherCardPredicate; -import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -62,7 +61,8 @@ public class ArsenalThresher extends CardImpl { this.toughness = new MageInt(2); // As Arsenal Thresher enters the battlefield, you may reveal any number of other artifact cards from your hand. Arsenal Thresher enters the battlefield with a +1/+1 counter on it for each card revealed this way. - this.addAbility(new AsEntersBattlefieldAbility(new ArsenalThresherEffect(), "you may reveal any number of other artifact cards from your hand. {this} enters the battlefield with a +1/+1 counter on it for each card revealed this way")); + this.addAbility(new AsEntersBattlefieldAbility(new ArsenalThresherEffect(), + "you may reveal any number of other artifact cards from your hand. {this} enters the battlefield with a +1/+1 counter on it for each card revealed this way")); } public ArsenalThresher(final ArsenalThresher card) { @@ -92,29 +92,29 @@ class ArsenalThresherEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player you = game.getPlayer(source.getControllerId()); - if (you == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - Permanent arsenalThresher = game.getPermanent(source.getSourceId()); + Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId()); FilterArtifactCard filter = new FilterArtifactCard(); filter.add(new AnotherCardPredicate()); - if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", source, game)) { + if (controller.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", source, game)) { Cards cards = new CardsImpl(); - if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); - if (you.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { for (UUID uuid : target.getTargets()) { - cards.add(you.getHand().get(uuid, game)); + cards.add(controller.getHand().get(uuid, game)); } - you.revealCards("Revealed cards", cards, game); if (arsenalThresher != null) { + controller.revealCards(arsenalThresher.getIdName(), cards, game); arsenalThresher.addCounters(CounterType.P1P1.createInstance(cards.size()), game); - return true; } } } + return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/alarareborn/Wargate.java b/Mage.Sets/src/mage/sets/alarareborn/Wargate.java index db3728446e6..38654b08777 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/Wargate.java +++ b/Mage.Sets/src/mage/sets/alarareborn/Wargate.java @@ -28,14 +28,13 @@ package mage.sets.alarareborn; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.common.FilterPermanentCard; @@ -54,10 +53,6 @@ public class Wargate extends CardImpl { super(ownerId, 129, "Wargate", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}{W}{U}"); this.expansionSetCode = "ARB"; - - - - // Search your library for a permanent card with converted mana cost X or less, put it onto the battlefield, then shuffle your library. this.getSpellAbility().addEffect(new WargateEffect()); } @@ -72,8 +67,8 @@ public class Wargate extends CardImpl { } } - class WargateEffect extends OneShotEffect { + WargateEffect() { super(Outcome.PutCreatureInPlay); staticText = "Search your library for a permanent card with converted mana cost X or less, put it onto the battlefield, then shuffle your library"; @@ -97,7 +92,7 @@ class WargateEffect extends OneShotEffect { if (target.getTargets().size() > 0) { Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/alliances/JuniperOrderAdvocate.java b/Mage.Sets/src/mage/sets/alliances/JuniperOrderAdvocate.java new file mode 100644 index 00000000000..6faff763326 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alliances/JuniperOrderAdvocate.java @@ -0,0 +1,84 @@ +/* + * 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.sets.alliances; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.SourceTappedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LoneFox + */ +public class JuniperOrderAdvocate extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("green creatures you control"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public JuniperOrderAdvocate(UUID ownerId) { + super(ownerId, 132, "Juniper Order Advocate", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "ALL"; + this.subtype.add("Human"); + this.subtype.add("Knight"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // As long as Juniper Order Advocate is untapped, green creatures you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, false), + new InvertCondition(new SourceTappedCondition()), + "As long as {this} is untapped, green creatures you control get +1/+1."))); + } + + public JuniperOrderAdvocate(final JuniperOrderAdvocate card) { + super(card); + } + + @Override + public JuniperOrderAdvocate copy() { + return new JuniperOrderAdvocate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/antiquities/TransmuteArtifact.java b/Mage.Sets/src/mage/sets/antiquities/TransmuteArtifact.java index d0b6d85fde4..7a12056f9a8 100644 --- a/Mage.Sets/src/mage/sets/antiquities/TransmuteArtifact.java +++ b/Mage.Sets/src/mage/sets/antiquities/TransmuteArtifact.java @@ -27,7 +27,6 @@ */ package mage.sets.antiquities; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.mana.GenericManaCost; @@ -43,7 +42,6 @@ import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; @@ -57,7 +55,6 @@ public class TransmuteArtifact extends CardImpl { super(ownerId, 58, "Transmute Artifact", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{U}{U}"); this.expansionSetCode = "ATQ"; - // Sacrifice an artifact. If you do, search your library for an artifact card. If that card's converted mana cost is less than or equal to the sacrificed artifact's converted mana cost, put it onto the battlefield. If it's greater, you may pay {X}, where X is the difference. If you do, put it onto the battlefield. If you don't, put it into its owner's graveyard. Then shuffle your library. this.getSpellAbility().addEffect(new TransmuteArtifactEffect()); } @@ -74,7 +71,6 @@ public class TransmuteArtifact extends CardImpl { class TransmuteArtifactEffect extends SearchEffect { - public TransmuteArtifactEffect() { super(new TargetCardInLibrary(new FilterArtifactCard()), Outcome.PutCardInPlay); staticText = "Sacrifice an artifact. If you do, search your library for an artifact card. If that card's converted mana cost is less than or equal to the sacrificed artifact's converted mana cost, put it onto the battlefield. If it's greater, you may pay {X}, where X is the difference. If you do, put it onto the battlefield. If you don't, put it into its owner's graveyard. Then shuffle your library"; @@ -95,41 +91,36 @@ class TransmuteArtifactEffect extends SearchEffect { if (controller == null) { return false; } - //Sacrifice an artifact. + //Sacrifice an artifact. int convertedManaCost = 0; boolean sacrifice = false; TargetControlledPermanent targetArtifact = new TargetControlledPermanent(new FilterControlledArtifactPermanent()); - if(controller.chooseTarget(Outcome.Sacrifice, targetArtifact, source, game)){ + if (controller.chooseTarget(Outcome.Sacrifice, targetArtifact, source, game)) { Permanent permanent = game.getPermanent(targetArtifact.getFirstTarget()); - if(permanent != null){ + if (permanent != null) { convertedManaCost = permanent.getManaCost().convertedManaCost(); sacrifice = permanent.sacrifice(source.getSourceId(), game); } - } - else - { + } else { return true; } - //If you do, search your library for an artifact card. + //If you do, search your library for an artifact card. if (sacrifice && controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - for (UUID cardId: target.getTargets()) { + for (UUID cardId : target.getTargets()) { Card card = controller.getLibrary().getCard(cardId, game); if (card != null) { - //If that card's converted mana cost is less than or equal to the sacrificed artifact's converted mana cost, put it onto the battlefield. - if(card.getManaCost().convertedManaCost() <= convertedManaCost){ - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } - else - { - //If it's greater, you may pay {X}, where X is the difference. If you do, put it onto the battlefield. + //If that card's converted mana cost is less than or equal to the sacrificed artifact's converted mana cost, put it onto the battlefield. + if (card.getManaCost().convertedManaCost() <= convertedManaCost) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } else { + //If it's greater, you may pay {X}, where X is the difference. If you do, put it onto the battlefield. GenericManaCost cost = new GenericManaCost(card.getManaCost().convertedManaCost() - convertedManaCost); - if(cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)){ - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } - else{ + if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } else { //If you don't, put it into its owner's graveyard. Then shuffle your library - controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } } } @@ -142,5 +133,4 @@ class TransmuteArtifactEffect extends SearchEffect { return false; } - } diff --git a/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java index 0452fbb018e..a746e9877c9 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java @@ -68,14 +68,14 @@ public class Anavolver extends CardImpl { // If Anavolver was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying. EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{U}"), true, "If {this} was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying.", + new KickedCostCondition("{1}{U}"), "If {this} was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying.", "{this} enters the battlefield with two +1/+1 counters on it and with flying"); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Anavolver was kicked with its {B} kicker, it enters the battlefield with a +1/+1 counter on it and with "Pay 3 life: Regenerate Anavolver." EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{B}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{B}"), "If {this} was kicked with its {B} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Pay 3 life: Regenerate Anavolver.\"", "{this} enters the battlefield with a +1/+1 counter on it and with \"Pay 3 life: Regenerate Anavolver.\""); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new PayLifeCost(3)), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java index 8a040de3b0d..16029793e73 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java @@ -65,14 +65,14 @@ public class Cetavolver extends CardImpl { // If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike. EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{R}"), true, "If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike.", + new KickedCostCondition("{1}{R}"), "If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike.", "{this} enters the battlefield with two +1/+1 counters on it and with first strike"); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Cetavolver was kicked with its {G} kicker, it enters the battlefield with a +1/+1 counter on it and with trample. EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{G}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{G}"), "If Cetavolver was kicked with its {G} kicker, it enters the battlefield with a +1/+1 counter on it and with trample.", "{this} enters the battlefield with a +1/+1 counter on it and with trample"); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java index 87577042db5..c0b557454ac 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java @@ -69,14 +69,14 @@ public class Degavolver extends CardImpl { // If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with "Pay 3 life: Regenerate Degavolver." EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{B}"), true, "If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\"", + new KickedCostCondition("{1}{B}"), "If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\"", "{this} enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\""); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new PayLifeCost(3)), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Degavolver was kicked with its {R} kicker, it enters the battlefield with a +1/+1 counter on it and with first strike. EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{R}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{R}"), "If Degavolver was kicked with its {R} kicker, it enters the battlefield with a +1/+1 counter on it and with first strike.", "{this} enters the battlefield with a +1/+1 counter on it and with first strike"); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/LifeDeath.java b/Mage.Sets/src/mage/sets/apocalypse/LifeDeath.java index 1db52a16d06..0cdede7a804 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/LifeDeath.java +++ b/Mage.Sets/src/mage/sets/apocalypse/LifeDeath.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.sets.apocalypse; import java.util.UUID; @@ -34,11 +33,11 @@ import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BecomesCreatureAllEffect; import mage.cards.Card; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.cards.SplitCard; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterCreatureCard; @@ -52,7 +51,6 @@ import mage.target.common.TargetCardInYourGraveyard; * * @author LevelX2 */ - public class LifeDeath extends SplitCard { public LifeDeath(UUID ownerId) { @@ -61,8 +59,8 @@ public class LifeDeath extends SplitCard { // Life // All lands you control become 1/1 creatures until end of turn. They're still lands. - getLeftHalfCard().getSpellAbility().addEffect(new BecomesCreatureAllEffect(new LifeLandToken(), "lands", - new FilterControlledLandPermanent("lands you control"), Duration.EndOfTurn)); + getLeftHalfCard().getSpellAbility().addEffect(new BecomesCreatureAllEffect(new LifeLandToken(), "lands", + new FilterControlledLandPermanent("lands you control"), Duration.EndOfTurn)); // Death // Return target creature card from your graveyard to the battlefield. You lose life equal to its converted mana cost. @@ -83,6 +81,7 @@ public class LifeDeath extends SplitCard { } class LifeLandToken extends Token { + public LifeLandToken() { super("", "1/1 creatures"); cardType.add(CardType.CREATURE); @@ -115,10 +114,10 @@ class DeathEffect extends OneShotEffect { if (creatureCard != null && controller != null) { boolean result = false; if (game.getState().getZone(creatureCard.getId()).equals(Zone.GRAVEYARD)) { - result = controller.putOntoBattlefieldWithInfo(creatureCard, game, Zone.GRAVEYARD, source.getSourceId()); - } + controller.moveCards(creatureCard, Zone.BATTLEFIELD, source, game); + } controller.loseLife(creatureCard.getManaCost().convertedManaCost(), game); - return result; + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java b/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java index 03427cbaf88..1a37ec37553 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java @@ -64,12 +64,12 @@ public class Necravolver extends CardImpl { this.addAbility(kickerAbility); // If Necravolver was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new KickedCostCondition("{1}{G}"), true, "If {this} was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample.", ""); + new KickedCostCondition("{1}{G}"), "If {this} was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample.", ""); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); // If Necravolver was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with "Whenever Necravolver deals damage, you gain that much life." ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - new KickedCostCondition("{W}"), true, "If {this} was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); + new KickedCostCondition("{W}"), "If {this} was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); ability.addEffect(new GainAbilitySourceEffect(new DealsDamageGainLifeSourceTriggeredAbility(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java index 62444bed93b..e020d9fd2ff 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java @@ -64,12 +64,12 @@ public class Rakavolver extends CardImpl { this.addAbility(kickerAbility); // If Rakavolver was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with "Whenever Rakavolver deals damage, you gain that much life." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new KickedCostCondition("{1}{W}"), true, "If {this} was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); + new KickedCostCondition("{1}{W}"), "If {this} was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); ability.addEffect(new GainAbilitySourceEffect(new DealsDamageGainLifeSourceTriggeredAbility(), Duration.WhileOnBattlefield)); this.addAbility(ability); // If Rakavolver was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying. ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - new KickedCostCondition("{U}"), true, "If {this} was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying.", ""); + new KickedCostCondition("{U}"), "If {this} was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/archenemy/MakeshiftMannequin.java b/Mage.Sets/src/mage/sets/archenemy/MakeshiftMannequin.java index e6f6c9a72df..cf248de7b5d 100644 --- a/Mage.Sets/src/mage/sets/archenemy/MakeshiftMannequin.java +++ b/Mage.Sets/src/mage/sets/archenemy/MakeshiftMannequin.java @@ -44,6 +44,7 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; import mage.counters.CounterType; +import mage.counters.Counters; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; @@ -77,21 +78,21 @@ public class MakeshiftMannequin extends CardImpl { } class MakeshiftMannequinEffect extends OneShotEffect { - + MakeshiftMannequinEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Return target creature card from your graveyard to the battlefield with a mannequin counter on it. For as long as that creature has a mannequin counter on it, it has \"When this creature becomes the target of a spell or ability, sacrifice it.\""; } - + MakeshiftMannequinEffect(final MakeshiftMannequinEffect effect) { super(effect); } - + @Override public MakeshiftMannequinEffect copy() { return new MakeshiftMannequinEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -99,12 +100,14 @@ class MakeshiftMannequinEffect extends OneShotEffect { UUID cardId = this.getTargetPointer().getFirst(game, source); Card card = controller.getGraveyard().get(cardId, game); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { + Counters counters = new Counters(); + counters.addCounter(CounterType.MANNEQUIN.createInstance()); + game.setEnterWithCounters(cardId, counters); + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(cardId); if (permanent != null) { - permanent.addCounters(CounterType.MANNEQUIN.createInstance(), game); ContinuousEffect gainedEffect = new MakeshiftMannequinGainAbilityEffect(); - gainedEffect.setTargetPointer(new FixedTarget(cardId)); + gainedEffect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(gainedEffect, source); } } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java index 00e88453cb5..5ff7b12ef69 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java @@ -38,15 +38,12 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.abilities.mana.ConditionalAnyColorManaAbility; import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.abilities.mana.conditional.CreatureCastManaCondition; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -55,10 +52,8 @@ import mage.constants.WatcherScope; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.players.Player; -import mage.util.CardUtil; import mage.watchers.Watcher; /** @@ -67,14 +62,12 @@ import mage.watchers.Watcher; */ public class CavernOfSouls extends CardImpl { - private static final String ruleText = "choose a creature type"; - public CavernOfSouls(UUID ownerId) { super(ownerId, 226, "Cavern of Souls", Rarity.RARE, new CardType[]{CardType.LAND}, ""); this.expansionSetCode = "AVR"; // As Cavern of Souls enters the battlefield, choose a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new CavernOfSoulsEffect(), ruleText)); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature))); // {T}: Add {1} to your mana pool. this.addAbility(new ColorlessManaAbility()); @@ -82,7 +75,7 @@ public class CavernOfSouls extends CardImpl { // {T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered. Ability ability = new ConditionalAnyColorManaAbility(new TapSourceCost(), 1, new CavernOfSoulsManaBuilder(), true); this.addAbility(ability, new CavernOfSoulsWatcher(ability.getOriginalId())); - this.addAbility(new SimpleStaticAbility(Zone.ALL, new CavernOfSoulsCantCounterEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CavernOfSoulsCantCounterEffect())); } public CavernOfSouls(final CavernOfSouls card) { @@ -95,60 +88,23 @@ public class CavernOfSouls extends CardImpl { } } -class CavernOfSoulsEffect extends OneShotEffect { - - public CavernOfSoulsEffect() { - super(Outcome.Benefit); - staticText = "As {this} enters the battlefield, choose a creature type"; - } - - public CavernOfSoulsEffect(final CavernOfSoulsEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.Benefit, typeChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); - } - return false; - } - - @Override - public CavernOfSoulsEffect copy() { - return new CavernOfSoulsEffect(this); - } -} - class CavernOfSoulsManaBuilder extends ConditionalManaBuilder { String creatureType; - + @Override public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) { Object value = game.getState().getValue(source.getSourceId() + "_type"); if (value != null && value instanceof String) { creatureType = (String) value; - } + } Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { - game.informPlayers(controller.getLogName() + " produces " + mana.toString() + " with " + sourceObject.getLogName() + - " (can only be spend to cast for creatures of type " + creatureType + " and that spell can't be countered)"); - } - return super.setMana(mana, source, game); + game.informPlayers(controller.getLogName() + " produces " + mana.toString() + " with " + sourceObject.getLogName() + + " (can only be spend to cast for creatures of type " + creatureType + " and that spell can't be countered)"); + } + return super.setMana(mana, source, game); } @Override @@ -174,11 +130,11 @@ class CavernOfSoulsConditionalMana extends ConditionalMana { class CavernOfSoulsManaCondition extends CreatureCastManaCondition { String creatureType; - + CavernOfSoulsManaCondition(String creatureType) { this.creatureType = creatureType; } - + @Override public boolean apply(Game game, Ability source, UUID manaProducer) { // check: ... to cast a creature spell @@ -197,7 +153,7 @@ class CavernOfSoulsWatcher extends Watcher { private List spells = new ArrayList<>(); private final String originalId; - + public CavernOfSoulsWatcher(UUID originalId) { super("ManaPaidFromCavernOfSoulsWatcher", WatcherScope.CARD); this.originalId = originalId.toString(); @@ -222,7 +178,7 @@ class CavernOfSoulsWatcher extends Watcher { } } } - + public boolean spellCantBeCountered(UUID spellId) { return spells.contains(spellId); } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/RestorationAngel.java b/Mage.Sets/src/mage/sets/avacynrestored/RestorationAngel.java index bd3043c6e72..65582db1bf7 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/RestorationAngel.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/RestorationAngel.java @@ -51,7 +51,7 @@ import mage.target.common.TargetControlledCreaturePermanent; /** * * @author noxx - + * */ public class RestorationAngel extends CardImpl { @@ -71,7 +71,7 @@ public class RestorationAngel extends CardImpl { this.addAbility(FlashAbility.getInstance()); this.addAbility(FlyingAbility.getInstance()); - + // When Restoration Angel enters the battlefield, you may exile target non-Angel creature you control, then return that card to the battlefield under your control Ability ability = new EntersBattlefieldTriggeredAbility(new RestorationAngelEffect(), true); ability.addTarget(new TargetControlledCreaturePermanent(1, 1, filter, false)); @@ -111,11 +111,13 @@ class RestorationAngelEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); if (permanent != null && sourcePermanent != null) { - controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); - Card card = game.getCard(targetPointer.getFirst(game, source)); - if (card != null) { - Zone currentZone = game.getState().getZone(card.getId()); - return controller.putOntoBattlefieldWithInfo(card, game, currentZone, source.getSourceId()); + int zcc = permanent.getZoneChangeCounter(game); + controller.moveCards(permanent, Zone.EXILED, source, game); + Card card = game.getCard(permanent.getId()); + if (card != null + && card.getZoneChangeCounter(game) == zcc + 1 + && game.getState().getZone(card.getId()).equals(Zone.EXILED)) { + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java b/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java index 8a0ead3bfc9..2f687150aa7 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/RidersOfGavony.java @@ -27,27 +27,28 @@ */ package mage.sets.avacynrestored; -import mage.constants.*; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; - -import java.util.UUID; /** * @author noxx @@ -66,7 +67,7 @@ public class RidersOfGavony extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // As Riders of Gavony enters the battlefield, choose a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new RidersOfGavonyEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Protect))); // Human creatures you control have protection from creatures of the chosen type. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RidersOfGavonyGainAbilityControlledEffect())); @@ -82,46 +83,6 @@ public class RidersOfGavony extends CardImpl { } } -class RidersOfGavonyEffect extends OneShotEffect { - - public RidersOfGavonyEffect() { - super(Outcome.BoostCreature); - staticText = "choose a creature type"; - } - - public RidersOfGavonyEffect(final RidersOfGavonyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - if (typeChoice.getChoice() != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice() + "", game); - } - } - return false; - } - - @Override - public RidersOfGavonyEffect copy() { - return new RidersOfGavonyEffect(this); - } - -} - class RidersOfGavonyGainAbilityControlledEffect extends ContinuousEffectImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Human creatures you control"); @@ -154,13 +115,13 @@ class RidersOfGavonyGainAbilityControlledEffect extends ContinuousEffectImpl { if (permanent != null) { String subtype = (String) game.getState().getValue(permanent.getId() + "_type"); if (subtype != null) { - protectionFilter = new FilterPermanent(subtype+"s"); + protectionFilter = new FilterPermanent(subtype + "s"); protectionFilter.add(new SubtypePredicate(subtype)); } } } if (protectionFilter != null) { - for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { perm.addAbility(new ProtectionAbility(protectionFilter), source.getSourceId(), game); } return true; diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java b/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java index 9e716508d32..19905589e8d 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java @@ -30,19 +30,18 @@ package mage.sets.avacynrestored; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect.HandSizeModification; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -50,7 +49,6 @@ import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TappedPredicate; @@ -71,8 +69,7 @@ public class TamiyoTheMoonSage extends CardImpl { this.expansionSetCode = "AVR"; this.subtype.add("Tamiyo"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Tap target permanent. It doesn't untap during its controller's next untap step. LoyaltyAbility ability = new LoyaltyAbility(new TapTargetEffect(), 1); @@ -130,7 +127,8 @@ class TappedCreaturesControlledByTargetCount implements DynamicValue { } /** - * Emblem with "You have no maximum hand size" and "Whenever a card is put into your graveyard from anywhere, you may return it to your hand." + * Emblem with "You have no maximum hand size" and "Whenever a card is put into + * your graveyard from anywhere, you may return it to your hand." */ class TamiyoTheMoonSageEmblem extends Emblem { diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java b/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java index b899d7e651a..b17f824dd78 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java @@ -29,29 +29,27 @@ package mage.sets.avacynrestored; import java.util.List; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -70,8 +68,7 @@ public class TibaltTheFiendBlooded extends CardImpl { this.expansionSetCode = "AVR"; this.subtype.add("Tibalt"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); // +1: Draw a card, then discard a card at random. LoyaltyAbility ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java index 9da9eacd178..07c4d334a5e 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; @@ -39,14 +39,12 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.command.Emblem; import mage.game.permanent.token.Token; @@ -61,7 +59,7 @@ public class GideonAllyOfZendikar extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Gideon"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. LoyaltyAbility ability = new LoyaltyAbility(new BecomesCreatureSourceEffect(new GideonAllyOfZendikarToken(), "planeswalker", Duration.EndOfTurn), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java index 557c17be929..ead4e657e67 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java @@ -32,13 +32,12 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterLandCard; @@ -73,7 +71,7 @@ public class KioraMasterOfTheDepths extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Kiora"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Untap up to one target creature and up to one target land. LoyaltyAbility ability1 = new LoyaltyAbility(new KioraUntapEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java index 419aaba047a..242438d7fdd 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java @@ -30,18 +30,16 @@ package mage.sets.battleforzendikar; import java.util.UUID; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -60,7 +58,7 @@ public class ObNixilisReignited extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Nixilis"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: You draw a card and you lose 1 life. Effect effect = new DrawCardSourceControllerEffect(1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java b/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java index b3f7679d293..a997e01fd4b 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java @@ -60,8 +60,8 @@ public class OranRiefHydra extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - - // Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. + + // Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. // If that land is a Forest, put two +1/+1 counters on Oran-Rief Hydra instead. this.addAbility(new OranRiefHydraTriggeredAbility()); } @@ -77,9 +77,9 @@ public class OranRiefHydra extends CardImpl { } class OranRiefHydraTriggeredAbility extends TriggeredAbilityImpl { - - private static final String text = "Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. " - + "If that land is a Forest, put two +1/+1 counters on Oran-Rief Hydra instead."; + + private static final String text = "Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on {this}. " + + "If that land is a Forest, put two +1/+1 counters on {this} instead."; public OranRiefHydraTriggeredAbility() { super(Zone.BATTLEFIELD, new OranRiefHydraEffect()); @@ -106,12 +106,13 @@ class OranRiefHydraTriggeredAbility extends TriggeredAbilityImpl { && permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(getControllerId())) { Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null) + if (sourcePermanent != null) { for (Effect effect : getEffects()) { - if (effect instanceof OranRiefHydraEffect) { - effect.setTargetPointer(new FixedTarget(permanent, game)); + if (effect instanceof OranRiefHydraEffect) { + effect.setTargetPointer(new FixedTarget(permanent, game)); + } + return true; } - return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java b/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java index f1594a72cf4..c86c1acfc31 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java @@ -57,7 +57,7 @@ public class PrismArray extends CardImpl { // Converge - Prism Array enters the battlefield with a crystal counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.CRYSTAL.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); // Remove a crystal counter from Prism Array: Tap target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java b/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java index e08242cc827..d02eccfbc59 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java @@ -59,7 +59,7 @@ public class SkyriderElf extends CardImpl { // Converge-Skyrider Elf enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java b/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java index 15981c7815d..73947b4132e 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java @@ -55,7 +55,7 @@ public class TajuruStalwart extends CardImpl { // Converge - Tajuru Stalwart enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge - {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge - {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java b/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java index c879bbeb29e..bcf90209c59 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java @@ -64,7 +64,7 @@ public class UlamogsDespoiler extends CardImpl { this.toughness = new MageInt(5); // As Ulamog's Despoiler enters the battlefield, you may put two cards your opponents own from exile into their owners' graveyards. If you do, Ulamog's Despoiler enters the battlefield with four +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new UlamogsDespoilerEffect(), null, true, + this.addAbility(new EntersBattlefieldAbility(new UlamogsDespoilerEffect(), null, "As {this} enters the battlefield, you may put two cards your opponents own from exile into their owners' graveyards. If you do, {this} enters the battlefield with four +1/+1 counters on it", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java b/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java index 5fa4a7be4c8..0ddd17b5cbf 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java @@ -59,7 +59,7 @@ public class WoodlandWanderer extends CardImpl { // Converge - Woodland Wanderer enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } public WoodlandWanderer(final WoodlandWanderer card) { diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java index c30dfb512fe..16bef199b09 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/GoryosVengeance.java @@ -110,12 +110,12 @@ class GoryosVengeanceEffect extends OneShotEffect { if (controller != null) { Card card = game.getCard(targetPointer.getFirst(game, source)); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { // Haste ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); - effect.setTargetPointer(new FixedTarget(permanent.getId())); + effect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(effect, source); // Exile it at end of turn Effect exileEffect = new ExileTargetEffect("Exile " + permanent.getName() + " at the beginning of the next end step"); diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java index 98bc1dbe5f7..b37336ee341 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/IwamoriOfTheOpenFist.java @@ -84,26 +84,26 @@ public class IwamoriOfTheOpenFist extends CardImpl { class IwamoriOfTheOpenFistEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("legendary creature card"); - + static { filter.add(new SupertypePredicate("Legendary")); filter.add(new CardTypePredicate(CardType.CREATURE)); } - + public IwamoriOfTheOpenFistEffect() { super(Outcome.Detriment); this.staticText = "each opponent may put a legendary creature card from his or her hand onto the battlefield"; } - + public IwamoriOfTheOpenFistEffect(final IwamoriOfTheOpenFistEffect effect) { super(effect); } - + @Override public IwamoriOfTheOpenFistEffect copy() { return new IwamoriOfTheOpenFistEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -123,14 +123,7 @@ class IwamoriOfTheOpenFistEffect extends OneShotEffect { } } } - if (cards.size() > 0) { - for (Card card: cards.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } - } - } + controller.moveCards(cards.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); return true; } diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java index b896f12a2c3..487d04fcf35 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java @@ -28,13 +28,17 @@ package mage.sets.betrayersofkamigawa; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -47,7 +51,7 @@ public class OrbOfDreams extends CardImpl { public OrbOfDreams(UUID ownerId) { super(ownerId, 156, "Orb of Dreams", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); this.expansionSetCode = "BOK"; - + // Permanents enter the battlefield tapped. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OrbOfDreamsEffect())); } @@ -60,7 +64,7 @@ public class OrbOfDreams extends CardImpl { public OrbOfDreams copy() { return new OrbOfDreams(this); } - + private class OrbOfDreamsEffect extends ReplacementEffectImpl { OrbOfDreamsEffect() { @@ -79,23 +83,22 @@ public class OrbOfDreams extends CardImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { permanent.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return true; } - } + } } - diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java index 826408a71be..f6d16875adc 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/PatronOfTheMoon.java @@ -35,8 +35,8 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.OfferingAbility; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -100,13 +100,8 @@ class PatronOfTheMoonEffect extends OneShotEffect { if (controller != null) { TargetCard target = new TargetCardInHand(0, 2, new FilterLandCard("up to two land cards to put onto the battlefield tapped")); controller.chooseTarget(outcome, controller.getHand(), target, source, game); - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), true); - } - } - return true; + return controller.moveCards(new CardsImpl(target.getTargets()).getCards(game), + Zone.BATTLEFIELD, source, game, true, false, false, null); } return false; } diff --git a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java index e7d04f82ebb..ccfb16f61e7 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java @@ -32,20 +32,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.PlayAdditionalLandsControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -64,6 +62,7 @@ import mage.util.CardUtil; public class KioraTheCrashingWave extends CardImpl { private static final FilterPermanent filter = new FilterPermanent("permanent an opponent control"); + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); } @@ -73,8 +72,7 @@ public class KioraTheCrashingWave extends CardImpl { this.expansionSetCode = "BNG"; this.subtype.add("Kiora"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); // +1: Until your next turn, prevent all damage that would be dealt to and dealt by target permanent an opponent controls. LoyaltyAbility ability = new LoyaltyAbility(new KioraPreventionEffect(), 1); @@ -89,7 +87,6 @@ public class KioraTheCrashingWave extends CardImpl { // -5: You get an emblem with "At the beginning of your end step, put a 9/9 blue Kraken creature token onto the battlefield." this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KioraEmblem()), -5)); - } public KioraTheCrashingWave(final KioraTheCrashingWave card) { @@ -126,10 +123,10 @@ class KioraPreventionEffect extends PreventionEffectImpl { @Override public void init(Ability source, Game game) { super.init(source, game); - for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { + for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented."), game); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(), CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented."), game); } } } @@ -138,7 +135,7 @@ class KioraPreventionEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (super.applies(event, source, game) && event instanceof DamageEvent) { Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetPermanent != null + if (targetPermanent != null && (event.getSourceId().equals(targetPermanent.getId()) || event.getTargetId().equals(targetPermanent.getId()))) { return true; } @@ -149,10 +146,10 @@ class KioraPreventionEffect extends PreventionEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (super.isInactive(source, game)) { - for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { + for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),"", game); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(), "", game); } } return true; @@ -162,9 +159,11 @@ class KioraPreventionEffect extends PreventionEffectImpl { } /** - * Emblem: "At the beginning of your end step, put a 9/9 blue Kraken creature token onto the battlefield." + * Emblem: "At the beginning of your end step, put a 9/9 blue Kraken creature + * token onto the battlefield." */ class KioraEmblem extends Emblem { + public KioraEmblem() { this.setName("EMBLEM: Kiora, the Crashing Wave"); Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.COMMAND, new CreateTokenEffect(new KioraKrakenToken()), TargetController.YOU, null, false); diff --git a/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java b/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java index 971027d4b3f..930ff9345d3 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java @@ -29,7 +29,6 @@ package mage.sets.bornofthegods; import java.util.UUID; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.TributeNotPaidCondition; diff --git a/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java b/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java index d5fdc7aca32..688d96d8083 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/Peregrination.java @@ -113,14 +113,13 @@ class PeregrinationEffect extends OneShotEffect { TargetCard target2 = new TargetCard(Zone.LIBRARY, filter); controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); - - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); revealed.remove(card); card = revealed.getCards(game).iterator().next(); - controller.moveCards(card, null, Zone.HAND, source, game); + controller.moveCards(card, Zone.HAND, source, game); } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java index bc9ef137476..ac250e6c060 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java @@ -59,7 +59,7 @@ public class MyojinOfInfiniteRage extends CardImpl { private static final FilterLandPermanent filter = new FilterLandPermanent("lands"); public MyojinOfInfiniteRage(UUID ownerId) { - super(ownerId, 181, "Myojin Of Infinite Rage", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{7}{R}{R}{R}"); + super(ownerId, 181, "Myojin of Infinite Rage", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{7}{R}{R}{R}"); this.expansionSetCode = "CHK"; this.supertype.add("Legendary"); this.subtype.add("Spirit"); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java b/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java index 00a11497edb..248b962c6f1 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java @@ -25,14 +25,10 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.championsofkamigawa; import java.util.UUID; import mage.MageObjectReference; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; @@ -40,12 +36,15 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.ExileZone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -61,7 +60,7 @@ public class OtherworldlyJourney extends CardImpl { super(ownerId, 37, "Otherworldly Journey", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.expansionSetCode = "CHK"; this.subtype.add("Arcane"); - + // Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it. this.getSpellAbility().addEffect(new OtherworldlyJourneyEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -82,7 +81,7 @@ class OtherworldlyJourneyEffect extends OneShotEffect { private static final String effectText = "Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it"; - OtherworldlyJourneyEffect ( ) { + OtherworldlyJourneyEffect() { super(Outcome.Benefit); staticText = effectText; } @@ -102,12 +101,12 @@ class OtherworldlyJourneyEffect extends OneShotEffect { Card card = game.getCard(permanent.getId()); if (card != null) { //create delayed triggered ability - DelayedTriggeredAbility delayedAbility = - new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OtherworldlyJourneyReturnFromExileEffect(new MageObjectReference(card, game))); + DelayedTriggeredAbility delayedAbility + = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OtherworldlyJourneyReturnFromExileEffect(new MageObjectReference(card, game))); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + game.addDelayedTriggeredAbility(delayedAbility); } } return true; @@ -126,6 +125,7 @@ class OtherworldlyJourneyEffect extends OneShotEffect { class OtherworldlyJourneyReturnFromExileEffect extends OneShotEffect { MageObjectReference objectToReturn; + public OtherworldlyJourneyReturnFromExileEffect(MageObjectReference objectToReturn) { super(Outcome.PutCardInPlay); this.objectToReturn = objectToReturn; @@ -148,19 +148,18 @@ class OtherworldlyJourneyReturnFromExileEffect extends OneShotEffect { if (card != null && objectToReturn.refersTo(card, game)) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { - game.addEffect(new OtherworldlyJourneyEntersBattlefieldEffect(objectToReturn), source); - owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + game.addEffect(new OtherworldlyJourneyEntersBattlefieldEffect(objectToReturn), source); + owner.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); } } return true; } } - class OtherworldlyJourneyEntersBattlefieldEffect extends ReplacementEffectImpl { - + MageObjectReference objectToReturn; - + public OtherworldlyJourneyEntersBattlefieldEffect(MageObjectReference objectToReturn) { super(Duration.Custom, Outcome.BoostCreature); this.objectToReturn = objectToReturn; @@ -187,7 +186,7 @@ class OtherworldlyJourneyEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(), game); discard(); // use only once diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/Reweave.java b/Mage.Sets/src/mage/sets/championsofkamigawa/Reweave.java index 665831faad9..6a82d96309c 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/Reweave.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/Reweave.java @@ -28,6 +28,7 @@ package mage.sets.championsofkamigawa; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.SpliceOntoArcaneAbility; @@ -58,7 +59,6 @@ public class Reweave extends CardImpl { this.expansionSetCode = "CHK"; this.subtype.add("Arcane"); - // Target permanent's controller sacrifices it. If he or she does, that player reveals cards from the top of his or her library until he or she reveals a permanent card that shares a card type with the sacrificed permanent, puts that card onto the battlefield, then shuffles his or her library. this.getSpellAbility().addEffect(new ReweaveEffect()); Target target = new TargetPermanent(); @@ -97,9 +97,10 @@ class ReweaveEffect extends OneShotEffect { } @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget()); - if (permanent != null) { + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + MageObject sourceObject = source.getSourceObject(game); + if (permanent != null && sourceObject != null) { if (permanent.sacrifice(source.getSourceId(), game)) { Player permanentController = game.getPlayer(permanent.getControllerId()); if (permanentController != null) { @@ -122,11 +123,11 @@ class ReweaveEffect extends OneShotEffect { } } } while (!cardFound && library.size() > 0); - permanentController.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + permanentController.moveCards(card, Zone.BATTLEFIELD, source, game); } if (cards.size() > 0) { - permanentController.revealCards("Reweave", cards, game); + permanentController.revealCards(sourceObject.getIdName(), cards, game); if (cardFound && card != null) { cards.remove(card); } @@ -137,7 +138,7 @@ class ReweaveEffect extends OneShotEffect { return true; } return false; - } + } } return true; } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/RyuseiTheFallingStar.java b/Mage.Sets/src/mage/sets/championsofkamigawa/RyuseiTheFallingStar.java index 22072830492..db772aa455f 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/RyuseiTheFallingStar.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/RyuseiTheFallingStar.java @@ -53,7 +53,7 @@ public class RyuseiTheFallingStar extends CardImpl { } public RyuseiTheFallingStar(UUID ownerID) { - super(ownerID, 185, "Ryusei, The Falling Star", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}"); + super(ownerID, 185, "Ryusei, the Falling Star", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}"); this.expansionSetCode = "CHK"; this.supertype.add("Legendary"); this.subtype.add("Dragon"); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java b/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java index 49f139f2639..958837afe7a 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java @@ -28,16 +28,20 @@ package mage.sets.championsofkamigawa; import java.util.UUID; - -import mage.constants.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -61,7 +65,7 @@ public class ShimatsuTheBloodcloaked extends CardImpl { this.toughness = new MageInt(0); // As Shimatsu the Bloodcloaked enters the battlefield, sacrifice any number of permanents. Shimatsu enters the battlefield with that many +1/+1 counters on it. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ShimatsuTheBloodcloakedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ShimatsuTheBloodcloakedEffect())); } public ShimatsuTheBloodcloaked(final ShimatsuTheBloodcloaked card) { @@ -75,16 +79,16 @@ public class ShimatsuTheBloodcloaked extends CardImpl { } class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { - + public ShimatsuTheBloodcloakedEffect() { - super(Duration.WhileOnBattlefield, Outcome.BoostCreature); + super(Duration.EndOfGame, Outcome.BoostCreature); this.staticText = "As {this} enters the battlefield, sacrifice any number of permanents. {this} enters the battlefield with that many +1/+1 counters on it"; } - + public ShimatsuTheBloodcloakedEffect(final ShimatsuTheBloodcloakedEffect effect) { super(effect); } - + @Override public ShimatsuTheBloodcloakedEffect copy() { return new ShimatsuTheBloodcloakedEffect(this); @@ -94,15 +98,15 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(source.getSourceId()); + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledPermanent(), true); @@ -112,8 +116,8 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { controller.chooseTarget(Outcome.Detriment, target, source, game); if (target.getTargets().size() > 0) { int sacrificedCreatures = target.getTargets().size(); - game.informPlayers(new StringBuilder(controller.getLogName()).append(" sacrifices ").append(sacrificedCreatures).append(" creatures for ").append(creature.getName()).toString()); - for (UUID targetId: target.getTargets()) { + game.informPlayers(controller.getLogName() + " sacrifices " + sacrificedCreatures + " creatures for " + creature.getLogName()); + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) { return false; @@ -124,5 +128,5 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java b/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java index bf4e4d5139b..f8510304312 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/ThroughTheBreach.java @@ -106,7 +106,7 @@ class ThroughTheBreachEffect extends OneShotEffect { if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); diff --git a/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java b/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java index 653bb2a81d0..7205351a470 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java +++ b/Mage.Sets/src/mage/sets/coldsnap/ArcumDagsson.java @@ -56,8 +56,9 @@ import mage.target.common.TargetCardInLibrary; * @author emerald000 */ public class ArcumDagsson extends CardImpl { - + private static final FilterPermanent filter = new FilterArtifactPermanent("artifact creature"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } @@ -88,26 +89,27 @@ public class ArcumDagsson extends CardImpl { } class ArcumDagssonEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterArtifactCard("noncreature artifact card"); + static { filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); } - + ArcumDagssonEffect() { super(Outcome.Removal); this.staticText = "Target artifact creature's controller sacrifices it. That player may search his or her library for a noncreature artifact card, put it onto the battlefield, then shuffle his or her library"; } - + ArcumDagssonEffect(final ArcumDagssonEffect effect) { super(effect); } - + @Override public ArcumDagssonEffect copy() { return new ArcumDagssonEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Permanent artifactCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); @@ -120,7 +122,7 @@ class ArcumDagssonEffect extends OneShotEffect { if (player.searchLibrary(target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + player.moveCards(card, Zone.BATTLEFIELD, source, game); } } player.shuffleLibrary(game); diff --git a/Mage.Sets/src/mage/sets/coldsnap/BraidOfFire.java b/Mage.Sets/src/mage/sets/coldsnap/BraidOfFire.java new file mode 100644 index 00000000000..e08dc4e32f9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/coldsnap/BraidOfFire.java @@ -0,0 +1,93 @@ +/* + * 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.sets.coldsnap; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.costs.CostImpl; +import mage.abilities.keyword.CumulativeUpkeepAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author AlumiuN + */ +public class BraidOfFire extends CardImpl { + + public BraidOfFire(UUID ownerId) { + super(ownerId, 78, "Braid of Fire", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + this.expansionSetCode = "CSP"; + + // Cumulative upkeep-Add {R} to your mana pool. + this.addAbility(new CumulativeUpkeepAbility(new BraidOfFireCost())); + } + + public BraidOfFire(final BraidOfFire card) { + super(card); + } + + @Override + public BraidOfFire copy() { + return new BraidOfFire(this); + } +} + +class BraidOfFireCost extends CostImpl { + + public BraidOfFireCost() { + this.text = "Add {R} to your mana pool"; + } + + public BraidOfFireCost(BraidOfFireCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Player player = game.getPlayer(controllerId); + player.getManaPool().addMana(Mana.RedMana, game, ability); + paid = true; + return true; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + return game.getPlayer(controllerId) != null; + } + + @Override + public BraidOfFireCost copy() { + return new BraidOfFireCost(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java index 70fc31b6951..4875d2aca7e 100644 --- a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java +++ b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java @@ -46,6 +46,7 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -101,33 +102,6 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl { return new ChorusOfTheConclaveReplacementEffect(this); } - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - int xCost = 0; - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - if (you.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", source, game)) { - xCost += playerPaysXGenericMana(you, source, game); - // save the x value to be available for ETB replacement effect - Object object = game.getState().getValue("spellX" + source.getSourceId()); - Map spellX; - if (object != null && object instanceof Map) { - spellX = (Map) object; - } else { - spellX = new HashMap<>(); - } - spellX.put(event.getSourceId().toString() + game.getState().getZoneChangeCounter(event.getSourceId()), xCost); - game.getState().setValue("spellX" + source.getSourceId(), spellX); - } - } - return false; - } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.CAST_SPELL; @@ -144,6 +118,28 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl { return false; } + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int xCost = 0; + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", source, game)) { + xCost += playerPaysXGenericMana(controller, source, game); + // save the x value to be available for ETB replacement effect + Object object = game.getState().getValue("spellX" + source.getSourceId()); + Map spellX; + if (object != null && object instanceof Map) { + spellX = (Map) object; + } else { + spellX = new HashMap<>(); + } + spellX.put(event.getSourceId().toString() + game.getState().getZoneChangeCounter(event.getSourceId()), xCost); + game.getState().setValue("spellX" + source.getSourceId(), spellX); + } + } + return false; + } + protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { int xValue = 0; boolean payed = false; @@ -191,16 +187,18 @@ class ChorusOfTheConclaveReplacementEffect2 extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Map spellX = (Map) game.getState().getValue("spellX" + source.getSourceId()); - return spellX != null && event.getSourceId() != null && spellX.containsKey(event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 2)); + return spellX != null + && event.getSourceId() != null + && spellX.containsKey(event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 1)); } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getSourceId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); Map spellX = (Map) game.getState().getValue("spellX" + source.getSourceId()); MageObject sourceObject = source.getSourceObject(game); if (sourceObject != null && creature != null && spellX != null) { - String key = event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 2); + String key = event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 1); int xValue = spellX.get(key); if (xValue > 0) { creature.addCounters(CounterType.P1P1.createInstance(xValue), game); diff --git a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java index ae71daeb4db..bc05511f481 100644 --- a/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java +++ b/Mage.Sets/src/mage/sets/commander/KaaliaOfTheVast.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,7 +20,7 @@ * 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. @@ -148,20 +148,20 @@ class KaaliaOfTheVastEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCreatureInPlay, "Put an Angel, Demon, or Dragon creature card from your hand onto the battlefield tapped and attacking?", source, game)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || !controller.chooseUse(Outcome.PutCreatureInPlay, "Put an Angel, Demon, or Dragon creature card from your hand onto the battlefield tapped and attacking?", source, game)) { return false; } TargetCardInHand target = new TargetCardInHand(filter); - if (target.canChoose(player.getId(), game) && target.choose(getOutcome(), player.getId(), source.getSourceId(), game)) { + if (target.canChoose(controller.getId(), game) && target.choose(getOutcome(), controller.getId(), source.getSourceId(), game)) { if (target.getTargets().size() > 0) { UUID cardId = target.getFirstTarget(); Card card = game.getCard(cardId); if (card != null && game.getCombat() != null) { UUID defenderId = game.getCombat().getDefendingPlayerId(source.getSourceId(), game); if (defenderId != null) { - player.getHand().remove(card); - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), true); + controller.getHand().remove(card); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); Permanent creature = game.getPermanent(cardId); if (creature != null) { game.getCombat().addAttackerToCombat(card.getId(), defenderId, game); diff --git a/Mage.Sets/src/mage/sets/commander/KodamasReach.java b/Mage.Sets/src/mage/sets/commander/KodamasReach.java index 6b7883e9e8b..103a617285c 100644 --- a/Mage.Sets/src/mage/sets/commander/KodamasReach.java +++ b/Mage.Sets/src/mage/sets/commander/KodamasReach.java @@ -110,17 +110,17 @@ class KodamasReachEffect extends OneShotEffect { controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); revealed.remove(card); } card = revealed.getCards(game).iterator().next(); if (card != null) { - controller.moveCards(card, null, Zone.HAND, source, game); + controller.moveCards(card, Zone.HAND, source, game); } } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } } diff --git a/Mage.Sets/src/mage/sets/commander/SewerNemesis.java b/Mage.Sets/src/mage/sets/commander/SewerNemesis.java index fa7df34d3fa..e8955959eee 100644 --- a/Mage.Sets/src/mage/sets/commander/SewerNemesis.java +++ b/Mage.Sets/src/mage/sets/commander/SewerNemesis.java @@ -35,7 +35,7 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChoosePlayerEffect; import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveTargetEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.cards.CardImpl; @@ -47,9 +47,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTarget; /** @@ -67,7 +65,7 @@ public class SewerNemesis extends CardImpl { this.toughness = new MageInt(0); // As Sewer Nemesis enters the battlefield, choose a player. - this.addAbility(new AsEntersBattlefieldAbility(new SewerNemesisChoosePlayerEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChoosePlayerEffect(Outcome.Detriment))); // Sewer Nemesis's power and toughness are each equal to the number of cards in the chosen player's graveyard. this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInTargetOpponentsGraveyardCount(), Duration.WhileOnBattlefield))); // Whenever the chosen player casts a spell, that player puts the top card of his or her library into his or her graveyard. @@ -85,42 +83,8 @@ public class SewerNemesis extends CardImpl { } } -class SewerNemesisChoosePlayerEffect extends OneShotEffect { - - public SewerNemesisChoosePlayerEffect() { - super(Outcome.Detriment); - this.staticText = "choose a player"; - } - - public SewerNemesisChoosePlayerEffect(final SewerNemesisChoosePlayerEffect effect) { - super(effect); - } - - @Override - public SewerNemesisChoosePlayerEffect copy() { - return new SewerNemesisChoosePlayerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetPlayer target = new TargetPlayer(1,1,true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getLogName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class CardsInTargetOpponentsGraveyardCount implements DynamicValue { + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { if (sourceAbility != null) { diff --git a/Mage.Sets/src/mage/sets/commander/TarielReckonerOfSouls.java b/Mage.Sets/src/mage/sets/commander/TarielReckonerOfSouls.java index 7cfe1e0b577..cb464431dbc 100644 --- a/Mage.Sets/src/mage/sets/commander/TarielReckonerOfSouls.java +++ b/Mage.Sets/src/mage/sets/commander/TarielReckonerOfSouls.java @@ -110,7 +110,7 @@ class TarielReckonerOfSoulsEffect extends OneShotEffect { } if (!creatureCards.isEmpty()) { Card card = creatureCards.getRandom(game); - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java index 5be1bed0a24..7ff4058deb2 100644 --- a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java +++ b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java @@ -80,27 +80,27 @@ public class TheMimeoplasm extends CardImpl { } class TheMimeoplasmEffect extends OneShotEffect { - + TheMimeoplasmEffect() { super(Outcome.Copy); } - + TheMimeoplasmEffect(final TheMimeoplasmEffect effect) { super(effect); } - + @Override public TheMimeoplasmEffect copy() { return new TheMimeoplasmEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) { - if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", source, game)) { + if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", source, game)) { TargetCardInGraveyard targetCopy = new TargetCardInGraveyard(new FilterCreatureCard("creature card to become a copy of")); TargetCardInGraveyard targetCounters = new TargetCardInGraveyard(new FilterCreatureCard("creature card to determine amount of additional +1/+1 counters")); if (controller.choose(Outcome.Copy, targetCopy, source.getSourceId(), game)) { @@ -122,7 +122,7 @@ class TheMimeoplasmEffect extends OneShotEffect { } } } - return true; + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java b/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java index b375229ce70..4143523f77c 100644 --- a/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java +++ b/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java @@ -66,8 +66,9 @@ public class NayaSoulbeast extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - // When you cast Naya Soulbeast, each player reveals the top card of his or her library. Naya Soulbeast enters the battlefield with X +1/+1 counters on it, where X is the total converted mana cost of all cards revealed this way. + // When you cast Naya Soulbeast, each player reveals the top card of his or her library. Ability ability = new CastSourceTriggeredAbility(new NayaSoulbeastCastEffect(), false); + // Naya Soulbeast enters the battlefield with X +1/+1 counters on it, where X is the total converted mana cost of all cards revealed this way. ability.addEffect(new NayaSoulbeastReplacementEffect()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java index 4601e1a29d5..53bb7eb50b8 100644 --- a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java +++ b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java @@ -47,6 +47,7 @@ import mage.constants.WatcherScope; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -74,7 +75,7 @@ public class OpalPalace extends CardImpl { ability = new SimpleStaticAbility(Zone.ALL, new OpalPalaceEntersBattlefieldEffect()); ability.setRuleVisible(false); this.addAbility(ability); - + } public OpalPalace(final OpalPalace card) { @@ -91,10 +92,10 @@ class OpalPalaceWatcher extends Watcher { public List commanderId = new ArrayList<>(); private final String originalId; - + public OpalPalaceWatcher(String originalId) { super("ManaPaidFromOpalPalaceWatcher", WatcherScope.CARD); - this.originalId = originalId; + this.originalId = originalId; } public OpalPalaceWatcher(final OpalPalaceWatcher watcher) { @@ -116,16 +117,16 @@ class OpalPalaceWatcher extends Watcher { if (spell != null) { Card card = spell.getCard(); if (card != null) { - for (UUID playerId :game.getPlayerList()) { + for (UUID playerId : game.getPlayerList()) { Player player = game.getPlayer(playerId); if (player != null) { if (player.getCommanderId() != null && player.getCommanderId().equals(card.getId())) { commanderId.add(card.getId()); break; } - } + } } - } + } } } } @@ -153,19 +154,19 @@ class OpalPalaceEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { OpalPalaceWatcher watcher = (OpalPalaceWatcher) game.getState().getWatchers().get("ManaPaidFromOpalPalaceWatcher", source.getSourceId()); - return watcher != null && - watcher.commanderId.contains(event.getTargetId()); + return watcher != null + && watcher.commanderId.contains(event.getTargetId()); } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { - Integer castCount = (Integer)game.getState().getValue(permanent.getId() + "_castCount"); + Integer castCount = (Integer) game.getState().getValue(permanent.getId() + "_castCount"); if (castCount != null && castCount > 0) { permanent.addCounters(CounterType.P1P1.createInstance(castCount), game); } diff --git a/Mage.Sets/src/mage/sets/commander2013/PrimalVigor.java b/Mage.Sets/src/mage/sets/commander2013/PrimalVigor.java index ee069e6b007..468b0b9fae7 100644 --- a/Mage.Sets/src/mage/sets/commander2013/PrimalVigor.java +++ b/Mage.Sets/src/mage/sets/commander2013/PrimalVigor.java @@ -51,7 +51,6 @@ public class PrimalVigor extends CardImpl { super(ownerId, 162, "Primal Vigor", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); this.expansionSetCode = "C13"; - // If one or more tokens would be put onto the battlefield, twice that many of those tokens are put onto the battlefield instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalVigorTokenEffect())); // If one or more +1/+1 counters would be placed on a creature, twice that many +1/+1 counters are placed on that creature instead. @@ -121,7 +120,7 @@ class PrimalVigorCounterEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(event.getAmount() *2); + event.setAmount(event.getAmount() * 2); return false; } @@ -132,8 +131,11 @@ class PrimalVigorCounterEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null && target.getCardType().contains(CardType.CREATURE) + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE) && event.getData() != null && event.getData().equals("+1/+1")) { return true; } diff --git a/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java b/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java index 18c7db6b708..6c3967a3e6d 100644 --- a/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java +++ b/Mage.Sets/src/mage/sets/commander2013/TrueNameNemesis.java @@ -30,9 +30,8 @@ package mage.sets.commander2013; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChoosePlayerEffect; import mage.abilities.keyword.ProtectionAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -44,18 +43,19 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.game.stack.StackObject; -import mage.players.Player; -import mage.target.TargetPlayer; /** - * Protection from a player is a new variant of the protection ability. It means the following: - * -- True-Name Nemesis can’t be the target of spells or abilities controlled by the chosen player. - * -- True-Name Nemesis can’t be enchanted by Auras or equipped by Equipment controlled - * by the chosen player. (The same is true for Fortifications controlled by the chosen player, - * if True-Name Nemesis becomes a land.) - * -- True-Name Nemesis can’t be blocked by creatures controlled by the chosen player. - * -- All damage that would be dealt to True-Name Nemesis by sources controlled by the chosen player - * is prevented. (The same is true for sources owned by the chosen player that don’t have controllers.) + * Protection from a player is a new variant of the protection ability. It means + * the following: -- True-Name Nemesis can’t be the target of spells or + * abilities controlled by the chosen player. -- True-Name Nemesis can’t be + * enchanted by Auras or equipped by Equipment controlled by the chosen player. + * (The same is true for Fortifications controlled by the chosen player, if + * True-Name Nemesis becomes a land.) -- True-Name Nemesis can’t be blocked by + * creatures controlled by the chosen player. -- All damage that would be dealt + * to True-Name Nemesis by sources controlled by the chosen player is prevented. + * (The same is true for sources owned by the chosen player that don’t have + * controllers.) + * * @author LevelX2 */ public class TrueNameNemesis extends CardImpl { @@ -70,7 +70,7 @@ public class TrueNameNemesis extends CardImpl { this.toughness = new MageInt(1); // As True-Name Nemesis enters the battlefield, choose a player. - this.addAbility(new AsEntersBattlefieldAbility(new TrueNameNemesisChoosePlayerEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChoosePlayerEffect(Outcome.Protect))); // True-Name Nemesis has protection from the chosen player. this.addAbility(new ProtectionFromPlayerAbility()); } @@ -85,42 +85,6 @@ public class TrueNameNemesis extends CardImpl { } } -class TrueNameNemesisChoosePlayerEffect extends OneShotEffect { - - public TrueNameNemesisChoosePlayerEffect() { - super(Outcome.Detriment); - this.staticText = "choose a player"; - } - - public TrueNameNemesisChoosePlayerEffect(final TrueNameNemesisChoosePlayerEffect effect) { - super(effect); - } - - @Override - public TrueNameNemesisChoosePlayerEffect copy() { - return new TrueNameNemesisChoosePlayerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetPlayer target = new TargetPlayer(1,1,true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - permanent.addInfo("chosen player", "Chosen player: " + chosenPlayer.getLogName() + "", game); - return true; - } - } - } - return false; - } -} - class ProtectionFromPlayerAbility extends ProtectionAbility { public ProtectionFromPlayerAbility() { diff --git a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java index 7ba41f23715..0ce63beead1 100644 --- a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java +++ b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java @@ -91,7 +91,7 @@ class BitterFeudEntersBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { TargetPlayer target = new TargetPlayer(2, 2, true); controller.chooseTarget(outcome, target, source, game); diff --git a/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java b/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java index 48b846573c7..0f07b4a61ab 100644 --- a/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java +++ b/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java @@ -33,13 +33,12 @@ import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; @@ -75,7 +73,7 @@ public class DarettiScrapSavant extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Daretti"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Discard up to two cards, then draw that many cards. this.addAbility(new LoyaltyAbility(new DarettiDiscardDrawEffect(), 2)); @@ -166,7 +164,7 @@ class DarettiSacrificeEffect extends OneShotEffect { if (artifact != null && artifact.sacrifice(source.getSourceId(), game)) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - return controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } @@ -179,7 +177,6 @@ class DarettiSacrificeEffect extends OneShotEffect { class DarettiScrapSavantEmblem extends Emblem { // You get an emblem with "Whenever an artifact is put into your graveyard from the battlefield, return that card to the battlefield at the beginning of the next end step." - public DarettiScrapSavantEmblem() { this.setName("Emblem - Daretti"); this.getAbilities().add(new DarettiScrapSavantTriggeredAbility()); diff --git a/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java b/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java index adf5daa6ca5..e8d82a0618a 100644 --- a/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java +++ b/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java @@ -32,19 +32,17 @@ import mage.MageInt; import mage.ObjectColor; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.mana.GreenManaAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.counters.CounterType; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterArtifactOrEnchantmentPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.permanent.token.Token; import mage.target.TargetPermanent; @@ -56,6 +54,7 @@ import mage.target.TargetPermanent; public class FreyaliseLlanowarsFury extends CardImpl { private static final FilterControlledCreaturePermanent filterGreen = new FilterControlledCreaturePermanent("green creature you control"); + static { filterGreen.add(new ColorPredicate(ObjectColor.GREEN)); } @@ -65,8 +64,8 @@ public class FreyaliseLlanowarsFury extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Freyalise"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); + // +2: Put a 1/1 green Elf Druid creature token onto the battlefield with "{T}: Add {G} to your mana pool." this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new FreyaliseLlanowarsFuryToken()), 2)); // -2: Destroy target artifact or enchantment. @@ -106,4 +105,4 @@ class FreyaliseLlanowarsFuryToken extends Token { // {T}: Add {G} to your mana pool. this.addAbility(new GreenManaAbility()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander2014/InfernalOffering.java b/Mage.Sets/src/mage/sets/commander2014/InfernalOffering.java index 18a0fef42cb..07816fa09d4 100644 --- a/Mage.Sets/src/mage/sets/commander2014/InfernalOffering.java +++ b/Mage.Sets/src/mage/sets/commander2014/InfernalOffering.java @@ -104,7 +104,7 @@ class InfernalOfferingSacrificeEffect extends OneShotEffect { if (opponent != null) { //Choose creatures to sacrifice Map toSacrifice = new HashMap<>(2); - for (UUID playerId : player.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(player.getId(), game)) { if (playerId.equals(player.getId()) || playerId.equals(opponent.getId())) { target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true); if (target.choose(Outcome.Sacrifice, playerId, source.getControllerId(), game)) { @@ -154,16 +154,16 @@ class InfernalOfferingReturnEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Target target = new TargetOpponent(true); target.choose(Outcome.PutCreatureInPlay, source.getControllerId(), source.getSourceId(), game); Player opponent = game.getPlayer(target.getFirstTarget()); target = new TargetCardInYourGraveyard(new FilterCreatureCard("creature card in your graveyard")); - if (target.choose(Outcome.PutCreatureInPlay, player.getId(), source.getSourceId(), game)) { - Card card = player.getGraveyard().get(target.getFirstTarget(), game); + if (target.choose(Outcome.PutCreatureInPlay, controller.getId(), source.getSourceId(), game)) { + Card card = controller.getGraveyard().get(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } if (opponent != null) { @@ -171,7 +171,7 @@ class InfernalOfferingReturnEffect extends OneShotEffect { if (target.choose(Outcome.PutCreatureInPlay, opponent.getId(), source.getSourceId(), game)) { Card card = opponent.getGraveyard().get(target.getFirstTarget(), game); if (card != null) { - opponent.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + opponent.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java b/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java index 7485d6c1534..1ec61bbb10e 100644 --- a/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java +++ b/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java @@ -28,14 +28,11 @@ package mage.sets.commander2014; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -45,6 +42,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author LevelX2 */ public class MasterworkOfIngenuity extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("artifact"); static { @@ -58,12 +56,7 @@ public class MasterworkOfIngenuity extends CardImpl { this.subtype.add("Equipment"); // You may have Masterwork of Ingenuity enter the battlefield as a copy of any Equipment on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(filter), - "You may have {this} enter the battlefield as a copy of any Equipment on the battlefield", - true)); - this.addAbility(ability); - + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public MasterworkOfIngenuity(final MasterworkOfIngenuity card) { diff --git a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java index c9f5dad4248..eb480233616 100644 --- a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java +++ b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java @@ -27,15 +27,11 @@ */ package mage.sets.commander2014; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.Effect; @@ -43,7 +39,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.IndestructibleAbility; @@ -55,7 +50,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -80,8 +74,7 @@ public class NahiriTheLithomancer extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Nahiri"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Put a 1/1 white Kor Soldier creature token onto the battlefield. You may attach an Equipment you control to it. this.addAbility(new LoyaltyAbility(new NahiriTheLithomancerFirstAbilityEffect(), 2)); @@ -111,6 +104,7 @@ public class NahiriTheLithomancer extends CardImpl { class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { private static final FilterControlledPermanent filter = new FilterControlledPermanent("an Equipment you control"); + static { filter.add(new SubtypePredicate("Equipment")); } @@ -139,8 +133,8 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { if (tokenPermanent != null) { //TODO: Make sure the Equipment can legally enchant the token, preferably on targetting. Target target = new TargetControlledPermanent(0, 1, filter, true); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", source, game)) { if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { Permanent equipmentPermanent = game.getPermanent(target.getFirstTarget()); if (equipmentPermanent != null) { @@ -164,6 +158,7 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("an Equipment"); + static { filter.add(new SubtypePredicate("Equipment")); } @@ -191,15 +186,14 @@ class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect { controller.choose(outcome, target, source.getSourceId(), game); Card card = controller.getHand().get(target.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - } - else { + } else { Target target = new TargetCardInYourGraveyard(0, 1, filter); target.choose(Outcome.PutCardInPlay, source.getControllerId(), source.getSourceId(), game); Card card = controller.getGraveyard().get(target.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java b/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java index b595331cf91..240f34a2f5f 100644 --- a/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java +++ b/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java @@ -71,7 +71,6 @@ public class NecromanticSelection extends CardImpl { super(ownerId, 26, "Necromantic Selection", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{B}{B}{B}"); this.expansionSetCode = "C14"; - // Destroy all creatures, then return a creature card put into a graveyard this way to the battlefield under your control. It's a black Zombie in addition to its other colors and types. Exile Necromantic Selection. this.getSpellAbility().addEffect(new NecromanticSelectionEffect()); this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); @@ -110,7 +109,7 @@ class NecromanticSelectionEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && controller != null) { Cards cards = new CardsImpl(); - for(Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), controller.getId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), controller.getId(), source.getSourceId(), game)) { permanent.destroy(source.getSourceId(), game, false); if (game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { cards.add(permanent); @@ -118,7 +117,7 @@ class NecromanticSelectionEffect extends OneShotEffect { } FilterCard filter = new FilterCreatureCard("creature card put into a graveyard with " + sourceObject.getLogName()); ArrayList> cardIdPredicates = new ArrayList<>(); - for(UUID cardId: cards) { + for (UUID cardId : cards) { cardIdPredicates.add(new CardIdPredicate(cardId)); } filter.add(Predicates.or(cardIdPredicates)); @@ -126,7 +125,7 @@ class NecromanticSelectionEffect extends OneShotEffect { if (controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); ContinuousEffect effect = new NecromanticSelectionContinuousEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java index 2593433d2ea..2a1e6544c52 100644 --- a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java +++ b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -44,14 +44,11 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.token.DemonToken; @@ -69,8 +66,7 @@ public class ObNixilisOfTheBlackOath extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Nixilis"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Each opponent loses 1 life. You gain life equal to the life lost this way. this.addAbility(new LoyaltyAbility(new ObNixilisOfTheBlackOathEffect1(), 2)); @@ -113,7 +109,7 @@ class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int loseLife = 0; - for (UUID opponentId: game.getOpponents(source.getControllerId())) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); if (opponent != null) { loseLife += opponent.loseLife(1, game); @@ -134,13 +130,15 @@ class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect { } class ObNixilisOfTheBlackOathEmblem extends Emblem { + // You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power." + public ObNixilisOfTheBlackOathEmblem() { this.setName("EMBLEM: Ob Nixilis of the Black Oath"); DynamicValue xValue = new SacrificeCostCreaturesPower(); Effect effect = new GainLifeEffect(xValue); effect.setText("You gain X life"); - Ability ability = new SimpleActivatedAbility(Zone.COMMAND, effect, new ManaCostsImpl("{1}{B}")); + Ability ability = new SimpleActivatedAbility(Zone.COMMAND, effect, new ManaCostsImpl("{1}{B}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent())); effect = new DrawCardSourceControllerEffect(xValue); effect.setText("and draw X cards, where X is the sacrificed creature's power"); diff --git a/Mage.Sets/src/mage/sets/commander2014/ScrapMastery.java b/Mage.Sets/src/mage/sets/commander2014/ScrapMastery.java index 95c2ae286fc..f2512b5b703 100644 --- a/Mage.Sets/src/mage/sets/commander2014/ScrapMastery.java +++ b/Mage.Sets/src/mage/sets/commander2014/ScrapMastery.java @@ -28,14 +28,14 @@ package mage.sets.commander2014; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -56,7 +56,6 @@ public class ScrapMastery extends CardImpl { super(ownerId, 38, "Scrap Mastery", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{R}{R}"); this.expansionSetCode = "C14"; - // Each player exiles all artifact cards from his or her graveyard, then sacrifices all artifacts he or she controls, then puts all cards he or she exiled this way onto the battlefield. this.getSpellAbility().addEffect(new ScrapMasteryEffect()); } @@ -93,36 +92,29 @@ class ScrapMasteryEffect extends OneShotEffect { if (controller != null) { Map> exiledCards = new HashMap<>(); // exile artifacts from graveyard - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - Set cards = new HashSet<>(); - for (Card card: player.getGraveyard().getCards(new FilterArtifactCard(), game)) { - cards.add(card.getId()); - player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); - } + Set cards = player.getGraveyard().getCards(new FilterArtifactCard(), game); + controller.moveCards(cards, Zone.EXILED, source, game); exiledCards.put(player.getId(), cards); } } // sacrifice all artifacts - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), playerId, game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), playerId, game)) { permanent.sacrifice(source.getSourceId(), game); } } } // puts all cards he or she exiled this way onto the battlefield - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (UUID cardId: exiledCards.get(playerId)) { - Card card = game.getCard(cardId); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, cardId); - } - } + Cards playersExiledCards = new CardsImpl(exiledCards.get(playerId)); + controller.moveCards(playersExiledCards, Zone.BATTLEFIELD, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java b/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java index 4990384fa41..bf6477bc1ea 100644 --- a/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java +++ b/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java @@ -31,14 +31,13 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.AsThoughEffectType; import mage.constants.CardType; @@ -46,7 +45,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.game.Game; @@ -64,7 +62,7 @@ public class TeferiTemporalArchmage extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Teferi"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library. this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect( @@ -96,7 +94,6 @@ public class TeferiTemporalArchmage extends CardImpl { class TeferiTemporalArchmageEmblem extends Emblem { // "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant." - public TeferiTemporalArchmageEmblem() { this.setName("EMBLEM: Teferi, Temporal Archmage"); this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new TeferiTemporalArchmageAsThoughEffect())); diff --git a/Mage.Sets/src/mage/sets/commander2014/WakeTheDead.java b/Mage.Sets/src/mage/sets/commander2014/WakeTheDead.java index fc1c258ea11..eb7e9438ae7 100644 --- a/Mage.Sets/src/mage/sets/commander2014/WakeTheDead.java +++ b/Mage.Sets/src/mage/sets/commander2014/WakeTheDead.java @@ -37,8 +37,9 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -148,26 +149,22 @@ class WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect extends OneShotEff @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (UUID targetId : getTargetPointer().getTargets(game, source)) { - Card card = game.getCard(targetId); - if (card != null) { - if (player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), false)) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - permanent.changeControllerId(source.getControllerId(), game); - Effect effect = new SacrificeTargetEffect("Sacrifice those creatures at the beginning of the next end step", source.getControllerId()); - effect.setTargetPointer(new FixedTarget(permanent, game)); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); - } - - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source)); + controller.moveCards(cards, Zone.BATTLEFIELD, source, game); + for (UUID targetId : cards) { + Permanent creature = game.getPermanent(targetId); + if (creature != null) { + Effect effect = new SacrificeTargetEffect("Sacrifice those creatures at the beginning of the next end step", source.getControllerId()); + effect.setTargetPointer(new FixedTarget(creature, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); } + } return true; } diff --git a/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java b/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java index 19994d3145c..bb5bb951b94 100644 --- a/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java +++ b/Mage.Sets/src/mage/sets/commander2014/WaveOfVitriol.java @@ -28,12 +28,15 @@ package mage.sets.commander2014; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -86,9 +89,9 @@ class WaveOfVitriolEffect extends OneShotEffect { new CardTypePredicate(CardType.LAND), Predicates.not(new SupertypePredicate("Basic")) ) - )); } + public WaveOfVitriolEffect() { super(Outcome.Benefit); this.staticText = "Each player sacrifices all artifacts, enchantments, and nonbasic lands he or she controls. For each land sacrificed this way, its controller may search his or her library for a basic land card and put it onto the battlefield tapped. Then each player who searched his or her library this way shuffles it"; @@ -108,11 +111,11 @@ class WaveOfVitriolEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Map sacrificedLands = new HashMap<>(); - for(UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { int count = 0; - for(Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, playerId, game)) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, playerId, game)) { if (permanent.sacrifice(source.getSourceId(), game) && permanent.getCardType().contains(CardType.LAND)) { count++; } @@ -123,25 +126,19 @@ class WaveOfVitriolEffect extends OneShotEffect { } } game.getState().handleSimultaneousEvent(game); - for(Map.Entry entry: sacrificedLands.entrySet()) { + Cards toBattlefield = new CardsImpl(); + Set playersToShuffle = new LinkedHashSet<>(); + for (Map.Entry entry : sacrificedLands.entrySet()) { if (entry.getKey().chooseUse(Outcome.PutLandInPlay, "Search your library for up to " + entry.getValue() + " basic lands?", source, game)) { Target target = new TargetCardInLibrary(0, entry.getValue(), new FilterBasicLandCard()); entry.getKey().chooseTarget(outcome, target, source, game); - for(UUID targetId: target.getTargets()) { - Card card = game.getCard(targetId); - if (card != null) { - entry.getKey().putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); - } - } - entry.getKey().shuffleLibrary(game); - } else { - entry.setValue(0); + toBattlefield.addAll(target.getTargets()); + playersToShuffle.add(entry.getKey()); } } - for(Map.Entry entry: sacrificedLands.entrySet()) { - if (entry.getValue() > 0) { - entry.getKey().shuffleLibrary(game); - } + controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); + for (Player player : playersToShuffle) { + player.shuffleLibrary(game); } return true; diff --git a/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java b/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java index a195c86159a..5c3a39ffaad 100644 --- a/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java +++ b/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java @@ -63,7 +63,8 @@ public class ApocalypseHydra extends CardImpl { this.toughness = new MageInt(0); // Apocalypse Hydra enters the battlefield with X +1/+1 counters on it. If X is 5 or more, it enters the battlefield with an additional X +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new ApocalypseHydraEffect(), true)); + this.addAbility(new EntersBattlefieldAbility(new ApocalypseHydraEffect())); + // {1}{R}, Remove a +1/+1 counter from Apocalypse Hydra: Apocalypse Hydra deals 1 damage to target creature or player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}{R}")); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); @@ -94,12 +95,12 @@ class ApocalypseHydraEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { int amount = spellAbility.getManaCostsToPay().getX(); if (amount > 0) { if (amount < 5) { diff --git a/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java b/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java index 892139f72c1..07e9f18043d 100644 --- a/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java +++ b/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java @@ -28,19 +28,17 @@ package mage.sets.conflux; import java.util.UUID; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.abilities.effects.common.SacrificeEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -65,8 +63,7 @@ public class NicolBolasPlaneswalker extends CardImpl { this.expansionSetCode = "CON"; this.subtype.add("Bolas"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +3: Destroy target noncreature permanent. LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), 3); diff --git a/Mage.Sets/src/mage/sets/conflux/Nyxathid.java b/Mage.Sets/src/mage/sets/conflux/Nyxathid.java index 22fb19bcede..0a7e5fee51a 100644 --- a/Mage.Sets/src/mage/sets/conflux/Nyxathid.java +++ b/Mage.Sets/src/mage/sets/conflux/Nyxathid.java @@ -27,6 +27,7 @@ */ package mage.sets.conflux; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -34,16 +35,16 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseOpponentEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetOpponent; - -import java.util.UUID; /** * @@ -60,7 +61,7 @@ public class Nyxathid extends CardImpl { this.toughness = new MageInt(7); // As Nyxathid enters the battlefield, choose an opponent. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponent())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.Detriment))); // Nyxathid gets -1/-1 for each card in the chosen player's hand. DynamicValue chosenPlayerHand = new SignInversionDynamicValue(new CardsInChosenPlayerHandCount()); @@ -78,48 +79,12 @@ public class Nyxathid extends CardImpl { } } -class ChooseOpponent extends OneShotEffect { - - public ChooseOpponent() { - super(Outcome.Neutral); - this.staticText = "choose an opponent"; - } - - public ChooseOpponent(final ChooseOpponent effect) { - super(effect); - } - - @Override - public ChooseOpponent copy() { - return new ChooseOpponent(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetOpponent target = new TargetOpponent(); - target.setNotTarget(true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class CardsInChosenPlayerHandCount implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { if (sourceAbility != null) { - UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + "_player"); + UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + ChooseOpponentEffect.VALUE_KEY); Player chosenPlayer = game.getPlayer(playerId); if (chosenPlayer != null) { return chosenPlayer.getHand().size(); diff --git a/Mage.Sets/src/mage/sets/conflux/PathToExile.java b/Mage.Sets/src/mage/sets/conflux/PathToExile.java index bc78ddb72ef..63f6a0c889a 100644 --- a/Mage.Sets/src/mage/sets/conflux/PathToExile.java +++ b/Mage.Sets/src/mage/sets/conflux/PathToExile.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.sets.conflux; import java.util.UUID; @@ -52,7 +51,7 @@ public class PathToExile extends CardImpl { public PathToExile(UUID ownerId) { super(ownerId, 15, "Path to Exile", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{W}"); - this.expansionSetCode = "CON"; + this.expansionSetCode = "CON"; // Exile target creature. Its controller may search his or her library for a basic land card, // put that card onto the battlefield tapped, then shuffle his or her library. @@ -93,13 +92,13 @@ class PathToExileEffect extends OneShotEffect { if (controller != null && permanent != null) { Player player = game.getPlayer(permanent.getControllerId()); // if the zone change to exile gets replaced does not prevent the target controller to be able to search - controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); + controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); if (player.chooseUse(Outcome.PutCardInPlay, "Search your library for a basic land card?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { Card card = player.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } } player.shuffleLibrary(game); diff --git a/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java b/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java index 09778edade8..e70912fe986 100644 --- a/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java +++ b/Mage.Sets/src/mage/sets/conflux/SkywardEyeProphets.java @@ -106,9 +106,9 @@ public class SkywardEyeProphets extends CardImpl { cards.add(card); controller.revealCards(sourceObject.getName(), cards, game); if (card.getCardType().contains(CardType.LAND)) { - return controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - controller.moveCards(card, null, Zone.HAND, source, game); + controller.moveCards(card, Zone.HAND, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java b/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java index 97809e24314..3ca79dcdde7 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java +++ b/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java @@ -103,7 +103,7 @@ class AcademyEliteEffect1 extends OneShotEffect { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { CardsInAllGraveyardsCount instantsAndSorceries = new CardsInAllGraveyardsCount(new FilterInstantOrSorceryCard("instant or sorcery cards")); int instantsAndSorceriesCount = instantsAndSorceries.calculate(game, source, this); if (instantsAndSorceriesCount > 0) { diff --git a/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java b/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java index e9d62fe6ab5..05b0faad94c 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java +++ b/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java @@ -34,13 +34,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -50,7 +49,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -73,8 +71,7 @@ public class DackFayden extends CardImpl { this.expansionSetCode = "CNS"; this.subtype.add("Dack"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Target player draws two cards, then discards two cards. LoyaltyAbility ability = new LoyaltyAbility(new DrawCardTargetEffect(2), 1); @@ -83,14 +80,14 @@ public class DackFayden extends CardImpl { ability.addEffect(effect); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - + // -2: Gain control of target artifact. effect = new GainControlTargetEffect(Duration.EndOfGame, true); effect.setText("Gain control of target artifact"); ability = new LoyaltyAbility(effect, -2); ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); - + // -6: You get an emblem with "Whenever you cast a spell that targets one or more permanents, gain control of those permanents." effect = new GetEmblemEffect(new DackFaydenEmblem()); effect.setText("You get an emblem with \"Whenever you cast a spell that targets one or more permanents, gain control of those permanents.\""); @@ -109,7 +106,7 @@ public class DackFayden extends CardImpl { } class DackFaydenEmblem extends Emblem { - + DackFaydenEmblem() { this.setName("EMBLEM: Dack Fayden"); this.getAbilities().add(new DackFaydenEmblemTriggeredAbility()); @@ -117,15 +114,15 @@ class DackFaydenEmblem extends Emblem { } class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { - + DackFaydenEmblemTriggeredAbility() { super(Zone.COMMAND, new DackFaydenEmblemEffect(), false); } - + DackFaydenEmblemTriggeredAbility(final DackFaydenEmblemTriggeredAbility ability) { super(ability); } - + @Override public DackFaydenEmblemTriggeredAbility copy() { return new DackFaydenEmblemTriggeredAbility(this); @@ -135,7 +132,7 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == EventType.SPELL_CAST; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { boolean returnValue = false; @@ -175,7 +172,7 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { } return returnValue; } - + @Override public String getRule() { return "Whenever you cast a spell that targets one or more permanents, gain control of those permanents."; @@ -183,24 +180,24 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { } class DackFaydenEmblemEffect extends ContinuousEffectImpl { - + protected List permanents; - + DackFaydenEmblemEffect() { super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); this.staticText = "gain control of those permanents"; } - + DackFaydenEmblemEffect(final DackFaydenEmblemEffect effect) { super(effect); this.permanents = effect.permanents; } - + @Override public DackFaydenEmblemEffect copy() { return new DackFaydenEmblemEffect(this); } - + @Override public boolean apply(Game game, Ability source) { for (UUID permanentId : this.permanents) { @@ -211,7 +208,7 @@ class DackFaydenEmblemEffect extends ContinuousEffectImpl { } return true; } - + public void setPermanents(List targettedPermanents) { this.permanents = new ArrayList<>(targettedPermanents); } diff --git a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java index 9b30e45ef2c..4fe08b08edc 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java +++ b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java @@ -30,7 +30,6 @@ package mage.sets.conspiracy; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -114,17 +113,16 @@ class ExtractFromDarknessReturnFromGraveyardToBattlefieldEffect extends OneShotE @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Target target = new TargetCardInGraveyard(new FilterCreatureCard()); target.setNotTarget(true); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && player.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + && controller.chooseTarget(outcome, target, source, game)) { + return controller.moveCards(game.getCard(target.getFirstTarget()), Zone.BATTLEFIELD, source, game); } return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/GrenzoDungeonWarden.java b/Mage.Sets/src/mage/sets/conspiracy/GrenzoDungeonWarden.java index 2a152f5c5d6..855d62758c7 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/GrenzoDungeonWarden.java +++ b/Mage.Sets/src/mage/sets/conspiracy/GrenzoDungeonWarden.java @@ -106,7 +106,7 @@ class GrenzoDungeonWardenEffect extends OneShotEffect { if (card.getCardType().contains(CardType.CREATURE)) { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (sourcePermanent != null && card.getPower().getValue() <= sourcePermanent.getPower().getValue()) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java b/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java index 71a562bab0f..437601df097 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java +++ b/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java @@ -99,14 +99,14 @@ class MuzzioVisionaryArchitectEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player == null || sourcePermanent == null) { + if (controller == null || sourcePermanent == null) { return false; } int highCMC = 0; - List controlledArtifacts = game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), player.getId(), game); + List controlledArtifacts = game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), controller.getId(), game); for (Permanent permanent : controlledArtifacts) { if (permanent.getSpellAbility() != null) { int cmc = permanent.getSpellAbility().getManaCosts().convertedManaCost(); @@ -119,26 +119,26 @@ class MuzzioVisionaryArchitectEffect extends OneShotEffect { Cards cards = new CardsImpl(); for (int i = 0; i < highCMC; i++) { - Card card = player.getLibrary().removeFromTop(game); + Card card = controller.getLibrary().removeFromTop(game); if (card != null) { cards.add(card); } } - player.lookAtCards(sourcePermanent.getName(), cards, game); + controller.lookAtCards(sourcePermanent.getIdName(), cards, game); if (!cards.isEmpty()) { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterArtifactCard("artifact card to put onto the battlefield")); - if (target.canChoose(source.getSourceId(), player.getId(), game) && player.choose(Outcome.Benefit, cards, target, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.choose(Outcome.Benefit, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { - player.revealCards(sourcePermanent.getName(), new CardsImpl(card), game); + controller.revealCards(sourcePermanent.getIdName(), new CardsImpl(card), game); cards.remove(card); - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/Victimize.java b/Mage.Sets/src/mage/sets/conspiracy/Victimize.java index 5f8a7bf3fc4..a49a512c2d3 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/Victimize.java +++ b/Mage.Sets/src/mage/sets/conspiracy/Victimize.java @@ -31,8 +31,8 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -70,36 +70,32 @@ public class Victimize extends CardImpl { } class VictimizeEffect extends OneShotEffect { - + VictimizeEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Choose two target creature cards in your graveyard. Sacrifice a creature. If you do, return the chosen cards to the battlefield tapped"; } - + VictimizeEffect(final VictimizeEffect effect) { super(effect); } - + @Override public VictimizeEffect copy() { return new VictimizeEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { SacrificeTargetCost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("a creature"))); if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) { - for (UUID targetId: getTargetPointer().getTargets(game, source)) { - Card card = game.getCard(targetId); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), true); - } - } + controller.moveCards(new CardsImpl(getTargetPointer().getTargets(game, source)).getCards(game), + Zone.BATTLEFIELD, source, game, true, false, false, null); } return true; } return false; - } + } } diff --git a/Mage.Sets/src/mage/sets/darkascension/MikaeusTheUnhallowed.java b/Mage.Sets/src/mage/sets/darkascension/MikaeusTheUnhallowed.java index 99831fe3acc..6b0ca36525a 100644 --- a/Mage.Sets/src/mage/sets/darkascension/MikaeusTheUnhallowed.java +++ b/Mage.Sets/src/mage/sets/darkascension/MikaeusTheUnhallowed.java @@ -28,10 +28,6 @@ package mage.sets.darkascension; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; @@ -41,6 +37,10 @@ import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.IntimidateAbility; import mage.abilities.keyword.UndyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -74,6 +74,7 @@ public class MikaeusTheUnhallowed extends CardImpl { this.addAbility(IntimidateAbility.getInstance()); // Whenever a Human deals damage to you, destroy it. this.addAbility(new MikaeusTheUnhallowedAbility()); + // Other non-Human creatures you control get +1/+1 and have undying. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new UndyingAbility(), Duration.WhileOnBattlefield, filter, true))); @@ -109,7 +110,6 @@ class MikaeusTheUnhallowedAbility extends TriggeredAbilityImpl { return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; } - @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getTargetId().equals(this.controllerId)) { diff --git a/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java b/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java index d351fa80033..f5a89e1c6dc 100644 --- a/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java +++ b/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java @@ -27,25 +27,24 @@ */ package mage.sets.darkascension; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.LifelinkAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -56,8 +55,6 @@ import mage.game.permanent.token.Token; import mage.players.Player; import mage.target.TargetPermanent; -import java.util.UUID; - /** * * @author BetaSteward @@ -77,8 +74,7 @@ public class SorinLordOfInnistrad extends CardImpl { this.expansionSetCode = "DKA"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Put a 1/1 black Vampire creature token with lifelink onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new VampireToken()), 1)); @@ -103,6 +99,7 @@ public class SorinLordOfInnistrad extends CardImpl { } class VampireToken extends Token { + VampireToken() { super("Vampire", "a 1/1 black Vampire creature token with lifelink"); cardType.add(CardType.CREATURE); @@ -142,7 +139,7 @@ class SorinLordOfInnistradEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (UUID targetId: source.getTargets().get(0).getTargets()) { + for (UUID targetId : source.getTargets().get(0).getTargets()) { Permanent perm = game.getPermanent(targetId); if (perm != null) { perm.destroy(source.getSourceId(), game, false); @@ -150,7 +147,7 @@ class SorinLordOfInnistradEffect extends OneShotEffect { } Player player = game.getPlayer(source.getControllerId()); if (player != null) { - for (UUID targetId: source.getTargets().get(0).getTargets()) { + for (UUID targetId : source.getTargets().get(0).getTargets()) { if (game.getState().getZone(targetId) == Zone.GRAVEYARD) { Card card = game.getCard(targetId); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java index baa5d24d1c4..8c1332a991b 100644 --- a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java +++ b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java @@ -28,11 +28,6 @@ package mage.sets.darksteel; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.TargetController; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -41,6 +36,11 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.common.FilterCreatureCard; @@ -107,18 +107,20 @@ class AEtherVialEffect extends OneShotEffect { filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, count)); String choiceText = "Put a " + filter.getMessage() + " from your hand onto the battlefield?"; - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getHand().count(filter, game) == 0 - || !player.chooseUse(this.outcome, choiceText, source, game)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } + if (controller.getHand().count(filter, game) == 0 + || !controller.chooseUse(this.outcome, choiceText, source, game)) { + return true; + } TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { + if (controller.choose(this.outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - return true; + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return false; diff --git a/Mage.Sets/src/mage/sets/darksteel/Reshape.java b/Mage.Sets/src/mage/sets/darksteel/Reshape.java index 28303ac7d8d..c1472d3c268 100644 --- a/Mage.Sets/src/mage/sets/darksteel/Reshape.java +++ b/Mage.Sets/src/mage/sets/darksteel/Reshape.java @@ -28,15 +28,14 @@ package mage.sets.darksteel; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterCard; @@ -64,7 +63,6 @@ public class Reshape extends CardImpl { super(ownerId, 31, "Reshape", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{U}{U}"); this.expansionSetCode = "DST"; - // As an additional cost to cast Reshape, sacrifice an artifact. this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); // Search your library for an artifact card with converted mana cost X or less and put it onto the battlefield. Then shuffle your library. @@ -94,8 +92,8 @@ class ReshapeSearchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } //Set the mana cost one higher to 'emulate' a less than or equal to comparison. @@ -104,17 +102,17 @@ class ReshapeSearchEffect extends OneShotEffect { filter.add(new CardTypePredicate(CardType.ARTIFACT)); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, xValue)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } diff --git a/Mage.Sets/src/mage/sets/darksteel/SurestrikeTrident.java b/Mage.Sets/src/mage/sets/darksteel/SurestrikeTrident.java new file mode 100644 index 00000000000..b3606a11a03 --- /dev/null +++ b/Mage.Sets/src/mage/sets/darksteel/SurestrikeTrident.java @@ -0,0 +1,144 @@ +/* + * 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.sets.darksteel; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPlayer; + +/** + * + * @author AlumiuN + */ +public class SurestrikeTrident extends CardImpl { + + public SurestrikeTrident(UUID ownerId) { + super(ownerId, 147, "Surestrike Trident", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "DST"; + this.subtype.add("Equipment"); + + // Equipped creature has first strike and "{T}, Unattach Surestrike Trident: This creature deals damage equal to its power to target player." + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT)); + DynamicValue xValue = new SourcePermanentPowerCount(); + Effect effect = new DamageTargetEffect(xValue); + effect.setText("This creature deals damage equal to its power to target player"); + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + gainedAbility.addTarget(new TargetPlayer()); + gainedAbility.addCost(new SurestrikeTridentUnattachCost(getName(), getId())); + effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.EQUIPMENT); + effect.setText("and \"{T}, Unattach {this}: This creature deals damage equal to its power to target player.\""); + ability.addEffect(effect); + this.addAbility(ability); + + // Equip {4} + this.addAbility(new EquipAbility(Outcome.Benefit, new GenericManaCost(4))); + } + + public SurestrikeTrident(final SurestrikeTrident card) { + super(card); + } + + @Override + public SurestrikeTrident copy() { + return new SurestrikeTrident(this); + } +} + +class SurestrikeTridentUnattachCost extends CostImpl { + + protected UUID sourceEquipmentId; + + public SurestrikeTridentUnattachCost(String name, UUID sourceId) { + this.text = "Unattach " + name; + this.sourceEquipmentId = sourceId; + } + + public SurestrikeTridentUnattachCost(final SurestrikeTridentUnattachCost cost) { + super(cost); + this.sourceEquipmentId = cost.sourceEquipmentId; + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { + Permanent permanent = game.getPermanent(sourceId); + if (permanent != null) { + for (UUID attachmentId : permanent.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.getId().equals(sourceEquipmentId)) { + paid = permanent.removeAttachment(attachmentId, game); + if (paid) { + break; + } + } + } + + } + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Permanent permanent = game.getPermanent(sourceId); + if (permanent != null) { + for (UUID attachmentId : permanent.getAttachments()) { + Permanent attachment = game.getPermanent(attachmentId); + if (attachment != null && attachment.getId().equals(sourceEquipmentId)) { + return true; + } + } + + } + return false; + } + + @Override + public SurestrikeTridentUnattachCost copy() { + return new SurestrikeTridentUnattachCost(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/dissension/CryptChampion.java b/Mage.Sets/src/mage/sets/dissension/CryptChampion.java index 894a5fdff35..7d29bfdf552 100644 --- a/Mage.Sets/src/mage/sets/dissension/CryptChampion.java +++ b/Mage.Sets/src/mage/sets/dissension/CryptChampion.java @@ -69,10 +69,10 @@ public class CryptChampion extends CardImpl { // Double strike this.addAbility(DoubleStrikeAbility.getInstance()); - + // When Crypt Champion enters the battlefield, each player puts a creature card with converted mana cost 3 or less from his or her graveyard onto the battlefield. this.addAbility(new EntersBattlefieldTriggeredAbility(new CryptChampionEffect())); - + // When Crypt Champion enters the battlefield, sacrifice it unless {R} was spent to cast it. this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessConditionEffect(new ManaWasSpentCondition(ColoredManaSymbol.R)), false), new ManaSpentToCastWatcher()); } @@ -88,26 +88,26 @@ public class CryptChampion extends CardImpl { } class CryptChampionEffect extends OneShotEffect { - + CryptChampionEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "each player puts a creature card with converted mana cost 3 or less from his or her graveyard onto the battlefield"; } - + CryptChampionEffect(final CryptChampionEffect effect) { super(effect); } - + @Override public CryptChampionEffect copy() { return new CryptChampionEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId : controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { FilterCard filter = new FilterCreatureCard("creature card with converted mana cost 3 or less from your graveyard"); @@ -117,7 +117,7 @@ class CryptChampionEffect extends OneShotEffect { if (target.canChoose(playerId, game) && player.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + player.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/dissension/FlaringFlameKin.java b/Mage.Sets/src/mage/sets/dissension/FlaringFlameKin.java index c8b77cfc298..1cfe02e7dc6 100644 --- a/Mage.Sets/src/mage/sets/dissension/FlaringFlameKin.java +++ b/Mage.Sets/src/mage/sets/dissension/FlaringFlameKin.java @@ -29,9 +29,9 @@ package mage.sets.dissension; import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.EnchantedCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; @@ -50,10 +50,6 @@ import mage.constants.Zone; */ public class FlaringFlameKin extends CardImpl { - private static final String rule1 = "As long as {this} is enchanted, it gets +2/+2"; - private static final String rule2 = "As long as {this} is enchanted, it has trample"; - private static final String rule3 = "As long as {this} is enchanted, it has \"{R}: {this} gets +1/+0 until end of turn.\""; - public FlaringFlameKin(UUID ownerId) { super(ownerId, 62, "Flaring Flame-Kin", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); this.expansionSetCode = "DIS"; @@ -63,17 +59,19 @@ public class FlaringFlameKin extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - SimpleActivatedAbility grantedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BoostSourceEffect(1, 0, Duration.EndOfTurn), - new ManaCostsImpl("{R}")); - - Condition enchanted = new EnchantedCondition(); - ConditionalContinuousEffect effect1 = new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), enchanted, rule1); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect1)); - ConditionalContinuousEffect effect2 = new ConditionalContinuousEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance()), enchanted, rule2); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect2)); - ConditionalContinuousEffect effect3 = new ConditionalContinuousEffect(new GainAbilitySourceEffect(grantedAbility), enchanted, rule3); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect3)); + // As long as Flaring Flame-Kin is enchanted, it gets +2/+2, has trample, and has "{R}: Flaring Flame-Kin gets +1/+0 until end of turn." + EnchantedCondition enchanted = new EnchantedCondition(); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), enchanted, + "As long as {this} is enchanted, it gets +2/+2")); + ability.addEffect(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(TrampleAbility.getInstance()), enchanted, + ", has trample")); + Ability grantedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl("{R}")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(grantedAbility), + enchanted, ", and has \"{R}: {this} gets +1/+0 until end of turn.\"")); + this.addAbility(ability); } public FlaringFlameKin(final FlaringFlameKin card) { diff --git a/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java b/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java index 4a7804b3443..064145d1981 100644 --- a/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java +++ b/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java @@ -78,47 +78,42 @@ public class ProteanHulk extends CardImpl { } class ProteanHulkEffect extends OneShotEffect { - + ProteanHulkEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "search your library for any number of creature cards with total converted mana cost 6 or less and put them onto the battlefield. Then shuffle your library"; } - + ProteanHulkEffect(final ProteanHulkEffect effect) { super(effect); } - + @Override public ProteanHulkEffect copy() { return new ProteanHulkEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Cards cardsPicked = this.ProteanHulkSearch(game, source); - for (UUID cardId : cardsPicked) { - Card card = game.getCard(cardId); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.PICK, source.getSourceId()); - } - } - player.shuffleLibrary(game); + controller.moveCards(cardsPicked.getCards(game), Zone.BATTLEFIELD, source, game); + controller.shuffleLibrary(game); return true; } return false; } - + Cards ProteanHulkSearch(Game game, Ability source) { - Cards cardsPicked = new CardsImpl(Zone.PICK); + Cards cardsPicked = new CardsImpl(Zone.LIBRARY); Player player = game.getPlayer(source.getControllerId()); if (player != null) { GameEvent event = GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, source.getControllerId(), source.getControllerId(), source.getControllerId(), Integer.MAX_VALUE); if (!game.replaceEvent(event)) { int manaCostLeftToFetch = 6; int librarySearchLimit = event.getAmount(); - + FilterCard filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (6 CMC left)"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); @@ -131,15 +126,14 @@ class ProteanHulkEffect extends OneShotEffect { break; } cardsPicked.add(card); - game.setZone(card.getId(), Zone.PICK); game.getState().getLookedAt(source.getControllerId()).add("Protean Hulk", cardsPicked); - + librarySearchLimit--; if (librarySearchLimit == 0) { break; } manaCostLeftToFetch -= card.getManaCost().convertedManaCost(); - filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less ("+ manaCostLeftToFetch +" CMC left)"); + filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (" + manaCostLeftToFetch + " CMC left)"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); target = new TargetCardInLibrary(0, 1, filter); target.setCardLimit(librarySearchLimit); diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java b/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java index 45ce77a9176..d79ba674371 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.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.sets.dragonsmaze; import java.util.UUID; @@ -39,13 +38,11 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; -import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.permanent.token.BirdToken; - - public class BeckCall extends SplitCard { public BeckCall(UUID ownerId) { @@ -58,7 +55,7 @@ public class BeckCall extends SplitCard { // Call // Put four 1/1 white Bird creature tokens with flying onto the battlefield. - getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new BirdToken(),4)); + getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new BirdToken(), 4)); } @@ -94,10 +91,7 @@ class BeckTriggeredAbility extends DelayedTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - return true; - } - return false; + return filter.match(permanent, getSourceId(), getControllerId(), game); } @Override diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/BloodBaronOfVizkopa.java b/Mage.Sets/src/mage/sets/dragonsmaze/BloodBaronOfVizkopa.java index 24af9bc9355..d675c36e768 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/BloodBaronOfVizkopa.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/BloodBaronOfVizkopa.java @@ -25,17 +25,9 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.dragonsmaze; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.ObjectColor; import mage.abilities.Ability; @@ -45,6 +37,13 @@ import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.ProtectionAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; @@ -52,27 +51,21 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -/** - * - * @author LevelX2 - */ - - public class BloodBaronOfVizkopa extends CardImpl { private static final FilterCard filter = new FilterCard("white and from black"); + static { filter.add(Predicates.or( new ColorPredicate(ObjectColor.WHITE), new ColorPredicate(ObjectColor.BLACK))); } - public BloodBaronOfVizkopa (UUID ownerId) { + public BloodBaronOfVizkopa(UUID ownerId) { super(ownerId, 57, "Blood Baron of Vizkopa", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{W}{B}"); this.expansionSetCode = "DGM"; this.subtype.add("Vampire"); - this.power = new MageInt(4); this.toughness = new MageInt(4); @@ -85,7 +78,7 @@ public class BloodBaronOfVizkopa extends CardImpl { } - public BloodBaronOfVizkopa (final BloodBaronOfVizkopa card) { + public BloodBaronOfVizkopa(final BloodBaronOfVizkopa card) { super(card); } @@ -97,7 +90,7 @@ public class BloodBaronOfVizkopa extends CardImpl { } class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl { - + public BloodBaronOfVizkopaEffect() { super(Duration.WhileOnBattlefield, Outcome.BoostCreature); staticText = "As long as you have 30 or more life and an opponent has 10 or less life, {this} gets +6/+6 and has flying"; @@ -117,21 +110,21 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl { if (conditionState(source, game)) { Permanent creature = game.getPermanent(source.getSourceId()); if (creature != null) { - switch (layer) { - case PTChangingEffects_7: - if (sublayer == SubLayer.ModifyPT_7c) { - creature.addPower(6); - creature.addToughness(6); - } - break; - case AbilityAddingRemovingEffects_6: - if (sublayer == SubLayer.NA) { - creature.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game); - } - break; - default: - } - return true; + switch (layer) { + case PTChangingEffects_7: + if (sublayer == SubLayer.ModifyPT_7c) { + creature.addPower(6); + creature.addToughness(6); + } + break; + case AbilityAddingRemovingEffects_6: + if (sublayer == SubLayer.NA) { + creature.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game); + } + break; + default: + } + return true; } } return false; @@ -140,10 +133,12 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl { protected boolean conditionState(Ability source, Game game) { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.getLife() >= 30) { - for (UUID opponentId :player.getInRange()) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null && opponent.getLife() < 11) { - return true; + for (UUID opponentId : player.getInRange()) { + if (player.hasOpponent(opponentId, game)) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null && opponent.getLife() < 11) { + return true; + } } } } @@ -159,6 +154,6 @@ class BloodBaronOfVizkopaEffect extends ContinuousEffectImpl { public boolean hasLayer(Layer layer) { return (layer.equals(Layer.AbilityAddingRemovingEffects_6) || layer.equals(layer.PTChangingEffects_7)); - } + } } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java index 0553d75993b..9df44c4d7df 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java @@ -30,18 +30,16 @@ package mage.sets.dragonsmaze; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.TokenPredicate; @@ -72,17 +70,16 @@ public class ProgenitorMimic extends CardImpl { // put a token onto the battlefield that's a copy of this creature." Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); effect.setText("put a token onto the battlefield that's a copy of this creature"); + AbilityApplier applier = new AbilityApplier( new ConditionalTriggeredAbility( new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, false), new SourceMatchesFilterCondition(filter), "At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.") ); - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(applier), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains \"At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.\"", - true))); + effect = new CopyPermanentEffect(); + effect.setText("as a copy of any creature on the battlefield except it gains \"At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.\""); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(applier), true)); } public ProgenitorMimic(final ProgenitorMimic card) { diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java b/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java index 829bc093bde..121946e99aa 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java @@ -28,17 +28,15 @@ package mage.sets.dragonsmaze; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -58,8 +56,7 @@ public class RalZarek extends CardImpl { this.expansionSetCode = "DGM"; this.subtype.add("Ral"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Tap target permanent, then untap another target permanent. LoyaltyAbility ability1 = new LoyaltyAbility(new RalZarekTapUntapEffect(), 1); @@ -86,7 +83,6 @@ public class RalZarek extends CardImpl { } } - class RalZarekTapUntapEffect extends OneShotEffect { public RalZarekTapUntapEffect() { @@ -112,10 +108,10 @@ class RalZarekTapUntapEffect extends OneShotEffect { i++; Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - if (i==1) { + if (i == 1) { permanent.tap(game); } - if (i==2) { + if (i == 2) { permanent.untap(game); } } @@ -146,7 +142,7 @@ class RalZarekExtraTurnsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (int i=0; i<5; i++) { + for (int i = 0; i < 5; i++) { if (controller.flipCoin(game)) { game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false)); } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/VoiceOfResurgence.java b/Mage.Sets/src/mage/sets/dragonsmaze/VoiceOfResurgence.java index 8bebbae8f2e..6e76865f938 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/VoiceOfResurgence.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/VoiceOfResurgence.java @@ -104,7 +104,7 @@ class VoiceOfResurgenceTriggeredAbility extends TriggeredAbilityImpl { return true; } } - // Voice Of Resurgence Dies + // Voice of Resurgence Dies if (event.getType() == GameEvent.EventType.ZONE_CHANGE && getSourceId().equals(event.getTargetId())) { ZoneChangeEvent zce = (ZoneChangeEvent) event; return zce.getFromZone().equals(Zone.BATTLEFIELD) && zce.getToZone().equals(Zone.GRAVEYARD); diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java index 098a319ff68..629a1e35e6a 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/DeathmistRaptor.java @@ -101,9 +101,9 @@ class DeathmistRaptorEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObjectIfItStillExists(game); if (controller != null && (sourceObject instanceof Card)) { - controller.putOntoBattlefieldWithInfo((Card) sourceObject, game, Zone.GRAVEYARD, source.getSourceId(), false, - controller.chooseUse(Outcome.Detriment, "Return " + sourceObject.getLogName() + " face down to battlefield (otherwise face up)?", source, game)); - return true; + return controller.moveCards((Card) sourceObject, Zone.BATTLEFIELD, source, game, false, + controller.chooseUse(Outcome.Detriment, "Return " + sourceObject.getLogName() + " face down to battlefield (otherwise face up)?", source, game), + false, null); } return false; } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java index 639d3f36c38..3873609cb39 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java @@ -32,7 +32,7 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; @@ -40,7 +40,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.ReboundAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -52,7 +51,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -71,7 +69,7 @@ public class NarsetTranscendent extends CardImpl { this.expansionSetCode = "DTK"; this.subtype.add("Narset"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); // +1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand. this.addAbility(new LoyaltyAbility(new NarsetTranscendentEffect1(), 1)); diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java index 095e054558d..ccd28a1c476 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java @@ -33,10 +33,9 @@ import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.choices.Choice; @@ -44,7 +43,6 @@ import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; @@ -69,7 +67,7 @@ public class SarkhanUnbroken extends CardImpl { this.expansionSetCode = "DTK"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Draw a card, then add one mana of any color to your mana pool. this.addAbility(new LoyaltyAbility(new SarkhanUnbrokenAbility1(), 1)); @@ -127,7 +125,7 @@ class SarkhanUnbrokenAbility1 extends OneShotEffect { Mana mana = new Mana(); controller.choose(Outcome.Benefit, manaChoice, game); - + if (manaChoice.getChoice() == null) { return false; } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java index 7cf4b87280b..bfd5b48ff0d 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SwiftWarkite.java @@ -122,7 +122,7 @@ class SwiftWarkiteEffect extends OneShotEffect { controller.choose(outcome, target, source.getSourceId(), game); Card card = controller.getHand().get(target.getFirstTarget(), game); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent creature = game.getPermanent(card.getId()); if (creature != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); @@ -143,7 +143,7 @@ class SwiftWarkiteEffect extends OneShotEffect { target.choose(Outcome.PutCardInPlay, source.getControllerId(), source.getSourceId(), game); Card card = controller.getGraveyard().get(target.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); Permanent creature = game.getPermanent(card.getId()); if (creature != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); diff --git a/Mage.Sets/src/mage/sets/elvesvsgoblins/SkirkDrillSergeant.java b/Mage.Sets/src/mage/sets/elvesvsgoblins/SkirkDrillSergeant.java index 55756cd3dbf..c5abcd76b27 100644 --- a/Mage.Sets/src/mage/sets/elvesvsgoblins/SkirkDrillSergeant.java +++ b/Mage.Sets/src/mage/sets/elvesvsgoblins/SkirkDrillSergeant.java @@ -37,7 +37,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -108,23 +107,20 @@ class SkirkDrillSergeantEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (player == null || sourceObject == null) { + if (controller == null || sourceObject == null) { return false; } - if (player.getLibrary().size() > 0) { - Card card = player.getLibrary().getFromTop(game); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards(sourceObject.getName(), cards, game); - + if (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().getFromTop(game); + controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); if (card != null) { if (filter.match(card, game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java b/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java index 5b8107dd5f1..3af4a21d774 100644 --- a/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java +++ b/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java @@ -61,11 +61,7 @@ public class CankerAbomination extends CardImpl { this.toughness = new MageInt(6); // As Canker Abomination enters the battlefield, choose an opponent. Canker Abomination enters the battlefield with a -1/-1 counter on it for each creature that player controls. - Ability ability = new AsEntersBattlefieldAbility(new CankerAbominationEffect()); - Target target = new TargetOpponent(); - target.setNotTarget(true); - ability.addTarget(target); - this.addAbility(ability); + this.addAbility(new AsEntersBattlefieldAbility(new CankerAbominationEffect())); } @@ -97,14 +93,19 @@ class CankerAbominationEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent CankerAbomination = game.getPermanent(source.getSourceId()); - if (player != null && CankerAbomination != null) { - Player chosenPlayer = game.getPlayer(source.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(CankerAbomination.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - int amount = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), chosenPlayer.getId(), game).size(); - CankerAbomination.addCounters(CounterType.M1M1.createInstance(amount), game); + Player controller = game.getPlayer(source.getControllerId()); + Permanent cankerAbomination = game.getPermanentEntering(source.getSourceId()); + if (controller != null && cankerAbomination != null) { + Target target = new TargetOpponent(); + target.setNotTarget(true); + controller.choose(outcome, target, source.getSourceId(), game); + Player opponent = game.getPlayer(target.getFirstTarget()); + if (opponent != null) { + game.informPlayers(cankerAbomination.getName() + ": " + controller.getLogName() + " has chosen " + opponent.getLogName()); + int amount = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), opponent.getId(), game).size(); + if (amount > 0) { + cankerAbomination.addCounters(CounterType.M1M1.createInstance(amount), game); + } return true; } } diff --git a/Mage.Sets/src/mage/sets/exodus/EntropicSpecter.java b/Mage.Sets/src/mage/sets/exodus/EntropicSpecter.java index 1e5348392f8..b2e6ebf7cca 100644 --- a/Mage.Sets/src/mage/sets/exodus/EntropicSpecter.java +++ b/Mage.Sets/src/mage/sets/exodus/EntropicSpecter.java @@ -27,6 +27,7 @@ */ package mage.sets.exodus; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -34,18 +35,18 @@ import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseOpponentEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetOpponent; - -import java.util.UUID; /** * @@ -64,13 +65,13 @@ public class EntropicSpecter extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // As Entropic Specter enters the battlefield, choose an opponent. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponent())); - + this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.Detriment))); + // Entropic Specter's power and toughness are each equal to the number of cards in the chosen player's hand. this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInTargetPlayerHandCount(), Duration.WhileOnBattlefield))); - + // Whenever Entropic Specter deals damage to a player, that player discards a card. this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1, false), false, true)); } @@ -85,47 +86,12 @@ public class EntropicSpecter extends CardImpl { } } -class ChooseOpponent extends OneShotEffect { - - public ChooseOpponent() { - super(Outcome.Neutral); - this.staticText = "choose an opponent"; - } - - public ChooseOpponent(final ChooseOpponent effect) { - super(effect); - } - - @Override - public ChooseOpponent copy() { - return new ChooseOpponent(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetOpponent target = new TargetOpponent(); - target.setNotTarget(true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class CardsInTargetPlayerHandCount implements DynamicValue { + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { if (sourceAbility != null) { - UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + "_player"); + UUID playerId = (UUID) game.getState().getValue(sourceAbility.getSourceId() + ChooseOpponentEffect.VALUE_KEY); Player chosenPlayer = game.getPlayer(playerId); if (chosenPlayer != null) { return chosenPlayer.getHand().size(); diff --git a/Mage.Sets/src/mage/sets/exodus/OathOfDruids.java b/Mage.Sets/src/mage/sets/exodus/OathOfDruids.java index e08f682393c..e613109d666 100644 --- a/Mage.Sets/src/mage/sets/exodus/OathOfDruids.java +++ b/Mage.Sets/src/mage/sets/exodus/OathOfDruids.java @@ -65,7 +65,6 @@ public class OathOfDruids extends CardImpl { super(ownerId, 115, "Oath of Druids", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.expansionSetCode = "EXO"; - // At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is his or her opponent. The first player may reveal cards from the top of his or her library until he or she reveals a creature card. If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into his or her graveyard. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfDruidsEffect(), TargetController.ANY, true); ability.addTarget(new TargetPlayer(1, 1, false, filter)); @@ -136,32 +135,32 @@ class OathOfDruidsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { MageObject sourceObject = game.getObject(source.getSourceId()); - Player player = game.getPlayer(source.getControllerId()); - if (player == null || sourceObject == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || sourceObject == null) { return false; } Cards revealed = new CardsImpl(); Card creatureCard = null; Cards nonCreatureCards = new CardsImpl(); //The first player may reveal cards from the top of his or her library - while (creatureCard == null && player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + while (creatureCard == null && controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); revealed.add(card); - // until he or she reveals a creature card. + // until he or she reveals a creature card. if (card.getCardType().contains(CardType.CREATURE)) { creatureCard = card; } else { nonCreatureCards.add(card); } } - player.revealCards(sourceObject.getName(), revealed, game); + controller.revealCards(sourceObject.getIdName(), revealed, game); //If he or she does, that player puts that card onto the battlefield if (creatureCard != null) { - player.putOntoBattlefieldWithInfo(creatureCard, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(creatureCard, Zone.BATTLEFIELD, source, game); } // and all other cards revealed this way into his or her graveyard - player.moveCards(nonCreatureCards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(nonCreatureCards, Zone.GRAVEYARD, source, game); return true; } diff --git a/Mage.Sets/src/mage/sets/exodus/OathOfLieges.java b/Mage.Sets/src/mage/sets/exodus/OathOfLieges.java index f11e6b7823e..ad31783661b 100644 --- a/Mage.Sets/src/mage/sets/exodus/OathOfLieges.java +++ b/Mage.Sets/src/mage/sets/exodus/OathOfLieges.java @@ -65,7 +65,7 @@ public class OathOfLieges extends CardImpl { this.expansionSetCode = "EXO"; // At the beginning of each player's upkeep, that player chooses target player who controls more lands than he or she does and is his or her opponent. The first player may search his or her library for a basic land card, put that card onto the battlefield, then shuffle his or her library. - Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(new FilterBasicLandCard()), false, Outcome.PutLandInPlay); + Effect effect = new SearchLibraryPutInPlayTargetPlayerEffect(new TargetCardInLibrary(new FilterBasicLandCard()), false, true, Outcome.PutLandInPlay, true); effect.setText("that player chooses target player who controls more lands than he or she does and is his or her opponent. The first player may search his or her library for a basic land card, put that card onto the battlefield, then shuffle his or her library"); Ability ability = new BeginningOfUpkeepTriggeredAbility(effect, TargetController.ANY, true); ability.addTarget(new TargetPlayer(1, 1, false, filter)); diff --git a/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java b/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java index 8914495c7f5..01b26cd052d 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java @@ -61,7 +61,7 @@ public class CitadelSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Citadel Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, "As {this} enters the battlefield, choose Khans or Dragons.","")); // * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control. diff --git a/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java b/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java index 9de1b018b1e..008f8a3c2c4 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java +++ b/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java @@ -53,7 +53,7 @@ public class FrontierMastodon extends CardImpl { // Ferocious - Frontier Mastodon enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - FerociousCondition.getInstance(), true, + FerociousCondition.getInstance(), "Ferocious — {this} enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater.","" )); } diff --git a/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java b/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java index f02ca1e3c0b..1a98c5c215c 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java @@ -76,7 +76,7 @@ public class FrontierSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Frontier Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of each of your main phases, add {G}{G} to your mana pool. diff --git a/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java b/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java index 333415da47a..746d4f6fe9f 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java +++ b/Mage.Sets/src/mage/sets/fatereforged/GhastlyConscription.java @@ -29,6 +29,8 @@ package mage.sets.fatereforged; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; @@ -96,15 +98,18 @@ class GhastlyConscriptionEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); if (controller != null && targetPlayer != null) { ArrayList cardsToManifest = new ArrayList<>(); - for(Card card: targetPlayer.getGraveyard().getCards(new FilterCreatureCard(), game)) { + for (Card card : targetPlayer.getGraveyard().getCards(new FilterCreatureCard(), game)) { cardsToManifest.add(card); controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD, true); } + if (cardsToManifest.isEmpty()) { + return true; + } Collections.shuffle(cardsToManifest); game.informPlayers(controller.getLogName() + " shuffles the face-down pile"); Ability newSource = source.copy(); newSource.setWorksFaceDown(true); - for (Card card: cardsToManifest) { + for (Card card : cardsToManifest) { ManaCosts manaCosts = null; if (card.getCardType().contains(CardType.CREATURE)) { manaCosts = card.getSpellAbility().getManaCosts(); @@ -112,13 +117,12 @@ class GhastlyConscriptionEffect extends OneShotEffect { manaCosts = new ManaCostsImpl("{0}"); } } - MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) +1, game); + MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), false, true)) { - game.informPlayers(new StringBuilder(controller.getLogName()) - .append(" puts facedown card from exile onto the battlefield").toString()); - } } + Set toBattlefield = new LinkedHashSet(); + toBattlefield.addAll(cardsToManifest); + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, true, false, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java b/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java index 2b64b4db950..30fc48f26c6 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java +++ b/Mage.Sets/src/mage/sets/fatereforged/JeskaiInfiltrator.java @@ -29,7 +29,9 @@ package mage.sets.fatereforged; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObjectReference; @@ -74,7 +76,7 @@ public class JeskaiInfiltrator extends CardImpl { Effect effect = new ConditionalRestrictionEffect(new CantBeBlockedSourceEffect(), new OneControlledCreatureCondition()); effect.setText("{this} can't be blocked as long as you control no other creatures"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + // Whenever Jeskai Infiltrator deals combat damage to a player, exile it and the top card of your library in a face-down pile, shuffle that pile, then manifest those cards. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new JeskaiInfiltratorEffect(), false)); } @@ -90,35 +92,35 @@ public class JeskaiInfiltrator extends CardImpl { } class JeskaiInfiltratorEffect extends OneShotEffect { - + JeskaiInfiltratorEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "exile it and the top card of your library in a face-down pile, shuffle that pile, then manifest those cards"; } - + JeskaiInfiltratorEffect(final JeskaiInfiltratorEffect effect) { super(effect); } - + @Override public JeskaiInfiltratorEffect copy() { return new JeskaiInfiltratorEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { List cardsToManifest = new ArrayList<>(2); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId()); - if (sourcePermanent != null && sourceCard != null) { - player.moveCardToExileWithInfo(sourcePermanent, sourcePermanent.getId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); + if (sourcePermanent != null && sourceCard != null) { + controller.moveCardToExileWithInfo(sourcePermanent, sourcePermanent.getId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); cardsToManifest.add(sourceCard); } - if (sourcePermanent!= null && player.getLibrary().size() > 0) { - Card cardFromLibrary = player.getLibrary().removeFromTop(game); - player.moveCardToExileWithInfo(cardFromLibrary, sourcePermanent.getId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + if (sourcePermanent != null && controller.getLibrary().size() > 0) { + Card cardFromLibrary = controller.getLibrary().removeFromTop(game); + controller.moveCardToExileWithInfo(cardFromLibrary, sourcePermanent.getId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); cardsToManifest.add(cardFromLibrary); } Collections.shuffle(cardsToManifest); @@ -133,13 +135,12 @@ class JeskaiInfiltratorEffect extends OneShotEffect { manaCosts = new ManaCostsImpl("{0}"); } } - MageObjectReference objectReference= new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) +1, game); - game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - if (player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), false, true)) { - game.informPlayers(new StringBuilder(player.getLogName()) - .append(" puts facedown card from exile onto the battlefield").toString()); - } + MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); + game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); } + Set toBattlefield = new LinkedHashSet(); + toBattlefield.addAll(cardsToManifest); + controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game, false, true, false, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java index 799cfbb802d..9753a5cf199 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java @@ -62,7 +62,7 @@ public class MonasterySiege extends CardImpl { this.expansionSetCode = "FRF"; // As Monastery Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of your draw step, draw an additional card, then discard a card. diff --git a/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java b/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java index a2598cdb69a..4ee0f6accad 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java @@ -69,7 +69,7 @@ public class OutpostSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Outpost Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card. diff --git a/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java b/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java index 3b153f3e251..d23bb16257a 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java @@ -59,7 +59,7 @@ public class PalaceSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Palace Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, "As {this} enters the battlefield, choose Khans or Dragons.","")); // * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand. diff --git a/Mage.Sets/src/mage/sets/fatereforged/RallyTheAncestors.java b/Mage.Sets/src/mage/sets/fatereforged/RallyTheAncestors.java index 100549a277a..564996f1e27 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/RallyTheAncestors.java +++ b/Mage.Sets/src/mage/sets/fatereforged/RallyTheAncestors.java @@ -46,6 +46,7 @@ import mage.filter.Filter.ComparisonType; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; @@ -99,11 +100,13 @@ class RallyTheAncestorsEffect extends OneShotEffect { FilterCreatureCard filter = new FilterCreatureCard(); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, xValue + 1)); Set cards = player.getGraveyard().getCards(filter, game); + player.moveCards(cards, Zone.BATTLEFIELD, source, game); for (Card card : cards) { if (card != null) { - if (player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { Effect exileEffect = new ExileTargetEffect("Exile those creatures at the beginning of your next upkeep"); - exileEffect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + exileEffect.setTargetPointer(new FixedTarget(permanent, game)); DelayedTriggeredAbility delayedAbility = new AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility(exileEffect); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java index d9590de8ffa..662d434e6df 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java +++ b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java @@ -97,6 +97,7 @@ class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { this.tapped = tapped; setText(); } + public ReturnSourceFromExileToBattlefieldEffect(boolean tapped, boolean ownerControl) { super(Outcome.PutCreatureInPlay); this.tapped = tapped; @@ -135,7 +136,7 @@ class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { return false; } - return player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), tapped); + return player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } private void setText() { @@ -144,7 +145,7 @@ class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { sb.append(" tapped"); } if (ownerControl) { - sb.append(" under its owner's control"); + sb.append(" under its owner's control"); } staticText = sb.toString(); } diff --git a/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java b/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java index 90ffdb0ca48..a7cbbf6bc0b 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java +++ b/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java @@ -30,19 +30,17 @@ package mage.sets.fatereforged; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter.ComparisonType; import mage.filter.FilterPermanent; import mage.filter.common.FilterPermanentCard; @@ -59,7 +57,6 @@ import mage.target.common.TargetCreatureOrPlayer; * * @author LevelX2 */ - public class UginTheSpiritDragon extends CardImpl { public UginTheSpiritDragon(UUID ownerId) { @@ -67,7 +64,7 @@ public class UginTheSpiritDragon extends CardImpl { this.expansionSetCode = "FRF"; this.subtype.add("Ugin"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(7)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(7)); // +2: Ugin, the Spirit Dragon deals 3 damage to target creature or player. LoyaltyAbility ability = new LoyaltyAbility(new DamageTargetEffect(3), 2); @@ -126,7 +123,7 @@ class UginTheSpiritDragonEffect2 extends OneShotEffect { FilterPermanent filter = new FilterPermanent("permanent with converted mana cost X or less that's one or more colors"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, cmc + 1)); filter.add(Predicates.not(new ColorlessPredicate())); - for(Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); } return true; @@ -157,12 +154,7 @@ class UginTheSpiritDragonEffect3 extends OneShotEffect { controller.drawCards(7, game); TargetCardInHand target = new TargetCardInHand(0, 7, new FilterPermanentCard("permanent cards")); if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { - for (UUID targetId: target.getTargets()) { - Card card = game.getCard(targetId); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getControllerId()); - } - } + controller.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java b/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java index 2ed36891b4a..bae08d67839 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java @@ -1,5 +1,6 @@ package mage.sets.fifthdawn; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -15,17 +16,15 @@ import mage.players.Player; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * @author andyfries */ -public class Acquire extends CardImpl{ +public class Acquire extends CardImpl { + public Acquire(UUID ownerId) { super(ownerId, 21, "Acquire", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{U}{U}"); this.expansionSetCode = "5DN"; - // Search target opponent's library for an artifact card and put that card onto the battlefield under your control. // Then that player shuffles his or her library. this.getSpellAbility().addEffect(new AcquireEffect()); @@ -68,7 +67,7 @@ class AcquireEffect extends OneShotEffect { controller.searchLibrary(target, game, opponent.getId()); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - controller.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); } opponent.shuffleLibrary(game); return true; @@ -81,4 +80,3 @@ class AcquireEffect extends OneShotEffect { return new AcquireEffect(this); } } - diff --git a/Mage.Sets/src/mage/sets/fifthdawn/EndlessWhispers.java b/Mage.Sets/src/mage/sets/fifthdawn/EndlessWhispers.java index df557686aee..2e772173bb2 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/EndlessWhispers.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/EndlessWhispers.java @@ -59,18 +59,17 @@ public class EndlessWhispers extends CardImpl { super(ownerId, 49, "Endless Whispers", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); this.expansionSetCode = "5DN"; - // Each creature has "When this creature dies, choose target opponent. That player puts this card from its owner's graveyard onto the battlefield under his or her control at the beginning of the next end step." DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnSourceToBattlefieldEffect()); Effect effect = new CreateDelayedTriggeredAbilityEffect(delayedAbility, true); effect.setText("choose target opponent. That player puts this card from its owner's graveyard onto the battlefield under his or her control at the beginning of the next end step"); Ability gainAbility = new DiesTriggeredAbility(effect); gainAbility.addTarget(new TargetOpponent()); - + effect = new GainAbilityAllEffect(gainAbility, Duration.WhileOnBattlefield, new FilterCreaturePermanent("Each creature")); effect.setText("Each creature has \"When this creature dies, choose target opponent. That player puts this card from its owner's graveyard onto the battlefield under his or her control at the beginning of the next end step.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + } public EndlessWhispers(final EndlessWhispers card) { @@ -85,18 +84,17 @@ public class EndlessWhispers extends CardImpl { class ReturnSourceToBattlefieldEffect extends OneShotEffect { - public ReturnSourceToBattlefieldEffect() { this(false); } public ReturnSourceToBattlefieldEffect(boolean tapped) { super(Outcome.PutCreatureInPlay); - setText(); + staticText = "That player puts this card from its owner's graveyard onto the battlefield under his or her control"; } + public ReturnSourceToBattlefieldEffect(boolean tapped, boolean ownerControl) { super(Outcome.PutCreatureInPlay); - setText(); } public ReturnSourceToBattlefieldEffect(final ReturnSourceToBattlefieldEffect effect) { @@ -112,24 +110,19 @@ class ReturnSourceToBattlefieldEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { if (!game.getState().getZone(source.getSourceId()).equals(Zone.GRAVEYARD)) { return false; - } + } Card card = game.getCard(source.getSourceId()); if (card == null) { return false; } - + Player player = game.getPlayer(source.getFirstTarget()); - - if (player == null) { + + if (player == null) { return false; - } - - return player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), false); + } + + return player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } - private void setText() { - StringBuilder sb = new StringBuilder("That player puts this card from its owner's graveyard onto the battlefield under his or her control"); - - } - -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/fifthdawn/MyrServitor.java b/Mage.Sets/src/mage/sets/fifthdawn/MyrServitor.java index f284a356e4c..33c27d2d941 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/MyrServitor.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/MyrServitor.java @@ -34,7 +34,6 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.common.SourceOnBattlefieldCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -66,7 +65,7 @@ public class MyrServitor extends CardImpl { SourceOnBattlefieldCondition.getInstance(), "At the beginning of your upkeep, if {this} is on the battlefield, each player returns all cards named Myr Servitor from his or her graveyard to the battlefield" )); - + } public MyrServitor(final MyrServitor card) { @@ -80,39 +79,38 @@ public class MyrServitor extends CardImpl { } class MyrServitorReturnEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("cards named Myr Servitor"); - + static { filter.add(new NamePredicate("Myr Servitor")); } - + public MyrServitorReturnEffect() { super(Outcome.PutCardInPlay); this.staticText = "if {this} is on the battlefield, each player returns all cards named Myr Servitor from his or her graveyard to the battlefield"; } - + public MyrServitorReturnEffect(final MyrServitorReturnEffect effect) { super(effect); } - + @Override public MyrServitorReturnEffect copy() { return new MyrServitorReturnEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getGraveyard().getCards(filter, game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); - } + controller.moveCards(player.getGraveyard().getCards(filter, game), Zone.BATTLEFIELD, source, game); } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/fifthedition/Kismet.java b/Mage.Sets/src/mage/sets/fifthedition/Kismet.java index 9e327b22775..a4319c15b6b 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/Kismet.java +++ b/Mage.Sets/src/mage/sets/fifthedition/Kismet.java @@ -38,6 +38,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -79,26 +80,25 @@ class KismetEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } return false; } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && (permanent.getCardType().contains(CardType.ARTIFACT) || - permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND))) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && (permanent.getCardType().contains(CardType.ARTIFACT) + || permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java index 561def505a0..9ac15c4a2c1 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java +++ b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java @@ -45,6 +45,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -65,7 +66,7 @@ public class PrimalClay extends CardImpl { this.toughness = new MageInt(0); // As Primal Clay enters the battlefield, it becomes your choice of a 3/3 artifact creature, a 2/2 artifact creature with flying, or a 1/6 Wall artifact creature with defender in addition to its other types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalPlasmaReplacementEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new PrimalPlasmaReplacementEffect())); } public PrimalClay(final PrimalClay card) { @@ -101,7 +102,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -116,7 +117,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what " + permanent.getIdName() + " becomes to"); diff --git a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java index afa1cd28900..d20b20c4158 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java +++ b/Mage.Sets/src/mage/sets/fifthedition/SylvanLibrary.java @@ -27,7 +27,9 @@ */ package mage.sets.fifthedition; -import java.util.HashSet; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; import java.util.UUID; import mage.MageObject; @@ -64,7 +66,8 @@ public class SylvanLibrary extends CardImpl { this.expansionSetCode = "5ED"; // At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. - this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true), new CardsDrawnThisTurnWatcher()); + this.addAbility(new BeginningOfDrawTriggeredAbility(new SylvanLibraryEffect(), TargetController.YOU, true), + new CardsDrawnThisTurnWatcher()); } @@ -99,11 +102,11 @@ class SylvanLibraryEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { controller.drawCards(2, game); - CardsDrawnThisTurnWatcher watcher = (CardsDrawnThisTurnWatcher) game.getState().getWatchers().get("CardsDrawnThisTurnWatcher", source.getControllerId()); + CardsDrawnThisTurnWatcher watcher = (CardsDrawnThisTurnWatcher) game.getState().getWatchers().get("CardsDrawnThisTurnWatcher"); if (watcher != null) { Cards cards = new CardsImpl(); for (UUID cardId : controller.getHand()) { - if (watcher.getCardsDrawnThisTurn().contains(cardId)) { + if (watcher.getCardsDrawnThisTurn(controller.getId()).contains(cardId)) { Card card = game.getCard(cardId); if (card != null) { cards.add(card); @@ -161,26 +164,31 @@ class SylvanLibraryEffect extends OneShotEffect { class CardsDrawnThisTurnWatcher extends Watcher { - private final Set cardsDrawnThisTurn = new HashSet(); + private final Map> cardsDrawnThisTurn = new HashMap<>(); public CardsDrawnThisTurnWatcher() { - super("CardsDrawnThisTurnWatcher", WatcherScope.PLAYER); + super("CardsDrawnThisTurnWatcher", WatcherScope.GAME); } public CardsDrawnThisTurnWatcher(final CardsDrawnThisTurnWatcher watcher) { super(watcher); - this.cardsDrawnThisTurn.addAll(watcher.cardsDrawnThisTurn); + this.cardsDrawnThisTurn.putAll(watcher.cardsDrawnThisTurn); } @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DREW_CARD && event.getPlayerId().equals(this.getControllerId())) { - cardsDrawnThisTurn.add(event.getTargetId()); + if (event.getType() == GameEvent.EventType.DREW_CARD) { + if (!cardsDrawnThisTurn.containsKey(event.getPlayerId())) { + Set cardsDrawn = new LinkedHashSet<>(); + cardsDrawnThisTurn.put(event.getPlayerId(), cardsDrawn); + } + Set cardsDrawn = cardsDrawnThisTurn.get(event.getPlayerId()); + cardsDrawn.add(event.getTargetId()); } } - public Set getCardsDrawnThisTurn() { - return cardsDrawnThisTurn; + public Set getCardsDrawnThisTurn(UUID playerId) { + return cardsDrawnThisTurn.get(playerId); } @Override @@ -195,7 +203,6 @@ class CardsDrawnThisTurnWatcher extends Watcher { } } - class CardIdPredicate implements Predicate { private final Cards cardsId; @@ -206,10 +213,8 @@ class CardIdPredicate implements Predicate { @Override public boolean apply(MageObject input, Game game) { - for(UUID uuid : cardsId) - { - if(uuid.equals(input.getId())) - { + for (UUID uuid : cardsId) { + if (uuid.equals(input.getId())) { return true; } } diff --git a/Mage.Sets/src/mage/sets/fourthedition/Chaoslace.java b/Mage.Sets/src/mage/sets/fourthedition/Chaoslace.java new file mode 100644 index 00000000000..74d149d3ed6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Chaoslace.java @@ -0,0 +1,63 @@ +/* + * 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.sets.fourthedition; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.ObjectColor; +import mage.target.common.TargetSpellOrPermanent; + + +/** + * + * @author AlumiuN + */ +public class Chaoslace extends CardImpl { + + public Chaoslace(UUID ownerId) { + super(ownerId, 200, "Chaoslace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "4ED"; + + // Target spell or permanent becomes red. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.RED, Duration.Custom)); + } + + public Chaoslace(final Chaoslace card) { + super(card); + } + + @Override + public Chaoslace copy() { + return new Chaoslace(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/fourthedition/Deathlace.java b/Mage.Sets/src/mage/sets/fourthedition/Deathlace.java new file mode 100644 index 00000000000..a6d66e70d78 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Deathlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Deathlace extends mage.sets.limitedbeta.Deathlace { + + public Deathlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 15; + this.expansionSetCode = "4ED"; + } + + public Deathlace(final Deathlace card) { + super(card); + } + + @Override + public Deathlace copy() { + return new Deathlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/Lifelace.java b/Mage.Sets/src/mage/sets/fourthedition/Lifelace.java new file mode 100644 index 00000000000..2b9c81b10ef --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Lifelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Lifelace extends mage.sets.limitedalpha.Lifelace { + + public Lifelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 142; + this.expansionSetCode = "4ED"; + } + + public Lifelace(final Lifelace card) { + super(card); + } + + @Override + public Lifelace copy() { + return new Lifelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/Purelace.java b/Mage.Sets/src/mage/sets/fourthedition/Purelace.java new file mode 100644 index 00000000000..a25d9f92c2c --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Purelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Purelace extends mage.sets.unlimitededition.Purelace { + + public Purelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 293; + this.expansionSetCode = "4ED"; + } + + public Purelace(final Purelace card) { + super(card); + } + + @Override + public Purelace copy() { + return new Purelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fourthedition/TheRack.java b/Mage.Sets/src/mage/sets/fourthedition/TheRack.java index 98b564a6bbf..bbbed87b4d3 100644 --- a/Mage.Sets/src/mage/sets/fourthedition/TheRack.java +++ b/Mage.Sets/src/mage/sets/fourthedition/TheRack.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseOpponentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -40,9 +41,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetOpponent; /** * @@ -55,7 +54,7 @@ public class TheRack extends CardImpl { this.expansionSetCode = "4ED"; // As The Rack enters the battlefield, choose an opponent. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponent())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.Detriment))); // At the beginning of the chosen player's upkeep, The Rack deals X damage to that player, where X is 3 minus the number of cards in his or her hand. this.addAbility(new TheRackTriggeredAbility()); } @@ -72,7 +71,6 @@ public class TheRack extends CardImpl { class TheRackTriggeredAbility extends TriggeredAbilityImpl { - public TheRackTriggeredAbility() { super(Zone.BATTLEFIELD, new TheRackEffect(), false); } @@ -93,52 +91,16 @@ class TheRackTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return event.getPlayerId().equals((UUID) game.getState().getValue(new StringBuilder(this.getSourceId().toString()).append("_player").toString())); + return event.getPlayerId().equals((UUID) game.getState().getValue(this.getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY)); } @Override public String getRule() { - return new StringBuilder("At the beginning of the chosen player's upkeep, ").append(super.getRule()).toString(); + return "At the beginning of the chosen player's upkeep, " + super.getRule(); } } -class ChooseOpponent extends OneShotEffect { - - public ChooseOpponent() { - super(Outcome.Neutral); - this.staticText = "choose an opponent"; - } - - public ChooseOpponent(final ChooseOpponent effect) { - super(effect); - } - - @Override - public ChooseOpponent copy() { - return new ChooseOpponent(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetOpponent target = new TargetOpponent(); - target.setNotTarget(true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class TheRackEffect extends OneShotEffect { public TheRackEffect() { @@ -157,7 +119,7 @@ class TheRackEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - UUID playerId = (UUID) game.getState().getValue(new StringBuilder(source.getSourceId().toString()).append("_player").toString()); + UUID playerId = (UUID) game.getState().getValue(source.getSourceId().toString() + "_player"); Player chosenPlayer = game.getPlayer(playerId); if (chosenPlayer != null) { int damage = 3 - chosenPlayer.getHand().size(); diff --git a/Mage.Sets/src/mage/sets/fourthedition/Thoughtlace.java b/Mage.Sets/src/mage/sets/fourthedition/Thoughtlace.java new file mode 100644 index 00000000000..19f9d3bcc34 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fourthedition/Thoughtlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.fourthedition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Thoughtlace extends mage.sets.limitedbeta.Thoughtlace { + + public Thoughtlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 107; + this.expansionSetCode = "4ED"; + } + + public Thoughtlace(final Thoughtlace card) { + super(card); + } + + @Override + public Thoughtlace copy() { + return new Thoughtlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/futuresight/CloudKey.java b/Mage.Sets/src/mage/sets/futuresight/CloudKey.java index 7fc55b94457..b357c8b83f1 100644 --- a/Mage.Sets/src/mage/sets/futuresight/CloudKey.java +++ b/Mage.Sets/src/mage/sets/futuresight/CloudKey.java @@ -23,6 +23,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.util.CardUtil; @@ -73,8 +74,11 @@ class CloudKeyChooseTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && controller != null) { + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (mageObject != null && controller != null) { ChoiceImpl choices = new ChoiceImpl(true); choices.setMessage("Choose a spell type"); choices.getChoices().add(CardType.ARTIFACT.toString()); @@ -82,9 +86,12 @@ class CloudKeyChooseTypeEffect extends OneShotEffect { choices.getChoices().add(CardType.ENCHANTMENT.toString()); choices.getChoices().add(CardType.INSTANT.toString()); choices.getChoices().add(CardType.SORCERY.toString()); - if(controller.choose(Outcome.Neutral, choices, game)) { - game.informPlayers(sourceObject.getLogName() + ": chosen spell type is " + choices.getChoice()); + if (controller.choose(Outcome.Neutral, choices, game)) { + game.informPlayers(mageObject.getLogName() + ": chosen spell type is " + choices.getChoice()); game.getState().setValue(source.getSourceId().toString() + "_CloudKey", choices.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosenCardType", CardUtil.addToolTipMarkTags("Chosen card type: " + choices.getChoice()), game); + } return true; } } @@ -129,4 +136,3 @@ class CloudKeyCostModificationEffect extends CostModificationEffectImpl { return false; } } - diff --git a/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java b/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java index deca054ff68..c9055368a95 100644 --- a/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java +++ b/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java @@ -61,7 +61,7 @@ public class KavuPrimarch extends CardImpl { // If Kavu Primarch was kicked, it enters the battlefield with four +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),KickedCondition.getInstance(), true, + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),KickedCondition.getInstance(), "If Kavu Primarch was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); } diff --git a/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java b/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java index 30c9a66fcf0..a1f6e59f044 100644 --- a/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java +++ b/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java @@ -64,7 +64,7 @@ public class RavagingRiftwurm extends CardImpl { this.addAbility(new VanishingSacrificeAbility()); // If Ravaging Riftwurm was kicked, it enters the battlefield with three additional time counters on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.TIME.createInstance(3)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with three additional time counters on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with three additional time counters on it.", "")); } public RavagingRiftwurm(final RavagingRiftwurm card) { diff --git a/Mage.Sets/src/mage/sets/futuresight/SwordOfTheMeek.java b/Mage.Sets/src/mage/sets/futuresight/SwordOfTheMeek.java index eaaf39e852f..737dfd0139d 100644 --- a/Mage.Sets/src/mage/sets/futuresight/SwordOfTheMeek.java +++ b/Mage.Sets/src/mage/sets/futuresight/SwordOfTheMeek.java @@ -70,7 +70,7 @@ public class SwordOfTheMeek extends CardImpl { this.subtype.add("Equipment"); // Equipped creature gets +1/+2. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1,2,Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 2, Duration.WhileOnBattlefield))); // Equip {2} this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); // Whenever a 1/1 creature enters the battlefield under your control, you may return Sword of the Meek from your graveyard to the battlefield, then attach it to that creature. @@ -108,7 +108,7 @@ class SwordOfTheMeekEffect extends OneShotEffect { Card equipment = game.getCard(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); if (equipment != null && controller != null && game.getState().getZone(source.getSourceId()).equals(Zone.GRAVEYARD)) { - controller.putOntoBattlefieldWithInfo(equipment, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(equipment, Zone.BATTLEFIELD, source, game); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { return permanent.addAttachment(equipment.getId(), game); diff --git a/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java b/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java index 5167e1c6d68..27985e968f3 100644 --- a/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java +++ b/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java @@ -73,7 +73,7 @@ public class ScaleguardSentinels extends CardImpl { // Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), - ScaleguardSentinelsCondition.getInstance(), true, + ScaleguardSentinelsCondition.getInstance(), "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}", ""), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); diff --git a/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java b/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java index 3bc36d45269..9178c73592d 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java +++ b/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java @@ -28,17 +28,18 @@ package mage.sets.gatecrash; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.ExtortAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -52,7 +53,6 @@ public class BlindObedience extends CardImpl { super(ownerId, 6, "Blind Obedience", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.expansionSetCode = "GTC"; - // Extort (Whenever you cast a spell, you may pay {WB}. If you do, each opponent loses 1 life and you gain that much life.) this.addAbility(new ExtortAbility()); @@ -72,6 +72,7 @@ public class BlindObedience extends CardImpl { } class BlindObedienceTapEffect extends ReplacementEffectImpl { + BlindObedienceTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts and creatures your opponents control enter the battlefield tapped"; @@ -83,22 +84,22 @@ class BlindObedienceTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null && (permanent.getCardType().contains(CardType.CREATURE) || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } diff --git a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java index 0d92cdf0bac..cf84a981cc3 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java @@ -31,13 +31,12 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.FightTargetsEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HexproofAbility; @@ -50,7 +49,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; @@ -70,7 +68,7 @@ public class DomriRade extends CardImpl { this.expansionSetCode = "GTC"; this.subtype.add("Domri"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Look at the top card of your library. If it's a creature card, you may reveal it and put it into your hand. this.addAbility(new LoyaltyAbility(new DomriRadeEffect1(), 1)); @@ -138,7 +136,6 @@ class DomriRadeEffect1 extends OneShotEffect { class DomriRadeEmblem extends Emblem { // "Creatures you control have double strike, trample, hexproof and haste." - public DomriRadeEmblem() { this.setName("EMBLEM: Domri Rade"); FilterPermanent filter = new FilterControlledCreaturePermanent("Creatures"); diff --git a/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java b/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java index 67f67d0d830..5f125a6fec3 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java +++ b/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java @@ -1,5 +1,5 @@ /* -/* + /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are @@ -60,7 +60,7 @@ public class FathomMage extends CardImpl { // Evolve (Whenever a creature enters the battlefield under your control, if that creature // has greater power or toughness than this creature, put a +1/+1 counter on this creature.) this.addAbility(new EvolveAbility()); - + //Whenever a +1/+1 counter is placed on Fathom Mage, you may draw a card. this.addAbility(new FathomMageTriggeredAbility()); } @@ -75,11 +75,10 @@ public class FathomMage extends CardImpl { } } - class FathomMageTriggeredAbility extends TriggeredAbilityImpl { public FathomMageTriggeredAbility() { - super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), true); + super(Zone.ALL, new DrawCardSourceControllerEffect(1), true); } public FathomMageTriggeredAbility(FathomMageTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java index 60ce90daeed..9467a3ccfcc 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java +++ b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java @@ -27,10 +27,11 @@ */ package mage.sets.gatecrash; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.CountersCount; import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount; @@ -41,7 +42,11 @@ import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -49,8 +54,6 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author LevelX2 @@ -62,7 +65,7 @@ public class GideonChampionOfJustice extends CardImpl { this.expansionSetCode = "GTC"; this.subtype.add("Gideon"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a loyalty counter on Gideon, Champion of Justice for each creature target opponent controls. LoyaltyAbility ability1 = new LoyaltyAbility( diff --git a/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java b/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java index eeb0b6346dd..8a7a9c32ef9 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java +++ b/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java @@ -1,30 +1,30 @@ /* -* 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. -*/ + * 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.sets.gatecrash; import java.util.UUID; @@ -42,37 +42,38 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** -* -* @author LevelX2 -*/ + * + * @author LevelX2 + */ public class MasterBiomancer extends CardImpl { public MasterBiomancer(UUID ownerId) { - super(ownerId, 176, "Master Biomancer", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); - this.expansionSetCode = "GTC"; - this.subtype.add("Elf"); - this.subtype.add("Wizard"); + super(ownerId, 176, "Master Biomancer", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); + this.expansionSetCode = "GTC"; + this.subtype.add("Elf"); + this.subtype.add("Wizard"); - this.power = new MageInt(2); - this.toughness = new MageInt(4); + this.power = new MageInt(2); + this.toughness = new MageInt(4); - // Each other creature you control enters the battlefield with a number of additional +1/+1 counters on it equal to Master Biomancer's power and as a Mutant in addition to its other types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MasterBiomancerEntersBattlefieldEffect())); + // Each other creature you control enters the battlefield with a number of additional +1/+1 counters on it equal to Master Biomancer's power and as a Mutant in addition to its other types. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MasterBiomancerEntersBattlefieldEffect())); } public MasterBiomancer(final MasterBiomancer card) { - super(card); + super(card); } @Override public MasterBiomancer copy() { - return new MasterBiomancer(this); + return new MasterBiomancer(this); } } @@ -86,16 +87,16 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { public MasterBiomancerEntersBattlefieldEffect(MasterBiomancerEntersBattlefieldEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && !event.getTargetId().equals(source.getSourceId()); } @@ -103,20 +104,19 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent sourceCreature = game.getPermanent(source.getSourceId()); - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (sourceCreature != null && creature != null) { int power = sourceCreature.getPower().getValue(); if (power > 0) { creature.addCounters(CounterType.P1P1.createInstance(power), game); } ContinuousEffect effect = new AddCardSubTypeTargetEffect("Mutant", Duration.Custom); - effect.setTargetPointer(new FixedTarget(creature.getId())); + effect.setTargetPointer(new FixedTarget(creature.getId(), creature.getZoneChangeCounter(game) + 1)); game.addEffect(effect, source); } return false; } - @Override public MasterBiomancerEntersBattlefieldEffect copy() { return new MasterBiomancerEntersBattlefieldEffect(this); diff --git a/Mage.Sets/src/mage/sets/gatecrash/ObzedatGhostCouncil.java b/Mage.Sets/src/mage/sets/gatecrash/ObzedatGhostCouncil.java index 4435598c20d..4ebfb6bdee6 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/ObzedatGhostCouncil.java +++ b/Mage.Sets/src/mage/sets/gatecrash/ObzedatGhostCouncil.java @@ -180,7 +180,7 @@ class ObzedatGhostCouncilReturnEffect extends OneShotEffect { // return it only from the own exile zone if (currentZone != null && currentZone.size() > 0) { Player owner = game.getPlayer(card.getOwnerId()); - if (owner != null && owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId())) { + if (owner != null && owner.moveCards(card, Zone.BATTLEFIELD, source, game)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java b/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java index dfb670e3dd7..f0707af005d 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java +++ b/Mage.Sets/src/mage/sets/gatecrash/Realmwright.java @@ -29,6 +29,18 @@ package mage.sets.gatecrash; import java.util.List; import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ChooseBasicLandTypeEffect; +import mage.abilities.mana.BlackManaAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,15 +48,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.mana.*; -import mage.cards.CardImpl; -import mage.choices.ChoiceImpl; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -66,7 +69,7 @@ public class Realmwright extends CardImpl { this.toughness = new MageInt(1); // As Realmwright enters the battlefield, choose a basic land type. - this.addAbility(new AsEntersBattlefieldAbility(new RealmwrightEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral))); // Lands you control are the chosen type in addition to their other types. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealmwrightEffect2())); @@ -82,44 +85,6 @@ public class Realmwright extends CardImpl { } } -class RealmwrightEffect extends OneShotEffect { - - public RealmwrightEffect() { - super(Outcome.Neutral); - this.staticText = "Choose a basic land type"; - } - - public RealmwrightEffect(final RealmwrightEffect effect) { - super(effect); - } - - @Override - public RealmwrightEffect copy() { - return new RealmwrightEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - ChoiceImpl choices = new ChoiceImpl(true); - choices.setMessage("Choose basic land type"); - choices.isRequired(); - choices.getChoices().add("Forest"); - choices.getChoices().add("Plains"); - choices.getChoices().add("Mountain"); - choices.getChoices().add("Island"); - choices.getChoices().add("Swamp"); - if (you.choose(Outcome.Neutral, choices, game)) { - game.informPlayers(new StringBuilder("Realmwright: ").append(" Chosen basic land type is ").append(choices.getChoice()).toString()); - game.getState().setValue(source.getSourceId().toString() + "_Realmwright", choices.getChoice()); - return true; - } - } - return false; - } -} - class RealmwrightEffect2 extends ContinuousEffectImpl { public RealmwrightEffect2() { @@ -140,7 +105,7 @@ class RealmwrightEffect2 extends ContinuousEffectImpl { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Player you = game.getPlayer(source.getControllerId()); List lands = game.getBattlefield().getAllActivePermanents(new FilterControlledLandPermanent(), source.getControllerId(), game); - String choice = (String) game.getState().getValue(source.getSourceId().toString() + "_Realmwright"); + String choice = (String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY); if (you != null && choice != null) { for (Permanent land : lands) { if (land != null) { diff --git a/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java b/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java index 48c906b6fec..41bc52a2399 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java +++ b/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java @@ -28,29 +28,25 @@ package mage.sets.gatecrash; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCounterCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.Effects; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.targetpointer.FixedTarget; /** * @@ -58,8 +54,6 @@ import mage.target.targetpointer.FixedTarget; */ public class ZameckGuildmage extends CardImpl { - private static final String ruleText = "This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it"; - public ZameckGuildmage(UUID ownerId) { super(ownerId, 209, "Zameck Guildmage", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{G}{U}"); this.expansionSetCode = "GTC"; @@ -69,9 +63,8 @@ public class ZameckGuildmage extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - // {G}{U}: This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), ruleText), new ManaCostsImpl("{G}{U}"))); + this.addAbility(new SimpleActivatedAbility(Zone.ALL, new ZameckGuildmageEntersBattlefieldEffect(), new ManaCostsImpl("{G}{U}"))); // {G}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{G}{U}")); @@ -89,25 +82,15 @@ public class ZameckGuildmage extends CardImpl { } } -class EntersBattlefieldEffect extends ReplacementEffectImpl { +class ZameckGuildmageEntersBattlefieldEffect extends ReplacementEffectImpl { - protected Effects baseEffects = new Effects(); - protected String text; - - public EntersBattlefieldEffect(Effect baseEffect, String text) { - super(Duration.EndOfTurn, baseEffect.getOutcome()); - this.baseEffects.add(baseEffect); - this.text = text; + public ZameckGuildmageEntersBattlefieldEffect() { + super(Duration.EndOfTurn, Outcome.BoostCreature); + this.staticText = "This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it"; } - public EntersBattlefieldEffect(EntersBattlefieldEffect effect) { + public ZameckGuildmageEntersBattlefieldEffect(ZameckGuildmageEntersBattlefieldEffect effect) { super(effect); - this.baseEffects = effect.baseEffects.copy(); - this.text = effect.text; - } - - public void addEffect(Effect effect) { - baseEffects.add(effect); } @Override @@ -117,11 +100,8 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) { - return true; - } - return false; + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + return permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE); } @Override @@ -131,23 +111,15 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - for (Effect effect: baseEffects) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null) { - effect.setTargetPointer(new FixedTarget(target.getId())); - effect.apply(game, source); - } + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); + if (target != null) { + target.addCounters(CounterType.P1P1.createInstance(), game); } return false; } @Override - public String getText(Mode mode) { - return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text; - } - - @Override - public EntersBattlefieldEffect copy() { - return new EntersBattlefieldEffect(this); + public ZameckGuildmageEntersBattlefieldEffect copy() { + return new ZameckGuildmageEntersBattlefieldEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/guildpact/StompingGround.java b/Mage.Sets/src/mage/sets/guildpact/StompingGround.java index 0bce0460177..85c8b2ce2d4 100644 --- a/Mage.Sets/src/mage/sets/guildpact/StompingGround.java +++ b/Mage.Sets/src/mage/sets/guildpact/StompingGround.java @@ -25,18 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.guildpact; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.TapSourceUnlessPaysEffect; import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -44,17 +43,19 @@ import mage.cards.CardImpl; */ public class StompingGround extends CardImpl { - public StompingGround (UUID ownerId) { + public StompingGround(UUID ownerId) { super(ownerId, 165, "Stomping Ground", Rarity.RARE, new CardType[]{CardType.LAND}, null); this.expansionSetCode = "GPT"; this.subtype.add("Mountain"); this.subtype.add("Forest"); + this.addAbility(new RedManaAbility()); this.addAbility(new GreenManaAbility()); - this.addAbility(new AsEntersBattlefieldAbility(new TapSourceUnlessPaysEffect(new PayLifeCost(2)), "you may pay 2 life. If you don't, Stomping Ground enters the battlefield tapped")); + this.addAbility(new AsEntersBattlefieldAbility(new TapSourceUnlessPaysEffect(new PayLifeCost(2)), + "you may pay 2 life. If you don't, {this} enters the battlefield tapped")); } - public StompingGround (final StompingGround card) { + public StompingGround(final StompingGround card) { super(card); } diff --git a/Mage.Sets/src/mage/sets/iceage/DanceOfTheDead.java b/Mage.Sets/src/mage/sets/iceage/DanceOfTheDead.java index 5f308525d87..126046c1d68 100644 --- a/Mage.Sets/src/mage/sets/iceage/DanceOfTheDead.java +++ b/Mage.Sets/src/mage/sets/iceage/DanceOfTheDead.java @@ -78,13 +78,12 @@ public class DanceOfTheDead extends CardImpl { this.expansionSetCode = "ICE"; this.subtype.add("Aura"); - // Enchant creature card in a graveyard TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new DanceOfTheDeadAttachEffect(Outcome.PutCreatureInPlay)); Ability enchantAbility = new EnchantAbility(auraTarget.getTargetName()); - this.addAbility(enchantAbility); + this.addAbility(enchantAbility); // When Dance of the Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" and gains "enchant creature put onto the battlefield with Dance of the Dead." Put enchanted creature card to the battlefield tapped under your control and attach Dance of the Dead to it. When Dance of the Dead leaves the battlefield, that creature's controller sacrifices it. Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new DanceOfTheDeadReAttachEffect(), false), @@ -92,18 +91,18 @@ public class DanceOfTheDead extends CardImpl { "When {this} enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with {this}.\" Return enchanted creature card to the battlefield under your control and attach {this} to it."); ability.addEffect(new DanceOfTheDeadChangeAbilityEffect()); this.addAbility(ability); - this.addAbility(new LeavesBattlefieldTriggeredAbility(new DanceOfTheDeadLeavesBattlefieldTriggeredEffect(), false)); - + this.addAbility(new LeavesBattlefieldTriggeredAbility(new DanceOfTheDeadLeavesBattlefieldTriggeredEffect(), false)); + // Enchanted creature gets +1/+1 and doesn't untap during its controller's untap step. ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield)); Effect effect = new DontUntapInControllersUntapStepEnchantedEffect(); effect.setText("and doesn't untap during its controller's untap step"); ability.addEffect(effect); this.addAbility(ability); - + // At the beginning of the upkeep of enchanted creature's controller, that player may pay {1}{B}. If he or she does, untap that creature. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DanceOfTheDeadDoIfCostPaidEffect(), TargetController.CONTROLLER_ATTACHED_TO, false)); - + } public DanceOfTheDead(final DanceOfTheDead card) { @@ -117,36 +116,36 @@ public class DanceOfTheDead extends CardImpl { } class DanceOfTheDeadReAttachEffect extends OneShotEffect { - + public DanceOfTheDeadReAttachEffect() { super(Outcome.Benefit); this.staticText = "Return enchanted creature card to the battlefield under your control and attach {this} to it"; } - + public DanceOfTheDeadReAttachEffect(final DanceOfTheDeadReAttachEffect effect) { super(effect); } - + @Override public DanceOfTheDeadReAttachEffect copy() { return new DanceOfTheDeadReAttachEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent enchantment = game.getPermanent(source.getSourceId()); - + if (controller != null && enchantment != null) { Card cardInGraveyard = game.getCard(enchantment.getAttachedTo()); if (cardInGraveyard == null) { return true; } - + // put card into play - controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId(), true); + controller.moveCards(cardInGraveyard, Zone.BATTLEFIELD, source, game, true, false, false, null); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); - + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Dance of the Dead"); filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); Target target = new TargetCreaturePermanent(filter); @@ -159,27 +158,27 @@ class DanceOfTheDeadReAttachEffect extends OneShotEffect { } return true; } - + return false; } } - + class DanceOfTheDeadLeavesBattlefieldTriggeredEffect extends OneShotEffect { - + public DanceOfTheDeadLeavesBattlefieldTriggeredEffect() { super(Outcome.Benefit); this.staticText = "enchanted creature's controller sacrifices it"; } - + public DanceOfTheDeadLeavesBattlefieldTriggeredEffect(final DanceOfTheDeadLeavesBattlefieldTriggeredEffect effect) { super(effect); } - + @Override public DanceOfTheDeadLeavesBattlefieldTriggeredEffect copy() { return new DanceOfTheDeadLeavesBattlefieldTriggeredEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -236,17 +235,16 @@ class DanceOfTheDeadAttachEffect extends OneShotEffect { class DanceOfTheDeadChangeAbilityEffect extends ContinuousEffectImpl implements SourceEffect { private final static Ability newAbility = new EnchantAbility("creature put onto the battlefield with Dance of the Dead"); - + static { newAbility.setRuleAtTheTop(true); } - + public DanceOfTheDeadChangeAbilityEffect() { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); staticText = "it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Dance of the Dead\""; } - public DanceOfTheDeadChangeAbilityEffect(final DanceOfTheDeadChangeAbilityEffect effect) { super(effect); } @@ -255,7 +253,7 @@ class DanceOfTheDeadChangeAbilityEffect extends ContinuousEffectImpl implements public DanceOfTheDeadChangeAbilityEffect copy() { return new DanceOfTheDeadChangeAbilityEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); @@ -267,7 +265,7 @@ class DanceOfTheDeadChangeAbilityEffect extends ContinuousEffectImpl implements Permanent permanent = affectedObjectList.get(0).getPermanent(game);; if (permanent != null) { Ability abilityToRemove = null; - for (Ability ability: permanent.getAbilities()) { + for (Ability ability : permanent.getAbilities()) { if (ability instanceof EnchantAbility) { abilityToRemove = ability; } @@ -277,7 +275,7 @@ class DanceOfTheDeadChangeAbilityEffect extends ContinuousEffectImpl implements } permanent.addAbility(newAbility, source.getSourceId(), game); return true; - } + } return false; } } @@ -309,4 +307,4 @@ class DanceOfTheDeadDoIfCostPaidEffect extends DoIfCostPaid { return new StringBuilder("that player may ").append(getCostText()) .append(". If he or she does, ").append(executingEffects.getText(mode)).toString(); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/iceage/SkeletonShip.java b/Mage.Sets/src/mage/sets/iceage/SkeletonShip.java index 38a31f5b63c..78053e99136 100644 --- a/Mage.Sets/src/mage/sets/iceage/SkeletonShip.java +++ b/Mage.Sets/src/mage/sets/iceage/SkeletonShip.java @@ -51,7 +51,7 @@ import mage.target.common.TargetCreaturePermanent; public class SkeletonShip extends CardImpl { public SkeletonShip(UUID ownerId) { - super(ownerId, 379, "Skeleton Ship", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}"); + super(ownerId, 379, "Skeleton Ship", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); this.expansionSetCode = "ICE"; this.supertype.add("Legendary"); this.subtype.add("Skeleton"); @@ -62,7 +62,7 @@ public class SkeletonShip extends CardImpl { this.addAbility(new ControlsPermanentsControllerTriggeredAbility( new FilterLandPermanent("Island", "no Islands"), Filter.ComparisonType.Equal, 0, new SacrificeSourceEffect())); - + // {tap}: Put a -1/-1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.M1M1.createInstance()), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java index 4dc4e3bd417..7bbd95e03b1 100644 --- a/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java +++ b/Mage.Sets/src/mage/sets/innistrad/CaravanVigil.java @@ -96,13 +96,12 @@ class CaravanVigilEffect extends OneShotEffect { if (controller.searchLibrary(target, game)) { Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); + Cards cards = new CardsImpl(card); if (MorbidCondition.getInstance().apply(game, source) && controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to put the card onto the battlefield instead?", source, game)) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - controller.moveCards(card, null, Zone.HAND, source, game); + controller.moveCards(card, Zone.HAND, source, game); } controller.revealCards(sourceObject.getIdName(), cards, game); } diff --git a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java index 4a1345a52c9..aa0a1f54fef 100644 --- a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java +++ b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java @@ -27,39 +27,30 @@ */ package mage.sets.innistrad; - -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.Effect; -import mage.abilities.effects.Effects; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.stack.Spell; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; /** * @author nantuko */ public class DearlyDeparted extends CardImpl { - private static final String ruleText = "As long as {this} is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it"; - public DearlyDeparted(UUID ownerId) { super(ownerId, 9, "Dearly Departed", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); this.expansionSetCode = "ISD"; @@ -71,8 +62,7 @@ public class DearlyDeparted extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // As long as Dearly Departed is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it. - this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, - new EntersBattlefieldEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), ruleText))); + this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, new DearlyDepartedEntersBattlefieldEffect())); } public DearlyDeparted(final DearlyDeparted card) { @@ -85,43 +75,26 @@ public class DearlyDeparted extends CardImpl { } } -class EntersBattlefieldEffect extends ReplacementEffectImpl { +class DearlyDepartedEntersBattlefieldEffect extends ReplacementEffectImpl { - protected Effects baseEffects = new Effects(); - protected String text; - - public static final String SOURCE_CAST_SPELL_ABILITY = "sourceCastSpellAbility"; - - public EntersBattlefieldEffect(Effect baseEffect) { - this(baseEffect, ""); + public DearlyDepartedEntersBattlefieldEffect() { + super(Duration.OneUse, Outcome.BoostCreature); + staticText = "As long as {this} is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it"; } - public EntersBattlefieldEffect(Effect baseEffect, String text) { - super(Duration.OneUse, baseEffect.getOutcome()); - this.baseEffects.add(baseEffect); - this.text = text; - } - - public EntersBattlefieldEffect(EntersBattlefieldEffect effect) { + public DearlyDepartedEntersBattlefieldEffect(DearlyDepartedEntersBattlefieldEffect effect) { super(effect); - this.baseEffects = effect.baseEffects.copy(); - this.text = effect.text; } - public void addEffect(Effect effect) { - baseEffects.add(effect); - } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.hasSubtype("Human")) { - setValue("target", permanent); return true; } return false; @@ -129,33 +102,16 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Spell spell = game.getStack().getSpell(event.getSourceId()); - for (Effect effect: baseEffects) { - Object target = getValue("target"); - if (target != null && target instanceof Permanent) { - effect.setTargetPointer(new FixedTarget(((Permanent)target).getId())); - if (effect instanceof ContinuousEffect) { - game.addEffect((ContinuousEffect) effect, source); - } - else { - if (spell != null) { - effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); - } - effect.apply(game, source); - } - } + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); + if (target != null) { + target.addCounters(CounterType.P1P1.createInstance(), game); } return false; } @Override - public String getText(Mode mode) { - return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text; - } - - @Override - public EntersBattlefieldEffect copy() { - return new EntersBattlefieldEffect(this); + public DearlyDepartedEntersBattlefieldEffect copy() { + return new DearlyDepartedEntersBattlefieldEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java b/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java index 657f77a94c3..68b0c47ceb9 100644 --- a/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java +++ b/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java @@ -28,20 +28,19 @@ package mage.sets.innistrad; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CopyEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -89,21 +88,18 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent perm = game.getPermanent(event.getTargetId()); + Permanent perm = ((EntersTheBattlefieldEvent) event).getTarget(); return perm != null && perm.getCardType().contains(CardType.CREATURE) && perm.getControllerId().equals(source.getControllerId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent perm = game.getPermanent(source.getSourceId()); - if (perm != null) { - perm = perm.copy(); - perm.reset(game); - perm.assignNewId(); - game.addEffect(new EssenceOfTheWildCopyEffect(perm, event.getTargetId()), source); + Permanent sourceObject = ((EntersTheBattlefieldEvent) event).getTarget(); + if (sourceObject != null) { + game.addEffect(new CopyEffect(Duration.Custom, sourceObject, event.getTargetId()), source); } return false; } @@ -114,59 +110,3 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl { } } - -class EssenceOfTheWildCopyEffect extends ContinuousEffectImpl { - - private final Permanent essence; - private final UUID targetId; - - public EssenceOfTheWildCopyEffect(Permanent essence, UUID targetId) { - super(Duration.EndOfGame, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); - this.essence = essence; - this.targetId = targetId; - } - - public EssenceOfTheWildCopyEffect(final EssenceOfTheWildCopyEffect effect) { - super(effect); - this.essence = effect.essence.copy(); - this.targetId = effect.targetId; - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - permanent.setName(essence.getName()); - permanent.getColor(game).setColor(essence.getColor(game)); - permanent.getManaCost().clear(); - permanent.getManaCost().add(essence.getManaCost()); - permanent.getCardType().clear(); - for (CardType type: essence.getCardType()) { - permanent.getCardType().add(type); - } - permanent.getSubtype().clear(); - for (String type: essence.getSubtype()) { - permanent.getSubtype().add(type); - } - permanent.getSupertype().clear(); - for (String type: essence.getSupertype()) { - permanent.getSupertype().add(type); - } - permanent.getAbilities().clear(); - for (Ability ability: essence.getAbilities()) { - permanent.addAbility(ability, game); - } - permanent.getPower().setValue(essence.getPower().getValue()); - permanent.getToughness().setValue(essence.getToughness().getValue()); - - return true; - } - return false; - } - - @Override - public EssenceOfTheWildCopyEffect copy() { - return new EssenceOfTheWildCopyEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java b/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java index 3cf16f8fbe3..62ec36b5d7e 100644 --- a/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java +++ b/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java @@ -31,11 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; @@ -65,11 +65,10 @@ public class EvilTwin extends CardImpl { this.toughness = new MageInt(0); // You may have Evil Twin enter the battlefield as a copy of any creature on the battlefield except it gains "{U}{B}, {T}: Destroy target creature with the same name as this creature." - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new EvilTwinApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains \"{U}{B}, {T}: Destroy target creature with the same name as this creature\"", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new EvilTwinApplyToPermanent()); + effect.setText("a copy of any creature on the battlefield except it gains \"{U}{B}, {T}: Destroy target creature with the same name as this creature.\""); + this.addAbility(new EntersBattlefieldAbility(effect, true)); + } public EvilTwin(final EvilTwin card) { diff --git a/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java b/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java index 3d3e258a14b..1f43014bc50 100644 --- a/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java +++ b/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java @@ -31,11 +31,10 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -60,11 +59,10 @@ public class GarrukRelentless extends CardImpl { this.expansionSetCode = "ISD"; this.subtype.add("Garruk"); - this.canTransform = true; this.secondSideCard = new GarrukTheVeilCursed(ownerId); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // When Garruk Relentless has two or fewer loyalty counters on him, transform him. this.addAbility(new TransformAbility()); @@ -160,4 +158,4 @@ class GarrukRelentlessDamageEffect extends OneShotEffect { return new GarrukRelentlessDamageEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java b/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java index aeba8786b36..5d05bc28c57 100644 --- a/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java +++ b/Mage.Sets/src/mage/sets/innistrad/GhostQuarter.java @@ -98,16 +98,16 @@ class GhostQuarterEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = (Permanent) game.getPermanentOrLKIBattlefield(source.getFirstTarget()); // if indestructible effect should work also if (permanent != null) { - Player player = game.getPlayer(permanent.getControllerId()); - if (player.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", source, game)) { + Player controller = game.getPlayer(permanent.getControllerId()); + if (controller.chooseUse(Outcome.PutLandInPlay, "Do you wish to search for a basic land, put it onto the battlefield and then shuffle your library?", source, game)) { TargetCardInLibrary target = new TargetCardInLibrary(new FilterBasicLandCard()); - if (player.searchLibrary(target, game)) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + if (card != null) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); } return true; } diff --git a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java index d20fc714ff0..0fea92be5d7 100644 --- a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java +++ b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java @@ -27,18 +27,19 @@ */ package mage.sets.innistrad; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.abilities.effects.common.SacrificeEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -47,10 +48,6 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * * @author North @@ -62,17 +59,16 @@ public class LilianaOfTheVeil extends CardImpl { this.expansionSetCode = "ISD"; this.subtype.add("Liliana"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Each player discards a card. this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(), 1)); - + // -2: Target player sacrifices a creature. LoyaltyAbility ability = new LoyaltyAbility(new SacrificeEffect(new FilterCreaturePermanent(), 1, "Target player"), -2); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - + // -6: Separate all permanents target player controls into two piles. That player sacrifices all permanents in the pile of his or her choice. ability = new LoyaltyAbility(new LilianaOfTheVeilEffect(), -6); ability.addTarget(new TargetPlayer()); @@ -124,7 +120,7 @@ class LilianaOfTheVeilEffect extends OneShotEffect { } } List pile2 = new ArrayList<>(); - for (Permanent p: game.getBattlefield().getAllActivePermanents(targetPlayer.getId())) { + for (Permanent p : game.getBattlefield().getAllActivePermanents(targetPlayer.getId())) { if (!pile1.contains(p)) { pile2.add(p); } diff --git a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java index dee67c6f07f..dee1d81fe79 100644 --- a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java +++ b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java @@ -1,16 +1,16 @@ /* * Copyright 2011 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 @@ -20,7 +20,7 @@ * 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. @@ -33,11 +33,8 @@ import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.NameACardEffect; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -46,9 +43,6 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.util.CardUtil; /** * @@ -60,11 +54,10 @@ public class Nevermore extends CardImpl { super(ownerId, 25, "Nevermore", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); this.expansionSetCode = "ISD"; + // As Nevermore enters the battlefield, name a nonland card. + this.addAbility(new AsEntersBattlefieldAbility(new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME))); - //As Nevermore enters the battlefield, name a nonland card. - this.addAbility(new AsEntersBattlefieldAbility(new NevermoreEffect1())); - - //The named card can't be cast. + // The named card can't be cast. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NevermoreEffect2())); } @@ -80,46 +73,6 @@ public class Nevermore extends CardImpl { } -class NevermoreEffect1 extends OneShotEffect { - - public NevermoreEffect1() { - super(Outcome.Detriment); - staticText = "name a nonland card"; - } - - public NevermoreEffect1(final NevermoreEffect1 effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (controller != null && permanent != null) { - Choice cardChoice = new ChoiceImpl(); - cardChoice.setChoices(CardRepository.instance.getNonLandNames()); - cardChoice.clearChoice(); - while (!controller.choose(Outcome.Detriment, cardChoice, game)) { - if (!controller.canRespond()) { - return false; - } - } - String cardName = cardChoice.getChoice(); - game.informPlayers(permanent.getLogName() + ", named card: [" + cardName + "]"); - game.getState().setValue(source.getSourceId().toString(), cardName); - permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]"), game); - return true; - } - return false; - } - - @Override - public NevermoreEffect1 copy() { - return new NevermoreEffect1(this); - } - -} - class NevermoreEffect2 extends ContinuousRuleModifyingEffectImpl { public NevermoreEffect2() { @@ -145,7 +98,7 @@ class NevermoreEffect2 extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { + if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java b/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java index 16fef1058fe..3f50f943347 100644 --- a/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java +++ b/Mage.Sets/src/mage/sets/innistrad/SkirsdagHighPriest.java @@ -30,20 +30,19 @@ package mage.sets.innistrad; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.CostImpl; +import mage.abilities.condition.common.MorbidCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.TappedPredicate; -import mage.game.Game; import mage.game.permanent.token.DemonToken; import mage.target.common.TargetControlledCreaturePermanent; @@ -69,9 +68,10 @@ public class SkirsdagHighPriest extends CardImpl { this.toughness = new MageInt(2); // Morbid - {tap}, Tap two untapped creatures you control: Put a 5/5 black Demon creature token with flying onto the battlefield. Activate this ability only if a creature died this turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DemonToken()), new TapSourceCost()); - ability.addCost(new TapTargetCost(new TargetControlledCreaturePermanent(2,2,filter, false))); - ability.addCost(new SkirsdagHighPriestCost()); + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DemonToken()), + new TapSourceCost(), MorbidCondition.getInstance()); + ability.addCost(new TapTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, false))); + ability.setAbilityWord(AbilityWord.MORBID); this.addAbility(ability); } @@ -84,30 +84,3 @@ public class SkirsdagHighPriest extends CardImpl { return new SkirsdagHighPriest(this); } } - -class SkirsdagHighPriestCost extends CostImpl { - - public SkirsdagHighPriestCost() { - this.text = "Activate this ability only if a creature died this turn"; - } - - public SkirsdagHighPriestCost(final SkirsdagHighPriestCost cost) { - super(cost); - } - - @Override - public SkirsdagHighPriestCost copy() { - return new SkirsdagHighPriestCost(this); - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return game.getState().getWatchers().get("Morbid").conditionMet(); - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) { - this.paid = true; - return paid; - } -} diff --git a/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java index 92799396ef5..db8e522dc02 100644 --- a/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java +++ b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java @@ -53,7 +53,7 @@ public class AlloyGolem extends CardImpl { // As Alloy Golem enters the battlefield, choose a color. // Alloy Golem is the chosen color. this.addAbility(new EntersBattlefieldAbility(new BecomesColorSourceEffect(Duration.WhileOnBattlefield), - null, true, "As {this} enters the battlefield, choose a color.\n{this} is the chosen color.", "")); + null, "As {this} enters the battlefield, choose a color.\n{this} is the chosen color.", "")); } public AlloyGolem(final AlloyGolem card) { diff --git a/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java index 8fb23c7cc30..eee53175131 100644 --- a/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java +++ b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java @@ -60,7 +60,7 @@ public class ArdentSoldier extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // If Ardent Soldier was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); } public ArdentSoldier(final ArdentSoldier card) { diff --git a/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java b/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java index 7fc7d46ab01..cb7bb39c3d8 100644 --- a/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java +++ b/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java @@ -61,7 +61,7 @@ public class BenalishLancer extends CardImpl { // If Benalish Lancer was kicked, it enters the battlefield with two +1/+1 counters on it and with first strike. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with first strike.", ""); ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/Duskwalker.java b/Mage.Sets/src/mage/sets/invasion/Duskwalker.java index fecf398f9ba..23923ab9284 100644 --- a/Mage.Sets/src/mage/sets/invasion/Duskwalker.java +++ b/Mage.Sets/src/mage/sets/invasion/Duskwalker.java @@ -61,7 +61,7 @@ public class Duskwalker extends CardImpl { // If Duskwalker was kicked, it enters the battlefield with two +1/+1 counters on it and with fear. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with fear.", ""); ability.addEffect(new GainAbilitySourceEffect(FearAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java index d463f15af2e..4d36fabfd90 100644 --- a/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java +++ b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java @@ -61,7 +61,7 @@ public class FaerieSquadron extends CardImpl { this.addAbility(new KickerAbility("{3}{U}")); // If Faerie Squadron was kicked, it enters the battlefield with two +1/+1 counters on it and with flying. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with flying.", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with flying.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java index b0ce21efa99..9b0aaa5aac9 100644 --- a/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java +++ b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java @@ -59,7 +59,7 @@ public class KavuAggressor extends CardImpl { this.addAbility(new CantBlockAbility()); // If Kavu Aggressor was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); } public KavuAggressor(final KavuAggressor card) { diff --git a/Mage.Sets/src/mage/sets/invasion/KavuTitan.java b/Mage.Sets/src/mage/sets/invasion/KavuTitan.java index 84a39593671..ed1da4b825d 100644 --- a/Mage.Sets/src/mage/sets/invasion/KavuTitan.java +++ b/Mage.Sets/src/mage/sets/invasion/KavuTitan.java @@ -60,7 +60,7 @@ public class KavuTitan extends CardImpl { this.addAbility(new KickerAbility("{2}{G}")); // If Kavu Titan was kicked, it enters the battlefield with three +1/+1 counters on it and with trample. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If Kavu Titan was kicked, it enters the battlefield with three +1/+1 counters on it and with trample.", ""); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/PhyrexianDelver.java b/Mage.Sets/src/mage/sets/invasion/PhyrexianDelver.java index eb4c4a5174d..1178f5af64c 100644 --- a/Mage.Sets/src/mage/sets/invasion/PhyrexianDelver.java +++ b/Mage.Sets/src/mage/sets/invasion/PhyrexianDelver.java @@ -98,7 +98,7 @@ class PhyrexianDelverEffect extends OneShotEffect { if (creatureCard != null && controller != null) { boolean result = false; if (game.getState().getZone(creatureCard.getId()).equals(Zone.GRAVEYARD)) { - result = controller.putOntoBattlefieldWithInfo(creatureCard, game, Zone.GRAVEYARD, source.getSourceId()); + result = controller.moveCards(creatureCard, Zone.BATTLEFIELD, source, game);; } controller.loseLife(creatureCard.getManaCost().convertedManaCost(), game); return result; diff --git a/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java b/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java index 966430d562d..3793017ef35 100644 --- a/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java +++ b/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java @@ -64,7 +64,7 @@ public class PouncingKavu extends CardImpl { this.addAbility(FirstStrikeAbility.getInstance()); // If Pouncing Kavu was kicked, it enters the battlefield with two +1/+1 counters on it and with haste. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with haste.", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with haste.", ""); ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java index e28139b407a..a50a302bef4 100644 --- a/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java +++ b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java @@ -64,7 +64,7 @@ public class PrisonBarricade extends CardImpl { this.addAbility(new KickerAbility("{1}{W}")); // If Prison Barricade was kicked, it enters the battlefield with a +1/+1 counter on it and with "Prison Barricade can attack as though it didn't have defender." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/TeferisResponse.java b/Mage.Sets/src/mage/sets/invasion/TeferisResponse.java new file mode 100644 index 00000000000..57e5f15db4f --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/TeferisResponse.java @@ -0,0 +1,113 @@ +/* + * 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.sets.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterStackObject; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.TargetStackObject; + +/** + * + * @author AlumiuN + */ +public class TeferisResponse extends CardImpl { + + private final static FilterStackObject filter = new FilterStackObject("spell or ability an opponent controls that targets a land you control"); + + static { + filter.add(new TargetsPermanentPredicate(new FilterControlledLandPermanent())); + } + + public TeferisResponse(UUID ownerId) { + super(ownerId, 78, "Teferi's Response", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "INV"; + + // Counter target spell or ability an opponent controls that targets a land you control. If a permanent's ability is countered this way, destroy that permanent. + this.getSpellAbility().addEffect(new TeferisResponseEffect()); + this.getSpellAbility().addTarget(new TargetStackObject(filter)); + + // Draw two cards. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + } + + public TeferisResponse(final TeferisResponse card) { + super(card); + } + + @Override + public TeferisResponse copy() { + return new TeferisResponse(this); + } +} + +class TeferisResponseEffect extends OneShotEffect { + + public TeferisResponseEffect() { + super(Outcome.Detriment); + this.staticText = "Counter target spell or ability an opponent controls that targets a land you control. If a permanent's ability is countered this way, destroy that permanent"; + } + + public TeferisResponseEffect(final TeferisResponseEffect effect) { + super(effect); + } + + @Override + public TeferisResponseEffect copy() { + return new TeferisResponseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID targetId = source.getFirstTarget(); + StackObject stackObject = game.getStack().getStackObject(targetId); + if (targetId != null && game.getStack().counter(targetId, source.getSourceId(), game)) { + UUID permanentId = stackObject.getSourceId(); + if (permanentId != null) { + Permanent usedPermanent = game.getPermanent(permanentId); + if (usedPermanent != null) { + usedPermanent.destroy(source.getSourceId(), game, false); + } + } + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/invasion/ThicketElemental.java b/Mage.Sets/src/mage/sets/invasion/ThicketElemental.java index 142a7b4fc14..e669ddd5ade 100644 --- a/Mage.Sets/src/mage/sets/invasion/ThicketElemental.java +++ b/Mage.Sets/src/mage/sets/invasion/ThicketElemental.java @@ -67,7 +67,7 @@ public class ThicketElemental extends CardImpl { // When Thicket Elemental enters the battlefield, if it was kicked, you may reveal cards from the top of your library until you reveal a creature card. If you do, put that card onto the battlefield and shuffle all other cards revealed this way into your library. TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ThicketElementalEffect()); this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), - "When {this} enters the battlefield, if it was kicked, you may reveal cards from the top of your library until you reveal a creature card. If you do, put that card onto the battlefield and shuffle all other cards revealed this way into your library.")); + "When {this} enters the battlefield, if it was kicked, you may reveal cards from the top of your library until you reveal a creature card. If you do, put that card onto the battlefield and shuffle all other cards revealed this way into your library.")); } public ThicketElemental(final ThicketElemental card) { @@ -82,8 +82,6 @@ public class ThicketElemental extends CardImpl { class ThicketElementalEffect extends OneShotEffect { - - public ThicketElementalEffect() { super(Outcome.Benefit); staticText = "if {this} was kicked, reveal cards from the top of your library until you reveal a creature card. Put that card onto the battlefield and shuffle all other cards revealed this way into your library"; @@ -102,15 +100,13 @@ class ThicketElementalEffect extends OneShotEffect { while (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card.getCardType().contains(CardType.CREATURE)) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; } revealedCards.add(card); } - controller.revealCards("ThicketElemental", revealedCards, game); - for (Card card: revealedCards.getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + controller.revealCards(sourceObject.getIdName(), revealedCards, game); + controller.moveCards(revealedCards, Zone.LIBRARY, source, game); controller.shuffleLibrary(game); return true; } @@ -121,4 +117,4 @@ class ThicketElementalEffect extends OneShotEffect { public ThicketElementalEffect copy() { return new ThicketElementalEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java b/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java index 6a5a08663fd..a729cf2c00c 100644 --- a/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java +++ b/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java @@ -68,7 +68,7 @@ public class UrborgSkeleton extends CardImpl { // If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it. Ability ability = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(),false, staticText,""); + KickedCondition.getInstance(), staticText,""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java b/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java index 02703289141..44d4bd6a633 100644 --- a/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java +++ b/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java @@ -62,7 +62,7 @@ public class VodalianSerpent extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackUnlessDefenderControllsPermanent(new FilterLandPermanent("Island", "an Island")))); // If Vodalian Serpent was kicked, it enters the battlefield with four +1/+1 counters on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); } public VodalianSerpent(final VodalianSerpent card) { diff --git a/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java b/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java index ef7d31f7976..de36fde3e17 100644 --- a/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java +++ b/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java @@ -30,8 +30,7 @@ package mage.sets.jacevsvraska; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; import mage.cards.Card; @@ -40,10 +39,8 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; @@ -63,11 +60,7 @@ public class BodyDouble extends CardImpl { this.toughness = new MageInt(0); // You may have Body Double enter the battlefield as a copy of any creature card in a graveyard. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new BodyDoubleCopyEffect(), - "You may have {this} enter the battlefield as a copy of any creature card in a graveyard", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new BodyDoubleCopyEffect(), true)); } @@ -85,7 +78,7 @@ class BodyDoubleCopyEffect extends OneShotEffect { public BodyDoubleCopyEffect() { super(Outcome.Copy); - this.staticText = "You may have {this} enter the battlefield as a copy of any creature card in a graveyard"; + this.staticText = "as a copy of any creature card in a graveyard"; } public BodyDoubleCopyEffect(final BodyDoubleCopyEffect effect) { @@ -95,8 +88,7 @@ class BodyDoubleCopyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (player != null && sourcePermanent != null) { + if (player != null) { Target target = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); target.setNotTarget(true); if (target.canChoose(source.getControllerId(), game)) { diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java index 82266793698..2fce108dbb9 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java @@ -30,11 +30,10 @@ package mage.sets.journeyintonyx; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -62,7 +61,7 @@ public class AjaniMentorOfHeroes extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control"); private static final FilterCard filterCard = new FilterCard("an Aura, creature, or planeswalker card"); - + static { filter.add(new ControllerPredicate(TargetController.YOU)); filterCard.add(Predicates.or( @@ -70,23 +69,22 @@ public class AjaniMentorOfHeroes extends CardImpl { new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.PLANESWALKER))); } - + public AjaniMentorOfHeroes(UUID ownerId) { super(ownerId, 145, "Ajani, Mentor of Heroes", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{G}{W}"); this.expansionSetCode = "JOU"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Distribute three +1/+1 counters among one, two, or three target creatures you control Ability ability = new LoyaltyAbility(new AjaniMentorOfHeroesAddCountersEffect(), 1); ability.addTarget(new TargetCreaturePermanentAmount(3, filter)); this.addAbility(ability); - + // +1: Look at the top four cards of your library. You may reveal an Aura, creature, or planeswalker card from among them and put that card into your hand. Put the rest on the bottom of your library in any order. - this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4,1, filterCard,true, false, Zone.HAND, true), 1)); - + this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4, 1, filterCard, true, false, Zone.HAND, true), 1)); + // -8: You gain 100 life. this.addAbility(new LoyaltyAbility(new GainLifeEffect(100), -8)); } @@ -122,7 +120,7 @@ class AjaniMentorOfHeroesAddCountersEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && source.getTargets().size() > 0) { Target multiTarget = source.getTargets().get(0); - for (UUID target: multiTarget.getTargets()) { + for (UUID target : multiTarget.getTargets()) { Permanent permanent = game.getPermanent(target); if (permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java b/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java index c5b745b5894..31e52d06b4a 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java @@ -89,7 +89,7 @@ public class BloodcrazedHoplite extends CardImpl { class BloodcrazedHopliteTriggeredAbility extends TriggeredAbilityImpl { public BloodcrazedHopliteTriggeredAbility() { - super(Zone.BATTLEFIELD, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); + super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); } public BloodcrazedHopliteTriggeredAbility(BloodcrazedHopliteTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java b/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java index 6fb34b789b2..6423e7622b4 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/HallOfTriumph.java @@ -33,9 +33,8 @@ import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseColorEffect; import mage.cards.CardImpl; -import mage.choices.ChoiceColor; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -46,8 +45,6 @@ import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; - /** * @@ -61,7 +58,7 @@ public class HallOfTriumph extends CardImpl { this.supertype.add("Legendary"); // As Hall of Triumph enters the battlefield choose a color. - this.addAbility(new AsEntersBattlefieldAbility(new HallOfTriumphEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // Creatures you control of the chosen color get +1/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HallOfTriumphBoostControlledEffect())); } @@ -76,45 +73,6 @@ public class HallOfTriumph extends CardImpl { } } -class HallOfTriumphEffect extends OneShotEffect { - - public HallOfTriumphEffect() { - super(Outcome.BoostCreature); - staticText = "choose a color"; - } - - public HallOfTriumphEffect(final HallOfTriumphEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - ChoiceColor colorChoice = new ChoiceColor(); - colorChoice.setMessage("Choose color"); - while (!player.choose(Outcome.BoostCreature, colorChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - if (colorChoice.getChoice() != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice()); - game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); - } - } - return false; - } - - @Override - public HallOfTriumphEffect copy() { - return new HallOfTriumphEffect(this); - } - -} - class HallOfTriumphBoostControlledEffect extends ContinuousEffectImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); @@ -137,7 +95,7 @@ class HallOfTriumphBoostControlledEffect extends ContinuousEffectImpl { public boolean apply(Game game, Ability source) { ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); if (color != null) { - for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { if (perm.getColor(game).shares(color)) { perm.addPower(1); perm.addToughness(1); diff --git a/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java b/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java index f832cbe3df9..c95149465dd 100644 --- a/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java +++ b/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java @@ -37,8 +37,9 @@ import mage.abilities.costs.common.ExileSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -51,7 +52,6 @@ import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.players.Player; - /** * * @author LevelX2 @@ -75,7 +75,7 @@ public class BalthorTheDefiled extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BalthorTheDefiledEffect(), new ManaCostsImpl("{B}{B}{B}")); ability.addCost(new ExileSourceCost()); this.addAbility(ability); - + } public BalthorTheDefiled(final BalthorTheDefiled card) { @@ -98,32 +98,32 @@ class BalthorTheDefiledEffect extends OneShotEffect { new ColorPredicate(ObjectColor.RED))); } - public BalthorTheDefiledEffect() { + public BalthorTheDefiledEffect() { super(Outcome.Detriment); this.staticText = "Each player returns all black and all red creature cards from his or her graveyard to the battlefield"; } - public BalthorTheDefiledEffect(final BalthorTheDefiledEffect effect) { + public BalthorTheDefiledEffect(final BalthorTheDefiledEffect effect) { super(effect); } @Override - public BalthorTheDefiledEffect copy() { - return new BalthorTheDefiledEffect(this); + public BalthorTheDefiledEffect copy() { + return new BalthorTheDefiledEffect(this); } @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + Cards cardsToReturn = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); - } + cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game)); } } + controller.moveCards(cardsToReturn.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/judgment/IronshellBeetle.java b/Mage.Sets/src/mage/sets/judgment/IronshellBeetle.java new file mode 100644 index 00000000000..b914f9ad59c --- /dev/null +++ b/Mage.Sets/src/mage/sets/judgment/IronshellBeetle.java @@ -0,0 +1,68 @@ +/* + * 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.sets.judgment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class IronshellBeetle extends CardImpl { + + public IronshellBeetle(UUID ownerId) { + super(ownerId, 121, "Ironshell Beetle", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "JUD"; + this.subtype.add("Insect"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Ironshell Beetle enters the battlefield, put a +1/+1 counter on target creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public IronshellBeetle(final IronshellBeetle card) { + super(card); + } + + @Override + public IronshellBeetle copy() { + return new IronshellBeetle(this); + } +} diff --git a/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java b/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java index ea74b1f8925..692fc29a17e 100644 --- a/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java +++ b/Mage.Sets/src/mage/sets/judgment/WorldgorgerDragon.java @@ -27,6 +27,8 @@ */ package mage.sets.judgment; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.MageObject; @@ -44,10 +46,10 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.ExileZone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.util.CardUtil; @@ -94,6 +96,7 @@ class WorldgorgerDragonEntersEffect extends OneShotEffect { static { filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new AnotherPredicate()); } public WorldgorgerDragonEntersEffect() { @@ -112,11 +115,9 @@ class WorldgorgerDragonEntersEffect extends OneShotEffect { if (controller != null) { UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); if (exileId != null) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { - if (!permanent.getId().equals(source.getSourceId())) { // Another - controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); - } - } + Set cardsToExile = new LinkedHashSet<>(); + cardsToExile.addAll(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)); + controller.moveCardsToExile(cardsToExile, source, game, true, exileId, sourceObject.getIdName()); return true; } } @@ -148,14 +149,7 @@ class WorldgorgerDragonLeavesEffect extends OneShotEffect { int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter)); if (exile != null) { - exile = exile.copy(); - for (UUID cardId : exile) { - Card card = game.getCard(cardId); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - } - return true; + return controller.moveCards(exile.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); } } return false; diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java b/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java index 115370c7f92..4a11b9fbfdc 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/AshcloudPhoenix.java @@ -64,13 +64,13 @@ public class AshcloudPhoenix extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // When Ashcloud Phoenix dies, return it to the battlefield face down under your control. this.addAbility(new DiesTriggeredAbility(new AshcloudPhoenixEffect())); - + // Morph {4}{R}{R} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{4}{R}{R}"))); - + // When Ashcloud Phoenix is turned face up, it deals 2 damage to each player. Effect effect = new DamagePlayersEffect(2, TargetController.ANY); effect.setText("it deals 2 damage to each player"); @@ -88,30 +88,30 @@ public class AshcloudPhoenix extends CardImpl { } class AshcloudPhoenixEffect extends OneShotEffect { - + AshcloudPhoenixEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "return it to the battlefield face down under your control"; } - + AshcloudPhoenixEffect(final AshcloudPhoenixEffect effect) { super(effect); } - + @Override public AshcloudPhoenixEffect copy() { return new AshcloudPhoenixEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Card card = game.getCard(source.getSourceId()); if (card != null) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null && owner.getGraveyard().contains(card.getId())) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), false, true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, true, false, null); } } return true; diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java b/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java index 87503dfe207..2a058c4e4bf 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java @@ -29,13 +29,11 @@ package mage.sets.khansoftarkir; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; /** @@ -53,10 +51,7 @@ public class CleverImpersonator extends CardImpl { this.toughness = new MageInt(0); // You may have Clever Impersonator enter the battlefield as a copy of any nonland permanent on the battlefield. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new FilterNonlandPermanent()), - "You may have {this} enter the battlefield as a copy of any nonland permanent on the battlefield", - true))); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(new FilterNonlandPermanent()), true)); } public CleverImpersonator(final CleverImpersonator card) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/HardenedScales.java b/Mage.Sets/src/mage/sets/khansoftarkir/HardenedScales.java index 3ecbf0b73e9..a83fa7b78be 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/HardenedScales.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/HardenedScales.java @@ -53,7 +53,6 @@ public class HardenedScales extends CardImpl { super(ownerId, 133, "Hardened Scales", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{G}"); this.expansionSetCode = "KTK"; - // If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HardenedScalesEffect())); @@ -70,6 +69,7 @@ public class HardenedScales extends CardImpl { } class HardenedScalesEffect extends ReplacementEffectImpl { + HardenedScalesEffect() { super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); staticText = "If one or more +1/+1 counters would be placed on a creature you control, that many plus one +1/+1 counters are placed on it instead"; @@ -86,17 +86,20 @@ class HardenedScalesEffect extends ReplacementEffectImpl { return false; } - @Override + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ADD_COUNTERS; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getData().equals(CounterType.P1P1.getName())) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null && target.getControllerId().equals(source.getControllerId()) - && target.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/KheruLichLord.java b/Mage.Sets/src/mage/sets/khansoftarkir/KheruLichLord.java index fa93f72f934..048f1d84fc0 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/KheruLichLord.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/KheruLichLord.java @@ -112,45 +112,41 @@ class KheruLichLordEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Cards cards = new CardsImpl(); - for (Card card : controller.getGraveyard().getCards(new FilterCreatureCard(), source.getSourceId(), source.getControllerId(), game)) { - cards.add(card.getId()); - } - - if (cards.size() > 0) { - Card card = cards.getRandom(game); - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + cards.addAll(controller.getGraveyard().getCards(new FilterCreatureCard(), source.getSourceId(), source.getControllerId(), game)); + Card card = cards.getRandom(game); + if (card != null) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { + FixedTarget fixedTarget = new FixedTarget(permanent, game); ContinuousEffect effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(permanent.getId())); + effect.setTargetPointer(fixedTarget); game.addEffect(effect, source); effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(permanent.getId())); + effect.setTargetPointer(fixedTarget); game.addEffect(effect, source); effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(permanent.getId())); + effect.setTargetPointer(fixedTarget); game.addEffect(effect, source); ExileTargetEffect exileEffect = new ExileTargetEffect(); - exileEffect.setTargetPointer(new FixedTarget(permanent.getId())); + exileEffect.setTargetPointer(fixedTarget); DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); delayedAbility.setSourceObject(source.getSourceObject(game), game); game.addDelayedTriggeredAbility(delayedAbility); - KheruLichLordReplacementEffect replacementEffect = new KheruLichLordReplacementEffect(); - replacementEffect.setTargetPointer(new FixedTarget(permanent.getId())); + KheruLichLordReplacementEffect replacementEffect = new KheruLichLordReplacementEffect(); + replacementEffect.setTargetPointer(fixedTarget); game.addEffect(replacementEffect, source); - } } return true; } - return false; } } @@ -183,11 +179,11 @@ class KheruLichLordReplacementEffect extends ReplacementEffectImpl { return true; } - @Override + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ZONE_CHANGE; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.ZONE_CHANGE diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/MeanderingTowershell.java b/Mage.Sets/src/mage/sets/khansoftarkir/MeanderingTowershell.java index 87bcfe85461..a51b22e36a8 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/MeanderingTowershell.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/MeanderingTowershell.java @@ -46,19 +46,21 @@ import mage.game.permanent.Permanent; import mage.players.Player; /** - * As Meandering Towershell returns to the battlefield because of the delayed triggered ability, - * you choose which opponent or opposing planeswalker it’s attacking. It doesn’t have to attack - * the same opponent or opposing planeswalker that it was when it was exiled. + * As Meandering Towershell returns to the battlefield because of the delayed + * triggered ability, you choose which opponent or opposing planeswalker it’s + * attacking. It doesn’t have to attack the same opponent or opposing + * planeswalker that it was when it was exiled. * - * If Meandering Towershell enters the battlefield attacking, it wasn’t declared as an attacking - * creature that turn. Abilities that trigger when a creature attacks, including its own triggered - * ability, won’t trigger. + * If Meandering Towershell enters the battlefield attacking, it wasn’t declared + * as an attacking creature that turn. Abilities that trigger when a creature + * attacks, including its own triggered ability, won’t trigger. * - * On the turn Meandering Towershell attacks and is exiled, raid abilities will see it as a creature - * that attacked. Conversely, on the turn Meandering Towershell enters the battlefield attacking, - * raid abilities will not. + * On the turn Meandering Towershell attacks and is exiled, raid abilities will + * see it as a creature that attacked. Conversely, on the turn Meandering + * Towershell enters the battlefield attacking, raid abilities will not. * - * If you attack with a Meandering Towershell that you don’t own, you’ll control it when it returns to the battlefield. + * If you attack with a Meandering Towershell that you don’t own, you’ll control + * it when it returns to the battlefield. * * @author LevelX2 */ @@ -75,7 +77,7 @@ public class MeanderingTowershell extends CardImpl { // Islandwalk this.addAbility(new IslandwalkAbility()); - // Whenever Meandering Towershell attacks, exile it. + // Whenever Meandering Towershell attacks, exile it. // Return it to the battlefield under your control tapped and attacking // at the beginning of the next declare attackers step on your next turn. this.addAbility(new AttacksTriggeredAbility(new MeanderingTowershellEffect(), false)); @@ -191,7 +193,7 @@ class MeanderingTowershellReturnEffect extends OneShotEffect { if (controller != null) { Card card = game.getCard(source.getSourceId()); if (card != null && game.getState().getZone(source.getSourceId()).equals(Zone.EXILED)) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); game.getCombat().addAttackingCreature(card.getId(), game); return true; } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java b/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java index cb84a4e3e85..c6d95ccf67b 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java @@ -34,13 +34,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfDrawTriggeredAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.HasteAbility; @@ -54,7 +53,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; @@ -71,16 +69,16 @@ public class SarkhanTheDragonspeaker extends CardImpl { this.expansionSetCode = "KTK"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, Sarkhan, the Dragonspeaker becomes a legendary 4/4 red Dragon creature with flying, indestructible, and haste. this.addAbility(new LoyaltyAbility(new SarkhanTheDragonspeakerEffect(), 1)); - + // -3: Sarkhan, the Dragonspeaker deals 4 damage to target creature. LoyaltyAbility ability = new LoyaltyAbility(new DamageTargetEffect(4), -3); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // -6: You get an emblem with "At the beginning of your draw step, draw two additional cards" and "At the beginning of your end step, discard your hand." Effect effect = new GetEmblemEffect(new SarkhanTheDragonspeakerEmblem()); effect.setText("You get an emblem with \"At the beginning of your draw step, draw two additional cards\" and \"At the beginning of your end step, discard your hand.\""); @@ -98,7 +96,7 @@ public class SarkhanTheDragonspeaker extends CardImpl { } class SarkhanTheDragonspeakerEffect extends ContinuousEffectImpl { - + SarkhanTheDragonspeakerEffect() { super(Duration.EndOfTurn, Outcome.BecomeCreature); staticText = "Until end of turn, {this} becomes a legendary 4/4 red Dragon creature with flying, indestructible, and haste."; @@ -112,7 +110,7 @@ class SarkhanTheDragonspeakerEffect extends ContinuousEffectImpl { public SarkhanTheDragonspeakerEffect copy() { return new SarkhanTheDragonspeakerEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java b/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java index bf66ae2db31..75c2c3dc55b 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SeeTheUnwritten.java @@ -47,8 +47,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; - - /** * * @author LevelX2 @@ -59,15 +57,14 @@ public class SeeTheUnwritten extends CardImpl { super(ownerId, 149, "See the Unwritten", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{4}{G}{G}"); this.expansionSetCode = "KTK"; - // Reveal the top eight cards of your library. You may put a creature card from among them onto the battlefield. Put the rest into your graveyard. // Ferocious - If you control a creature with power 4 or greater, you may put two creature cards onto the battlefield instead of one. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( new SeeTheUnwrittenEffect(1), - new SeeTheUnwrittenEffect(2), + new SeeTheUnwrittenEffect(2), new InvertCondition(FerociousCondition.getInstance()), - "Reveal the top eight cards of your library. You may put a creature card from among them onto the battlefield. Put the rest into your graveyard." + - "
Ferocious — If you control a creature with power 4 or greater, you may put two creature cards onto the battlefield instead of one" )); + "Reveal the top eight cards of your library. You may put a creature card from among them onto the battlefield. Put the rest into your graveyard." + + "
Ferocious — If you control a creature with power 4 or greater, you may put two creature cards onto the battlefield instead of one")); } public SeeTheUnwritten(final SeeTheUnwritten card) { @@ -89,9 +86,9 @@ class SeeTheUnwrittenEffect extends OneShotEffect { public SeeTheUnwrittenEffect(int numberOfCardsToPutIntoPlay) { super(Outcome.DrawCard); this.numberOfCardsToPutIntoPlay = numberOfCardsToPutIntoPlay; - this.staticText = "Reveal the top eight cards of your library. You may put " + - (numberOfCardsToPutIntoPlay == 1 ? "a creature card":"two creature cards") + - " from among them onto the battlefield. Put the rest into your graveyard"; + this.staticText = "Reveal the top eight cards of your library. You may put " + + (numberOfCardsToPutIntoPlay == 1 ? "a creature card" : "two creature cards") + + " from among them onto the battlefield. Put the rest into your graveyard"; } public SeeTheUnwrittenEffect(final SeeTheUnwrittenEffect effect) { @@ -126,24 +123,24 @@ class SeeTheUnwrittenEffect extends OneShotEffect { if (!cards.isEmpty()) { controller.revealCards(sourceObject.getName(), cards, game); if (creatureCardsFound > 0 && controller.chooseUse(outcome, "Put creature(s) into play?", source, game)) { - int cardsToChoose = Math.min(numberOfCardsToPutIntoPlay, creatureCardsFound); + int cardsToChoose = Math.min(numberOfCardsToPutIntoPlay, creatureCardsFound); TargetCard target = new TargetCard(cardsToChoose, cardsToChoose, Zone.LIBRARY, filter); if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) { - for(UUID creatureId: target.getTargets()) { + for (UUID creatureId : target.getTargets()) { Card card = game.getCard(creatureId); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } } - controller.moveCards(cards, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(cards, Zone.GRAVEYARD, source, game); } return true; } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java b/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java index 835039e8420..c12ea7c75ef 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java @@ -32,14 +32,13 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.SacrificeEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; @@ -48,12 +47,10 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.command.Emblem; import mage.game.permanent.token.Token; - /** * * @author LevelX2 @@ -65,8 +62,7 @@ public class SorinSolemnVisitor extends CardImpl { this.expansionSetCode = "KTK"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until your next turn, creatures you control get +1/+0 and gain lifelink. Effect effect = new BoostControlledEffect(1, 0, Duration.UntilYourNextTurn, new FilterCreaturePermanent()); @@ -94,18 +90,22 @@ public class SorinSolemnVisitor extends CardImpl { return new SorinSolemnVisitor(this); } } + /** - * Emblem: "At the beginning of each opponent's upkeep, that player sacrifices a creature." + * Emblem: "At the beginning of each opponent's upkeep, that player sacrifices a + * creature." */ class SorinEmblem extends Emblem { + public SorinEmblem() { this.setName("EMBLEM: Sorin, Solemn Visitor"); - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, new SacrificeEffect(new FilterCreaturePermanent(),1 ,"that player"), TargetController.OPPONENT, false, true); + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, new SacrificeEffect(new FilterCreaturePermanent(), 1, "that player"), TargetController.OPPONENT, false, true); this.getAbilities().add(ability); } } class SorinSolemnVisitorVampireToken extends Token { + SorinSolemnVisitorVampireToken() { super("Vampire", "a 2/2 black Vampire creature token with flying"); setOriginalExpansionSetCode("KTK"); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java b/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java index d319410e590..cc33f764fd9 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java @@ -68,7 +68,6 @@ public class WarNameAspirant extends CardImpl { // Raid - War-Name Aspirant 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.getInstance(), - true, "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/sets/legends/ArenaOfTheAncients.java b/Mage.Sets/src/mage/sets/legends/ArenaOfTheAncients.java index c5564f03ead..c8d98544ed1 100644 --- a/Mage.Sets/src/mage/sets/legends/ArenaOfTheAncients.java +++ b/Mage.Sets/src/mage/sets/legends/ArenaOfTheAncients.java @@ -32,7 +32,7 @@ public class ArenaOfTheAncients extends CardImpl { } public ArenaOfTheAncients(UUID ownerId) { - super(ownerId, 215, "Arena Of The Ancients", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); + super(ownerId, 215, "Arena of the Ancients", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); this.expansionSetCode = "LEG"; // When Arena of the Ancients enters the battlefield, tap all Legendary creatures diff --git a/Mage.Sets/src/mage/sets/legends/AvoidFate.java b/Mage.Sets/src/mage/sets/legends/AvoidFate.java new file mode 100644 index 00000000000..457ace9b738 --- /dev/null +++ b/Mage.Sets/src/mage/sets/legends/AvoidFate.java @@ -0,0 +1,73 @@ +/* + * 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.sets.legends; + +import java.util.UUID; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.target.TargetSpell; + +/** + * + * @author LoneFox + */ +public class AvoidFate extends CardImpl { + + private final static FilterSpell filter = new FilterSpell("instant or Aura spell that targets a permanent you control"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new SubtypePredicate("Aura"))); + filter.add(new TargetsPermanentPredicate(new FilterControlledPermanent())); + } + + public AvoidFate(UUID ownerId) { + super(ownerId, 89, "Avoid Fate", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); + this.expansionSetCode = "LEG"; + + // Counter target instant or Aura spell that targets a permanent you control. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + } + + public AvoidFate(final AvoidFate card) { + super(card); + } + + @Override + public AvoidFate copy() { + return new AvoidFate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/legends/RingOfImmortals.java b/Mage.Sets/src/mage/sets/legends/RingOfImmortals.java new file mode 100644 index 00000000000..4679b275d39 --- /dev/null +++ b/Mage.Sets/src/mage/sets/legends/RingOfImmortals.java @@ -0,0 +1,80 @@ +/* + * 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.sets.legends; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.target.TargetSpell; + +/** + * + * @author LoneFox + */ +public class RingOfImmortals extends CardImpl { + + private final static FilterSpell filter = new FilterSpell("instant or Aura spell that targets a permanent you control"); + + static { + filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new SubtypePredicate("Aura"))); + filter.add(new TargetsPermanentPredicate(new FilterControlledPermanent())); + } + + public RingOfImmortals(UUID ownerId) { + super(ownerId, 238, "Ring of Immortals", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{5}"); + this.expansionSetCode = "LEG"; + + // {3}, {tap}: Counter target instant or Aura spell that targets a permanent you control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{3}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetSpell(filter)); + this.addAbility(ability); + } + + public RingOfImmortals(final RingOfImmortals card) { + super(card); + } + + @Override + public RingOfImmortals copy() { + return new RingOfImmortals(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java b/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java index 3ab1fcca736..2852b95626f 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java @@ -70,15 +70,14 @@ public class AnimateDead extends CardImpl { this.expansionSetCode = "LEA"; this.subtype.add("Aura"); - // Enchant creature card in a graveyard TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AnimateDeadAttachEffect(Outcome.PutCreatureInPlay)); Ability enchantAbility = new EnchantAbility(auraTarget.getTargetName()); - this.addAbility(enchantAbility); - // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" - // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield + this.addAbility(enchantAbility); + // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" + // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield // under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new AnimateDeadReAttachEffect(), false), @@ -86,11 +85,11 @@ public class AnimateDead extends CardImpl { "When {this} enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with {this}.\" Return enchanted creature card to the battlefield under your control and attach {this} to it."); ability.addEffect(new AnimateDeadChangeAbilityEffect()); this.addAbility(ability); - this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false)); - + this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false)); + // Enchanted creature gets -1/-0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(-1, 0, Duration.WhileOnBattlefield))); - + } public AnimateDead(final AnimateDead card) { @@ -104,36 +103,36 @@ public class AnimateDead extends CardImpl { } class AnimateDeadReAttachEffect extends OneShotEffect { - + public AnimateDeadReAttachEffect() { super(Outcome.Benefit); this.staticText = "Return enchanted creature card to the battlefield under your control and attach {this} to it"; } - + public AnimateDeadReAttachEffect(final AnimateDeadReAttachEffect effect) { super(effect); } - + @Override public AnimateDeadReAttachEffect copy() { return new AnimateDeadReAttachEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent enchantment = game.getPermanent(source.getSourceId()); - + if (controller != null && enchantment != null) { Card cardInGraveyard = game.getCard(enchantment.getAttachedTo()); if (cardInGraveyard == null) { return true; } - + // put card into play - controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(cardInGraveyard, Zone.BATTLEFIELD, source, game); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); - + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); Target target = new TargetCreaturePermanent(filter); @@ -146,27 +145,27 @@ class AnimateDeadReAttachEffect extends OneShotEffect { } return true; } - + return false; } } - + class AnimateDeadLeavesBattlefieldTriggeredEffect extends OneShotEffect { - + public AnimateDeadLeavesBattlefieldTriggeredEffect() { super(Outcome.Benefit); this.staticText = "enchanted creature's controller sacrifices it"; } - + public AnimateDeadLeavesBattlefieldTriggeredEffect(final AnimateDeadLeavesBattlefieldTriggeredEffect effect) { super(effect); } - + @Override public AnimateDeadLeavesBattlefieldTriggeredEffect copy() { return new AnimateDeadLeavesBattlefieldTriggeredEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -223,17 +222,16 @@ class AnimateDeadAttachEffect extends OneShotEffect { class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements SourceEffect { private final static Ability newAbility = new EnchantAbility("creature put onto the battlefield with Animate Dead"); - + static { newAbility.setRuleAtTheTop(true); } - + public AnimateDeadChangeAbilityEffect() { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); staticText = "it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead\""; } - public AnimateDeadChangeAbilityEffect(final AnimateDeadChangeAbilityEffect effect) { super(effect); } @@ -242,7 +240,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou public AnimateDeadChangeAbilityEffect copy() { return new AnimateDeadChangeAbilityEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); @@ -254,7 +252,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou Permanent permanent = affectedObjectList.get(0).getPermanent(game); if (permanent != null) { Ability abilityToRemove = null; - for (Ability ability: permanent.getAbilities()) { + for (Ability ability : permanent.getAbilities()) { if (ability instanceof EnchantAbility) { abilityToRemove = ability; } @@ -264,7 +262,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou } permanent.addAbility(newAbility, source.getSourceId(), game); return true; - } + } return false; } } diff --git a/Mage.Sets/src/mage/sets/limitedalpha/BlackVise.java b/Mage.Sets/src/mage/sets/limitedalpha/BlackVise.java index 057ebaa541b..82e9d7e9b09 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/BlackVise.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/BlackVise.java @@ -32,6 +32,7 @@ import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseOpponentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -40,9 +41,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetOpponent; /** * @@ -55,7 +54,7 @@ public class BlackVise extends CardImpl { this.expansionSetCode = "LEA"; // As Black Vise enters the battlefield, choose an opponent. - this.addAbility(new AsEntersBattlefieldAbility(new BlackViseChooseOpponent())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseOpponentEffect(Outcome.Detriment))); // At the beginning of the chosen player's upkeep, Black Vise deals X damage to that player, where X is the number of cards in his or her hand minus 4. this.addAbility(new BlackViseTriggeredAbility()); } @@ -70,42 +69,6 @@ public class BlackVise extends CardImpl { } } -class BlackViseChooseOpponent extends OneShotEffect { - - public BlackViseChooseOpponent() { - super(Outcome.Neutral); - this.staticText = "choose an opponent"; - } - - public BlackViseChooseOpponent(final BlackViseChooseOpponent effect) { - super(effect); - } - - @Override - public BlackViseChooseOpponent copy() { - return new BlackViseChooseOpponent(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetOpponent target = new TargetOpponent(); - target.setNotTarget(true); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class BlackViseTriggeredAbility extends TriggeredAbilityImpl { public BlackViseTriggeredAbility() { @@ -128,19 +91,19 @@ class BlackViseTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - return event.getPlayerId().equals(game.getState().getValue(getSourceId().toString() + "_player")); + return event.getPlayerId().equals(game.getState().getValue(getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY)); } @Override public String getRule() { - return new StringBuilder("At the beginning of the chosen player's upkeep, ").append(super.getRule()).toString(); + return "At the beginning of the chosen player's upkeep, " + super.getRule(); } } class BlackViseEffect extends OneShotEffect { public BlackViseEffect() { - super(Outcome.Benefit); + super(Outcome.Detriment); this.staticText = "{this} deals X damage to that player, where X is the number of cards in his or her hand minus 4"; } @@ -155,7 +118,7 @@ class BlackViseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - UUID playerId = (UUID) game.getState().getValue(source.getSourceId().toString() + "_player"); + UUID playerId = (UUID) game.getState().getValue(source.getSourceId().toString() + ChooseOpponentEffect.VALUE_KEY); Player chosenPlayer = game.getPlayer(playerId); if (chosenPlayer != null) { int damage = chosenPlayer.getHand().size() - 4; diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Chaoslace.java b/Mage.Sets/src/mage/sets/limitedalpha/Chaoslace.java new file mode 100644 index 00000000000..0c9258bab69 --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedalpha/Chaoslace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedalpha; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Chaoslace extends mage.sets.fourthedition.Chaoslace { + + public Chaoslace(UUID ownerId) { + super(ownerId); + this.cardNumber = 140; + this.expansionSetCode = "LEA"; + } + + public Chaoslace(final Chaoslace card) { + super(card); + } + + @Override + public Chaoslace copy() { + return new Chaoslace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java index b1a99b0e249..d783513396a 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java @@ -28,24 +28,14 @@ package mage.sets.limitedalpha; import java.util.UUID; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; -import mage.util.functions.ApplyToPermanent; +import mage.filter.common.FilterArtifactPermanent; +import mage.util.functions.CardTypeApplier; /** * @@ -59,11 +49,9 @@ public class CopyArtifact extends CardImpl { this.expansionSetCode = "LEA"; // You may have Copy Artifact enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyArtifactEffect(), - "You may have {this} enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types", - true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterArtifactPermanent(), new CardTypeApplier(CardType.ENCHANTMENT)); + effect.setText("as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public CopyArtifact(final CopyArtifact card) { @@ -75,64 +63,3 @@ public class CopyArtifact extends CardImpl { return new CopyArtifact(this); } } - -class CopyArtifactEffect extends OneShotEffect { - - ApplyToPermanent applier = new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { - permanent.getCardType().add(CardType.ENCHANTMENT); - } - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getCardType().contains(CardType.ENCHANTMENT)) { - mageObject.getCardType().add(CardType.ENCHANTMENT); - } - return true; - } - - }; - - private static final FilterPermanent filter = new FilterPermanent("artifact"); - - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - - public CopyArtifactEffect() { - super(Outcome.Copy); - } - - public CopyArtifactEffect(final CopyArtifactEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(filter); - target.setNotTarget(true); - if (target.canChoose(source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, applier); - return true; - } - } - } - return false; - } - - @Override - public CopyArtifactEffect copy() { - return new CopyArtifactEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Deathlace.java b/Mage.Sets/src/mage/sets/limitedalpha/Deathlace.java new file mode 100644 index 00000000000..15a9f297430 --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedalpha/Deathlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedalpha; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Deathlace extends mage.sets.limitedbeta.Deathlace { + + public Deathlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 10; + this.expansionSetCode = "LEA"; + } + + public Deathlace(final Deathlace card) { + super(card); + } + + @Override + public Deathlace copy() { + return new Deathlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Lifelace.java b/Mage.Sets/src/mage/sets/limitedalpha/Lifelace.java new file mode 100644 index 00000000000..f01f6e6ae90 --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedalpha/Lifelace.java @@ -0,0 +1,62 @@ +/* + * 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.sets.limitedalpha; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author AlumiuN + */ +public class Lifelace extends CardImpl { + + public Lifelace(UUID ownerId) { + super(ownerId, 116, "Lifelace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{G}"); + this.expansionSetCode = "LEA"; + + // Target spell or permanent becomes green. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.GREEN, Duration.Custom)); + } + + public Lifelace(final Lifelace card) { + super(card); + } + + @Override + public Lifelace copy() { + return new Lifelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/PhantasmalTerrain.java b/Mage.Sets/src/mage/sets/limitedalpha/PhantasmalTerrain.java index f38d3ea0f7d..d7de486907b 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/PhantasmalTerrain.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/PhantasmalTerrain.java @@ -28,13 +28,12 @@ package mage.sets.limitedalpha; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ChooseBasicLandTypeEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlueManaAbility; @@ -42,7 +41,6 @@ import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.WhiteManaAbility; import mage.cards.CardImpl; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -52,7 +50,6 @@ import mage.constants.SubLayer; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetLandPermanent; @@ -72,10 +69,10 @@ public class PhantasmalTerrain extends CardImpl { this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); this.addAbility(new EnchantAbility(auraTarget.getTargetName())); - + // As Phantasmal Terrain enters the battlefield, choose a basic land type. - this.addAbility(new AsEntersBattlefieldAbility(new PhantasmalTerrainChooseEffect())); - + this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral))); + // Enchanted land is the chosen type. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PhantasmalTerrainContinuousEffect())); } @@ -90,52 +87,13 @@ public class PhantasmalTerrain extends CardImpl { } } -class PhantasmalTerrainChooseEffect extends OneShotEffect { - - public PhantasmalTerrainChooseEffect() { - super(Outcome.Neutral); - this.staticText = "choose a basic land type"; - } - - public PhantasmalTerrainChooseEffect(final PhantasmalTerrainChooseEffect effect) { - super(effect); - } - - @Override - public PhantasmalTerrainChooseEffect copy() { - return new PhantasmalTerrainChooseEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && controller != null) { - ChoiceImpl choices = new ChoiceImpl(true); - choices.setMessage("Choose basic land type"); - choices.getChoices().add("Forest"); - choices.getChoices().add("Plains"); - choices.getChoices().add("Mountain"); - choices.getChoices().add("Island"); - choices.getChoices().add("Swamp"); - if (controller.choose(Outcome.Neutral, choices, game)) { - game.informPlayers(sourceObject.getLogName() + ": chosen basic land type is " + choices.getChoice()); - game.getState().setValue(source.getSourceId().toString() + "_PhantasmalTerrain", choices.getChoice()); - return true; - } - } - return false; - } - -} - class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl { - public PhantasmalTerrainContinuousEffect(){ + public PhantasmalTerrainContinuousEffect() { super(Duration.WhileOnBattlefield, Outcome.Neutral); this.staticText = "enchanted land is the chosen type"; } - + public PhantasmalTerrainContinuousEffect(final PhantasmalTerrainContinuousEffect effect) { super(effect); } @@ -148,7 +106,7 @@ class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - String choice = (String) game.getState().getValue(source.getSourceId().toString() + "_PhantasmalTerrain"); + String choice = (String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY); if (enchantment != null && enchantment.getAttachedTo() != null && choice != null) { Permanent land = game.getPermanent(enchantment.getAttachedTo()); if (land != null) { @@ -195,5 +153,5 @@ class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl { public boolean hasLayer(Layer layer) { return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; } - + } diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Purelace.java b/Mage.Sets/src/mage/sets/limitedalpha/Purelace.java new file mode 100644 index 00000000000..3651a9766cf --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedalpha/Purelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedalpha; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Purelace extends mage.sets.unlimitededition.Purelace { + + public Purelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 216; + this.expansionSetCode = "LEA"; + } + + public Purelace(final Purelace card) { + super(card); + } + + @Override + public Purelace copy() { + return new Purelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Thoughtlace.java b/Mage.Sets/src/mage/sets/limitedalpha/Thoughtlace.java new file mode 100644 index 00000000000..e426d3ec9fb --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedalpha/Thoughtlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedalpha; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Thoughtlace extends mage.sets.limitedbeta.Thoughtlace { + + public Thoughtlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 83; + this.expansionSetCode = "LEA"; + } + + public Thoughtlace(final Thoughtlace card) { + super(card); + } + + @Override + public Thoughtlace copy() { + return new Thoughtlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedbeta/Chaoslace.java b/Mage.Sets/src/mage/sets/limitedbeta/Chaoslace.java new file mode 100644 index 00000000000..5dd7ab9c797 --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedbeta/Chaoslace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedbeta; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Chaoslace extends mage.sets.fourthedition.Chaoslace { + + public Chaoslace(UUID ownerId) { + super(ownerId); + this.cardNumber = 141; + this.expansionSetCode = "LEB"; + } + + public Chaoslace(final Chaoslace card) { + super(card); + } + + @Override + public Chaoslace copy() { + return new Chaoslace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedbeta/Deathlace.java b/Mage.Sets/src/mage/sets/limitedbeta/Deathlace.java new file mode 100644 index 00000000000..568c4641561 --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedbeta/Deathlace.java @@ -0,0 +1,62 @@ +/* + * 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.sets.limitedbeta; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author AlumiuN + */ +public class Deathlace extends CardImpl { + + public Deathlace(UUID ownerId) { + super(ownerId, 10, "Deathlace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{B}"); + this.expansionSetCode = "LEB"; + + // Target spell or permanent becomes black. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.Custom)); + } + + public Deathlace(final Deathlace card) { + super(card); + } + + @Override + public Deathlace copy() { + return new Deathlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedbeta/Lifelace.java b/Mage.Sets/src/mage/sets/limitedbeta/Lifelace.java new file mode 100644 index 00000000000..e19cd0970da --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedbeta/Lifelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedbeta; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Lifelace extends mage.sets.limitedalpha.Lifelace { + + public Lifelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 116; + this.expansionSetCode = "LEB"; + } + + public Lifelace(final Lifelace card) { + super(card); + } + + @Override + public Lifelace copy() { + return new Lifelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedbeta/Purelace.java b/Mage.Sets/src/mage/sets/limitedbeta/Purelace.java new file mode 100644 index 00000000000..bc81190443e --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedbeta/Purelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.limitedbeta; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Purelace extends mage.sets.unlimitededition.Purelace { + + public Purelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 218; + this.expansionSetCode = "LEB"; + } + + public Purelace(final Purelace card) { + super(card); + } + + @Override + public Purelace copy() { + return new Purelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/limitedbeta/Thoughtlace.java b/Mage.Sets/src/mage/sets/limitedbeta/Thoughtlace.java new file mode 100644 index 00000000000..0b91774b4df --- /dev/null +++ b/Mage.Sets/src/mage/sets/limitedbeta/Thoughtlace.java @@ -0,0 +1,62 @@ +/* + * 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.sets.limitedbeta; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author AlumiuN + */ +public class Thoughtlace extends CardImpl { + + public Thoughtlace(UUID ownerId) { + super(ownerId, 83, "Thoughtlace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{U}"); + this.expansionSetCode = "LEB"; + + // Target spell or permanent becomes blue. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.BLUE, Duration.Custom)); + } + + public Thoughtlace(final Thoughtlace card) { + super(card); + } + + @Override + public Thoughtlace copy() { + return new Thoughtlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java b/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java index f3ceefded0e..719016c9804 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java +++ b/Mage.Sets/src/mage/sets/lorwyn/IncandescentSoulstoke.java @@ -128,7 +128,7 @@ class IncandescentSoulstokeEffect extends OneShotEffect { if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); diff --git a/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java b/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java index f53660bf0f0..f123146b6a8 100644 --- a/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java +++ b/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,15 +20,26 @@ * 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.sets.magic2010; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.Effects; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,19 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effects; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; @@ -68,7 +66,7 @@ public class AjaniGoldmane extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Ajani"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: You gain 2 life. this.addAbility(new LoyaltyAbility(new GainLifeEffect(2), 1)); @@ -136,4 +134,4 @@ class AvatarTokenEffect extends ContinuousEffectImpl { return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java b/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java index e795ef55dc2..b1ced672549 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java +++ b/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,17 +20,17 @@ * 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.sets.magic2010; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.dynamicvalue.DynamicValue; @@ -38,18 +38,14 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.target.TargetPlayer; import mage.target.common.TargetCreaturePermanent; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com, nantuko @@ -61,8 +57,7 @@ public class ChandraNalaar extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); ability1.addTarget(new TargetPlayer()); @@ -98,7 +93,7 @@ class ChandraNalaarXValue implements DynamicValue { public int calculate(Game game, Ability sourceAbility, Effect effect) { for (Cost cost : sourceAbility.getCosts()) { if (cost instanceof PayVariableLoyaltyCost) { - return ((PayVariableLoyaltyCost)cost).getAmount(); + return ((PayVariableLoyaltyCost) cost).getAmount(); } } return 0; @@ -123,4 +118,3 @@ class ChandraNalaarXValue implements DynamicValue { return defaultValue; } } - diff --git a/Mage.Sets/src/mage/sets/magic2010/ConvincingMirage.java b/Mage.Sets/src/mage/sets/magic2010/ConvincingMirage.java index 5ee4db516fb..9049656edd4 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ConvincingMirage.java +++ b/Mage.Sets/src/mage/sets/magic2010/ConvincingMirage.java @@ -27,21 +27,13 @@ */ package mage.sets.magic2010; -import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ChooseBasicLandTypeEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.BlueManaAbility; @@ -49,10 +41,15 @@ import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.RedManaAbility; import mage.abilities.mana.WhiteManaAbility; import mage.cards.CardImpl; -import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetLandPermanent; @@ -67,13 +64,12 @@ public class ConvincingMirage extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Aura"); - // Enchant land TargetPermanent auraTarget = new TargetLandPermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); // As Convincing Mirage enters the battlefield, choose a basic land type. - this.addAbility(new AsEntersBattlefieldAbility(new ConvincingMirageEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral))); // Enchanted land is the chosen type. Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); @@ -90,42 +86,6 @@ public class ConvincingMirage extends CardImpl { } } -class ConvincingMirageEffect extends OneShotEffect { - - public ConvincingMirageEffect() { - super(Outcome.Neutral); - this.staticText = "choose a basic land type"; - } - - public ConvincingMirageEffect(final ConvincingMirageEffect effect) { - super(effect); - } - - @Override - public ConvincingMirageEffect copy() { - return new ConvincingMirageEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - ChoiceImpl choices = new ChoiceImpl(true); - Set choicesSet = choices.getChoices(); - choicesSet.add("Forest"); - choicesSet.add("Plains"); - choicesSet.add("Mountain"); - choicesSet.add("Island"); - choicesSet.add("Swamp"); - if (player.choose(Outcome.Neutral, choices, game)) { - game.getState().setValue(source.getSourceId().toString() + "_ConvincingMirage", choices.getChoice()); - return true; - } - } - return false; - } -} - class ConvincingMirageContinousEffect extends ContinuousEffectImpl { public ConvincingMirageContinousEffect() { @@ -145,7 +105,7 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Permanent enchantment = game.getPermanent(source.getSourceId()); - String choice = (String) game.getState().getValue(source.getSourceId().toString() + "_ConvincingMirage"); + String choice = (String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY); if (enchantment != null && enchantment.getAttachedTo() != null && choice != null) { Permanent land = game.getPermanent(enchantment.getAttachedTo()); if (land != null) { @@ -160,19 +120,19 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl { if (sublayer == SubLayer.NA) { land.getAbilities().clear(); if (choice.equals("Forest")) { - land.addAbility(new GreenManaAbility(), game); + land.addAbility(new GreenManaAbility(), source.getSourceId(), game); } if (choice.equals("Plains")) { - land.addAbility(new WhiteManaAbility(), game); + land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); } if (choice.equals("Mountain")) { - land.addAbility(new RedManaAbility(), game); + land.addAbility(new RedManaAbility(), source.getSourceId(), game); } if (choice.equals("Island")) { - land.addAbility(new BlueManaAbility(), game); + land.addAbility(new BlueManaAbility(), source.getSourceId(), game); } if (choice.equals("Swamp")) { - land.addAbility(new BlackManaAbility(), game); + land.addAbility(new BlackManaAbility(), source.getSourceId(), game); } } break; @@ -192,4 +152,4 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl { public boolean hasLayer(Layer layer) { return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java b/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java index 1ad585e45f5..ea454dc5cdb 100644 --- a/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java +++ b/Mage.Sets/src/mage/sets/magic2010/DjinnOfWishes.java @@ -105,7 +105,7 @@ class DjinnOfWishesEffect extends OneShotEffect { Card card = player.getLibrary().getFromTop(game); Cards cards = new CardsImpl(); cards.add(card); - player.revealCards("Djinn Of Wishes", cards, game); + player.revealCards("Djinn of Wishes", cards, game); player.getLibrary().removeFromTop(game); diff --git a/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java b/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java index 7c35ee12a38..9a3ddef6c26 100644 --- a/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java +++ b/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java @@ -1,49 +1,46 @@ /* -* 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. -*/ - + * 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.sets.magic2010; import java.util.UUID; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.BeastToken; import mage.target.common.TargetLandPermanent; @@ -61,8 +58,7 @@ public class GarrukWildspeaker extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Garruk"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Untap two target lands. LoyaltyAbility ability1 = new LoyaltyAbility(new UntapTargetEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2010/HiveMind.java b/Mage.Sets/src/mage/sets/magic2010/HiveMind.java index b33a3c8e8a2..36d56343ed8 100644 --- a/Mage.Sets/src/mage/sets/magic2010/HiveMind.java +++ b/Mage.Sets/src/mage/sets/magic2010/HiveMind.java @@ -27,9 +27,7 @@ */ package mage.sets.magic2010; -import java.util.Set; import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; @@ -130,13 +128,12 @@ class HiveMindEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Spell spell; spell = game.getStack().getSpell(((FixedTarget) getTargetPointer()).getTarget()); - if (spell == null) { // if spell e.g. was countered + if (spell == null) { // if spell e.g. was countered spell = (Spell) game.getLastKnownInformation(((FixedTarget) getTargetPointer()).getTarget(), Zone.STACK); } Player player = game.getPlayer(source.getControllerId()); if (spell != null && player != null) { - Set players = player.getInRange(); - for (UUID playerId : players) { + for (UUID playerId : game.getState().getPlayersInRange(player.getId(), game)) { if (!playerId.equals(spell.getControllerId())) { Spell copy = spell.copySpell(); copy.setControllerId(playerId); diff --git a/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java b/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java index fcd4938b0e1..b5566671786 100644 --- a/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java +++ b/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,25 +20,22 @@ * 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.sets.magic2010; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.target.TargetPlayer; /** @@ -52,9 +49,9 @@ public class JaceBeleren extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - // +2: Each player draws a card. + // +2: Each player draws a card. this.addAbility(new LoyaltyAbility(new DrawCardAllEffect(1), 2)); // -1: Target player draws a card. diff --git a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java index 5f955caa787..7ab2a913ae9 100644 --- a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java +++ b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java @@ -32,9 +32,8 @@ import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; import mage.cards.Card; @@ -43,7 +42,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; @@ -60,7 +58,7 @@ public class LilianaVess extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Liliana"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Target player discards a card. LoyaltyAbility ability1 = new LoyaltyAbility(new DiscardTargetEffect(1), 1); ability1.addTarget(new TargetPlayer()); diff --git a/Mage.Sets/src/mage/sets/magic2010/OpenTheVaults.java b/Mage.Sets/src/mage/sets/magic2010/OpenTheVaults.java index 7b44f6e0f01..192c5d22db8 100644 --- a/Mage.Sets/src/mage/sets/magic2010/OpenTheVaults.java +++ b/Mage.Sets/src/mage/sets/magic2010/OpenTheVaults.java @@ -27,18 +27,17 @@ */ package mage.sets.magic2010; -import java.util.LinkedList; -import java.util.Set; +import java.util.LinkedHashSet; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -52,7 +51,6 @@ public class OpenTheVaults extends CardImpl { super(ownerId, 21, "Open the Vaults", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{W}{W}"); this.expansionSetCode = "M10"; - // Return all artifact and enchantment cards from all graveyards to the battlefield under their owners' control. this.getSpellAbility().addEffect(new OpenTheVaultsEffect()); } @@ -85,33 +83,21 @@ class OpenTheVaultsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - LinkedList enchantments = new LinkedList(); - LinkedList artifacts = new LinkedList(); - - Set playerIds = player.getInRange(); - playerIds.add(player.getId()); - - for (UUID playerId : playerIds) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + LinkedHashSet cardsToReturn = new LinkedHashSet<>(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Cards graveyard = game.getPlayer(playerId).getGraveyard(); for (UUID cardId : graveyard) { Card card = game.getCard(cardId); - if (card != null && card.getCardType().contains(CardType.ENCHANTMENT)) { - enchantments.add(card); - } - if (card != null && card.getCardType().contains(CardType.ARTIFACT)) { - artifacts.add(card); + if (card != null + && (card.getCardType().contains(CardType.ENCHANTMENT) || card.getCardType().contains(CardType.ARTIFACT))) { + cardsToReturn.add(card); } } } - - for (Card card : enchantments) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), card.getOwnerId()); - } - for (Card card : artifacts) { - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), card.getOwnerId()); - } + controller.moveCards(cardsToReturn, Zone.BATTLEFIELD, source, game, false, false, true, null); + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java b/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java index 595a34013f8..c76befa295f 100644 --- a/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java +++ b/Mage.Sets/src/mage/sets/magic2010/SphinxAmbassador.java @@ -95,16 +95,16 @@ class SphinxAmbassadorEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player != null && targetPlayer != null && sourcePermanent != null) { + if (controller != null && targetPlayer != null && sourcePermanent != null) { TargetCardInLibrary target = new TargetCardInLibrary(); - player.searchLibrary(target, game, targetPlayer.getId()); + controller.searchLibrary(target, game, targetPlayer.getId()); Card card = game.getCard(target.getFirstTarget()); if (card != null) { - TreeSet choices = new TreeSet(); + TreeSet choices = new TreeSet<>(); Collection cards = game.getCards(); for (Card gameCard : cards) { if (gameCard.getOwnerId().equals(targetPlayer.getId())) { @@ -124,8 +124,8 @@ class SphinxAmbassadorEffect extends OneShotEffect { game.informPlayers(new StringBuilder(sourcePermanent.getName()).append(", named card: [").append(cardName).append("]").toString()); if (!card.getName().equals(cardName) && card.getCardType().contains(CardType.CREATURE)) { - if (player.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append(" onto the battlefield?").toString(), source, game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + if (controller.chooseUse(outcome, new StringBuilder("Put ").append(card.getName()).append(" onto the battlefield?").toString(), source, game)) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/magic2011/Cultivate.java b/Mage.Sets/src/mage/sets/magic2011/Cultivate.java index b68d4a6bdeb..d8b36c43345 100644 --- a/Mage.Sets/src/mage/sets/magic2011/Cultivate.java +++ b/Mage.Sets/src/mage/sets/magic2011/Cultivate.java @@ -111,17 +111,17 @@ class CultivateEffect extends OneShotEffect { controller.choose(Outcome.Benefit, revealed, target2, game); Card card = revealed.get(target2.getFirstTarget(), game); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); revealed.remove(card); } card = revealed.getCards(game).iterator().next(); if (card != null) { - controller.moveCards(card, null, Zone.HAND, source, game); + controller.moveCards(card, Zone.HAND, source, game); } } else if (target.getTargets().size() == 1) { Card card = revealed.getCards(game).iterator().next(); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); } } diff --git a/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java b/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java index 484242f65d6..8e61bb1817f 100644 --- a/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java +++ b/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,12 +20,11 @@ * 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.sets.magic2011; import java.util.UUID; @@ -100,10 +99,7 @@ class InfernoTitanAbility extends TriggeredAbilityImpl { if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) { return true; } - if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - return true; - } - return false; + return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java b/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java index 58a741397a3..d9cdc57cb98 100644 --- a/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java +++ b/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,12 +20,11 @@ * 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.sets.magic2011; import java.util.UUID; @@ -86,7 +85,7 @@ public class NecroticPlague extends CardImpl { Effect effect = new GainAbilityAttachedEffect(gainedAbility, AttachmentType.AURA, Duration.WhileOnBattlefield); effect.setText("Enchanted creature has \"At the beginning of your upkeep, sacrifice this creature.\""); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - this.addAbility(new DiesAttachedTriggeredAbility(new NecroticPlagueEffect(),"enchanted creature", false)); + this.addAbility(new DiesAttachedTriggeredAbility(new NecroticPlagueEffect(), "enchanted creature", false)); } @@ -94,7 +93,7 @@ public class NecroticPlague extends CardImpl { public void adjustTargets(Ability ability, Game game) { if (ability instanceof DiesAttachedTriggeredAbility) { Permanent attachedTo = null; - for (Effect effect :ability.getEffects()) { + for (Effect effect : ability.getEffects()) { attachedTo = (Permanent) effect.getValue("attachedTo"); } if (attachedTo != null) { @@ -122,8 +121,6 @@ public class NecroticPlague extends CardImpl { class NecroticPlagueEffect extends OneShotEffect { - - public NecroticPlagueEffect() { super(Outcome.PutCardInPlay); staticText = "its controller chooses target creature one of his or her opponents controls. Return {this} from its owner's graveyard to the battlefield attached to that creature"; @@ -143,7 +140,7 @@ class NecroticPlagueEffect extends OneShotEffect { Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (sourceEnchantmentCard != null && creature != null) { game.getState().setValue("attachTo:" + sourceEnchantmentCard.getId(), creature); - creatureController.putOntoBattlefieldWithInfo(sourceEnchantmentCard, game, Zone.GRAVEYARD, source.getSourceId()); + creatureController.moveCards(sourceEnchantmentCard, Zone.BATTLEFIELD, source, game); return creature.addAttachment(sourceEnchantmentCard.getId(), game); } } diff --git a/Mage.Sets/src/mage/sets/magic2011/PhylacteryLich.java b/Mage.Sets/src/mage/sets/magic2011/PhylacteryLich.java index a42e28768db..6cf3a7c7243 100644 --- a/Mage.Sets/src/mage/sets/magic2011/PhylacteryLich.java +++ b/Mage.Sets/src/mage/sets/magic2011/PhylacteryLich.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,19 +20,14 @@ * 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.sets.magic2011; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.StateTriggeredAbility; @@ -41,6 +36,10 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.Counter; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -64,8 +63,13 @@ public class PhylacteryLich extends CardImpl { this.power = new MageInt(5); this.toughness = new MageInt(5); - this.addAbility(new AsEntersBattlefieldAbility(new PhylacteryLichEffect(), "put a phylactery counter on an artifact you control")); + // Indestructible this.addAbility(IndestructibleAbility.getInstance()); + + // As Phylactery Lich enters the battlefield, put a phylactery counter on an artifact you control. + this.addAbility(new AsEntersBattlefieldAbility(new PhylacteryLichEffect(), "put a phylactery counter on an artifact you control")); + + // When you control no permanents with phylactery counters on them, sacrifice Phylactery Lich. this.addAbility(new PhylacteryLichAbility()); } @@ -95,7 +99,7 @@ public class PhylacteryLich extends CardImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - for (Permanent perm: game.getBattlefield().getAllActivePermanents(controllerId)) { + for (Permanent perm : game.getBattlefield().getAllActivePermanents(controllerId)) { if (perm.getCounters().getCount("phylactery") > 0) { return false; } @@ -133,7 +137,7 @@ class PhylacteryLichEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(filter); + TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); if (target.canChoose(source.getControllerId(), game)) { if (player.choose(Outcome.Neutral, target, source.getSourceId(), game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); @@ -151,4 +155,4 @@ class PhylacteryLichEffect extends OneShotEffect { return new PhylacteryLichEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2011/SunTitan.java b/Mage.Sets/src/mage/sets/magic2011/SunTitan.java index 03f7d21a769..0b5c5660dc7 100644 --- a/Mage.Sets/src/mage/sets/magic2011/SunTitan.java +++ b/Mage.Sets/src/mage/sets/magic2011/SunTitan.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,12 +20,11 @@ * 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.sets.magic2011; import java.util.UUID; @@ -117,10 +116,7 @@ class SunTitanAbility extends TriggeredAbilityImpl { if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) { return true; } - if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - return true; - } - return false; + return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java b/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java index 3677a7b9cc7..1fd2d3f98a1 100644 --- a/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java +++ b/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java @@ -25,23 +25,20 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2012; import java.util.UUID; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyTargetSpellEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -55,22 +52,21 @@ import mage.target.targetpointer.FixedTarget; */ public class ChandraTheFirebrand extends CardImpl { - public ChandraTheFirebrand (UUID ownerId) { + public ChandraTheFirebrand(UUID ownerId) { super(ownerId, 124, "Chandra, the Firebrand", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{R}"); this.expansionSetCode = "M12"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Chandra, the Firebrand deals 1 damage to target creature or player. - LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); ability1.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability1); // -2: When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy. - Effect effect = new CreateDelayedTriggeredAbilityEffect(new ChandraTheFirebrandAbility()); - effect .setText("When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy"); + Effect effect = new CreateDelayedTriggeredAbilityEffect(new ChandraTheFirebrandAbility()); + effect.setText("When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy"); this.addAbility(new LoyaltyAbility(effect, -2)); // -6: Chandra, the Firebrand deals 6 damage to each of up to six target creatures and/or players @@ -79,7 +75,7 @@ public class ChandraTheFirebrand extends CardImpl { this.addAbility(ability2); } - public ChandraTheFirebrand (final ChandraTheFirebrand card) { + public ChandraTheFirebrand(final ChandraTheFirebrand card) { super(card); } @@ -91,6 +87,7 @@ public class ChandraTheFirebrand extends CardImpl { } class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { + ChandraTheFirebrandAbility() { super(new CopyTargetSpellEffect(), Duration.EndOfTurn); } @@ -111,11 +108,11 @@ class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getPlayerId().equals(this.getControllerId())) { + if (event.getPlayerId().equals(this.getControllerId())) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); + effect.setTargetPointer(new FixedTarget(event.getTargetId())); } return true; } @@ -127,4 +124,4 @@ class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { public String getRule() { return "When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java b/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java index 17c8316eca0..935f24def0f 100644 --- a/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java +++ b/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java @@ -25,23 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2012; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; @@ -56,20 +52,19 @@ import mage.players.Player; * @author Loki */ public class GarrukPrimalHunter extends CardImpl { - + private static final FilterControlledPermanent filter = new FilterControlledLandPermanent(); - public GarrukPrimalHunter (UUID ownerId) { + public GarrukPrimalHunter(UUID ownerId) { super(ownerId, 174, "Garruk, Primal Hunter", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{G}{G}"); this.expansionSetCode = "M12"; this.subtype.add("Garruk"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Put a 3/3 green Beast creature token onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new BeastToken()), 1)); - + // -3: Draw cards equal to the greatest power among creatures you control. this.addAbility(new LoyaltyAbility(new GarrukPrimalHunterEffect(), -3)); @@ -77,7 +72,7 @@ public class GarrukPrimalHunter extends CardImpl { this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WurmToken(), new PermanentsOnBattlefieldCount(filter)), -6)); } - public GarrukPrimalHunter (final GarrukPrimalHunter card) { + public GarrukPrimalHunter(final GarrukPrimalHunter card) { super(card); } @@ -89,6 +84,7 @@ public class GarrukPrimalHunter extends CardImpl { } class GarrukPrimalHunterEffect extends OneShotEffect { + GarrukPrimalHunterEffect() { super(Outcome.DrawCard); staticText = "Draw cards equal to the greatest power among creatures you control"; diff --git a/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java b/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java index 58b5b0f98c3..2e687f4f8cb 100644 --- a/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java +++ b/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java @@ -27,24 +27,21 @@ */ package mage.sets.magic2012; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.Mode; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; -import java.util.UUID; - /** * @author nantuko */ @@ -55,8 +52,7 @@ public class JaceMemoryAdept extends CardImpl { this.expansionSetCode = "M12"; this.subtype.add("Jace"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Draw a card. Target player puts the top card of his or her library into his or her graveyard. LoyaltyAbility ability1 = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); @@ -116,5 +112,3 @@ class JaceMemoryAdeptEffect extends DrawCardTargetEffect { return new JaceMemoryAdeptEffect(this); } } - - diff --git a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java index 82de7d6d4e8..23ede410e11 100644 --- a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java +++ b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java @@ -30,23 +30,17 @@ package mage.sets.magic2012; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.common.BecomesTargetTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; /** @@ -55,7 +49,31 @@ import mage.util.functions.ApplyToPermanent; */ public class PhantasmalImage extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it gains \"When this creature becomes the target of a spell or ability, sacrifice it.\""; + private static final String effectText = "a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it gains \"When this creature becomes the target of a spell or ability, sacrifice it.\""; + + ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() { + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSubtype().contains("Illusion")) { + permanent.getSubtype().add("Illusion"); + } + // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities + permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); + //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSubtype().contains("Illusion")) { + mageObject.getSubtype().add("Illusion"); + } + // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities + mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); + //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); + return true; + } + }; public PhantasmalImage(UUID ownerId) { super(ownerId, 72, "Phantasmal Image", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}"); @@ -69,9 +87,9 @@ public class PhantasmalImage extends CardImpl { // You may have Phantasmal Image enter the battlefield as a copy of any creature // on the battlefield, except it's an Illusion in addition to its other types and // it gains "When this creature becomes the target of a spell or ability, sacrifice it." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new PhantasmalImageCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), phantasmalImageApplier); + effect.setText(effectText); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public PhantasmalImage(final PhantasmalImage card) { @@ -83,62 +101,3 @@ public class PhantasmalImage extends CardImpl { return new PhantasmalImage(this); } } - -class PhantasmalImageCopyEffect extends OneShotEffect { - - public PhantasmalImageCopyEffect() { - super(Outcome.Copy); - } - - public PhantasmalImageCopyEffect(final PhantasmalImageCopyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)")); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSubtype().contains("Illusion")) { - permanent.getSubtype().add("Illusion"); - } - // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities - permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); - //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSubtype().contains("Illusion")) { - mageObject.getSubtype().add("Illusion"); - } - // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities - mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); - //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); - return true; - } - - }); - - return true; - } - } - } - return false; - } - - @Override - public PhantasmalImageCopyEffect copy() { - return new PhantasmalImageCopyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java b/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java index 42a2b16593f..6f651062b5e 100644 --- a/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java +++ b/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java @@ -27,6 +27,7 @@ */ package mage.sets.magic2012; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -38,15 +39,19 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.constants.*; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; -import java.util.UUID; - /** * @author nantuko */ @@ -97,30 +102,32 @@ class SuturedGhoulEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player.getGraveyard().size() > 0) { - + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent == null) { + return false; + } + if (controller.getGraveyard().size() > 0) { TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard")); - if (player.chooseTarget(Outcome.Benefit, target, source, game)) { + if (controller.chooseTarget(Outcome.Benefit, target, source, game)) { int count = 0; for (UUID uuid : target.getTargets()) { - Card card = player.getGraveyard().get(uuid, game); + Card card = controller.getGraveyard().get(uuid, game); if (card != null) { - card.moveToExile(getId(), "Sutured Ghoul", source.getSourceId(), game); - if (permanent != null) { - permanent.imprint(card.getId(), game); - count++; - } + card.moveToExile(getId(), permanent.getIdName(), source.getSourceId(), game); + permanent.imprint(card.getId(), game); + count++; } } + Cards cardsToExile = new CardsImpl(target.getTargets()); + controller.moveCards(cardsToExile, null, Zone.EXILED, source, game); String msg = count == 1 ? "1 card" : count + "cards"; - game.informPlayers("Sutured Ghoul: " + player.getLogName() + " exiled " + msg); + game.informPlayers(permanent.getLogName() + ": " + controller.getLogName() + " exiled " + msg); } } else { - game.informPlayers("Sutured Ghoul: No cards in graveyard."); + game.informPlayers(permanent.getLogName() + ": No cards in graveyard."); } return true; } @@ -147,7 +154,7 @@ class SuturedGhoulPowerCount implements DynamicValue { int amount = 0; Permanent permanent = game.getPermanent(sourceAbility.getSourceId()); if (permanent != null) { - for (UUID uuid: permanent.getImprinted()) { + for (UUID uuid : permanent.getImprinted()) { Card card = game.getCard(uuid); if (card != null) { amount += card.getPower().getValue(); @@ -189,7 +196,7 @@ class SuturedGhoulToughnessCount implements DynamicValue { int amount = 0; Permanent permanent = game.getPermanent(sourceAbility.getSourceId()); if (permanent != null) { - for (UUID uuid: permanent.getImprinted()) { + for (UUID uuid : permanent.getImprinted()) { Card card = game.getCard(uuid); if (card != null) { amount += card.getToughness().getValue(); @@ -214,5 +221,3 @@ class SuturedGhoulToughnessCount implements DynamicValue { return "the total toughness of the exiled cards"; } } - - diff --git a/Mage.Sets/src/mage/sets/magic2012/ThranGolem.java b/Mage.Sets/src/mage/sets/magic2012/ThranGolem.java index eb4d72649fe..b8e679ff356 100644 --- a/Mage.Sets/src/mage/sets/magic2012/ThranGolem.java +++ b/Mage.Sets/src/mage/sets/magic2012/ThranGolem.java @@ -28,13 +28,9 @@ package mage.sets.magic2012; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; import mage.abilities.condition.common.EnchantedCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -43,6 +39,10 @@ import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; /** * @@ -50,11 +50,6 @@ import mage.cards.CardImpl; */ public class ThranGolem extends CardImpl { - private static final String rule1 = "As long as {this} is enchanted, it gets +2/+2 "; - private static final String rule2 = "As long as {this} is enchanted, it has flying"; - private static final String rule3 = "As long as {this} is enchanted, it has first strike"; - private static final String rule4 = "As long as {this} is enchanted, it has flying trample"; - public ThranGolem(UUID ownerId) { super(ownerId, 220, "Thran Golem", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); this.expansionSetCode = "M12"; @@ -63,15 +58,18 @@ public class ThranGolem extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(3); - Condition enchanted = new EnchantedCondition(); - ConditionalContinuousEffect effect1 = new ConditionalContinuousEffect(new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), enchanted, rule1); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect1)); - ConditionalContinuousEffect effect2 = new ConditionalContinuousEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance()), enchanted, rule2); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect2)); - ConditionalContinuousEffect effect3 = new ConditionalContinuousEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), enchanted, rule3); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect3)); - ConditionalContinuousEffect effect4 = new ConditionalContinuousEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance()), enchanted, rule4); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect4)); + // As long as Thran Golem is enchanted, it gets +2/+2 and has flying, first strike, and trample. + EnchantedCondition enchanted = new EnchantedCondition(); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), enchanted, + "As long as {this} is enchanted, it gets +2/+2")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance()), + enchanted, "and has flying")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance()), + enchanted, ", first strike")); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance()), + enchanted, ", and trample.")); + this.addAbility(ability); } public ThranGolem(final ThranGolem card) { diff --git a/Mage.Sets/src/mage/sets/magic2012/Trollhide.java b/Mage.Sets/src/mage/sets/magic2012/Trollhide.java index 47337163b65..a62c43d19e5 100644 --- a/Mage.Sets/src/mage/sets/magic2012/Trollhide.java +++ b/Mage.Sets/src/mage/sets/magic2012/Trollhide.java @@ -29,18 +29,23 @@ package mage.sets.magic2012; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.RegenerateSourceEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -55,13 +60,20 @@ public class Trollhide extends CardImpl { this.expansionSetCode = "M12"; this.subtype.add("Aura"); + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{G}")), AttachmentType.AURA))); + + // Enchanted creature gets +2/+2 and has "{1}{G}: Regenerate this creature." + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new RegenerateSourceEffect(), new ManaCostsImpl("{1}{G}")), AttachmentType.AURA); + effect.setText("and has \"{1}{G}: Regenerate this creature.\""); + ability.addEffect(effect); + this.addAbility(ability); } public Trollhide (final Trollhide card) { diff --git a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java index 2575cf4bc83..43b20bce5ec 100644 --- a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java +++ b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java @@ -28,16 +28,14 @@ package mage.sets.magic2013; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.ControllerLifeCount; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; @@ -64,12 +62,12 @@ public class AjaniCallerOfThePride extends CardImpl { @Override public void build() { - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a +1/+1 counter on up to one target creature. Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setText("Put a +1/+1 counter on up to one target creature"); Ability ability = new LoyaltyAbility(effect, 1); - ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.addTarget(new TargetCreaturePermanent(0, 1)); this.addAbility(ability); // -3: Target creature gains flying and double strike until end of turn. Effects effects = new Effects(); diff --git a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java index b706cc764c0..2ae1156c849 100644 --- a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java +++ b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java @@ -28,6 +28,18 @@ package mage.sets.magic2013; import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,20 +48,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.common.FilterLandCard; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -78,8 +76,7 @@ public class LilianaOfTheDarkRealms extends CardImpl { this.expansionSetCode = "M13"; this.subtype.add("Liliana"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Search your library for a Swamp card, reveal it, and put it into your hand. Then shuffle your library. this.addAbility(new LoyaltyAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), 1)); diff --git a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java index 8c3d87f6aad..25de8f9d80e 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java @@ -33,12 +33,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -49,7 +48,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -74,7 +72,7 @@ public class ChandraPyromaster extends CardImpl { this.expansionSetCode = "M14"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn. LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java b/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java index 95ef1ee6103..d1aab901884 100644 --- a/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java +++ b/Mage.Sets/src/mage/sets/magic2014/DoorOfDestinies.java @@ -33,12 +33,9 @@ import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -57,7 +54,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.stack.Spell; -import mage.players.Player; /** * @@ -70,7 +66,8 @@ public class DoorOfDestinies extends CardImpl { this.expansionSetCode = "M14"; // As Door of Destinies enters the battlefield, choose a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature))); + // Whenever you cast a spell of the chosen type, put a charge counter on Door of Destinies. this.addAbility(new AddCounterAbility()); // Creatures you control of the chosen type get +1/+1 for each charge counter on Door of Destinies. @@ -87,44 +84,6 @@ public class DoorOfDestinies extends CardImpl { } } -class ChooseCreatureTypeEffect extends OneShotEffect { - - public ChooseCreatureTypeEffect() { - super(Outcome.BoostCreature); - staticText = "choose a creature type"; - } - - public ChooseCreatureTypeEffect(final ChooseCreatureTypeEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); - } - return false; - } - - @Override - public ChooseCreatureTypeEffect copy() { - return new ChooseCreatureTypeEffect(this); - } - -} - class AddCounterAbility extends TriggeredAbilityImpl { public AddCounterAbility() { diff --git a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java index 6cf8ee79c45..4784c9168fa 100644 --- a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java +++ b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java @@ -31,20 +31,18 @@ import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -69,11 +67,10 @@ public class GarrukCallerOfBeasts extends CardImpl { this.expansionSetCode = "M14"; this.subtype.add("Garruk"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Reveal the top 5 cards of your library. Put all creature cards revealed this way into your hand and the rest on the bottom of your library in any order. - this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("all creature cards"),true), 1)); + this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("all creature cards"), true), 1)); // -3: You may put a green creature card from your hand onto the battlefield. this.addAbility(new LoyaltyAbility(new PutPermanentOnBattlefieldEffect(filterGreenCreature), -3)); @@ -94,18 +91,20 @@ public class GarrukCallerOfBeasts extends CardImpl { } /** - * Emblem: "Whenever you cast a creature spell, you may search your library for a creature card, put it onto the battlefield, then shuffle your library." + * Emblem: "Whenever you cast a creature spell, you may search your library for + * a creature card, put it onto the battlefield, then shuffle your library." */ class GarrukCallerOfBeastsEmblem extends Emblem { private static final FilterSpell filter = new FilterSpell("a creature spell"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } public GarrukCallerOfBeastsEmblem() { this.setName("EMBLEM: Garruk, Caller of Beasts"); - Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterCreatureCard("creature card")),false, true, Outcome.PutCreatureInPlay); + Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterCreatureCard("creature card")), false, true, Outcome.PutCreatureInPlay); Ability ability = new SpellCastControllerTriggeredAbility(Zone.COMMAND, effect, filter, true, false); this.getAbilities().add(ability); } diff --git a/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java b/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java index 0a7c07a1299..fc3aca583e9 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java +++ b/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java @@ -39,6 +39,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -58,7 +59,7 @@ public class ImposingSovereign extends CardImpl { // Creatures your opponents control enter the battlefield tapped. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ImposingSovereignEffect())); - + } public ImposingSovereign(final ImposingSovereign card) { @@ -72,7 +73,7 @@ public class ImposingSovereign extends CardImpl { } class ImposingSovereignEffect extends ReplacementEffectImpl { - + ImposingSovereignEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Creatures your opponents control enter the battlefield tapped"; @@ -84,7 +85,7 @@ class ImposingSovereignEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.tap(game); } @@ -95,11 +96,11 @@ class ImposingSovereignEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java index fc7db630f25..3f129598184 100644 --- a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java +++ b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java @@ -50,6 +50,7 @@ import mage.constants.WatcherScope; import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Commander; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -314,7 +315,7 @@ class SavageSummoningEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } diff --git a/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java b/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java index b9283d50ea6..aee04861911 100644 --- a/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java +++ b/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java @@ -30,7 +30,7 @@ package mage.sets.magic2015; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.PreventionEffectImpl; @@ -38,7 +38,6 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.VigilanceAbility; @@ -66,22 +65,21 @@ import mage.target.common.TargetCreaturePermanent; public class AjaniSteadfast extends CardImpl { private static final FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent("other planeswalker you control"); - + static { filter.add(new AnotherPredicate()); filter.add(new ControllerPredicate(TargetController.YOU)); } - + public AjaniSteadfast(UUID ownerId) { super(ownerId, 1, "Ajani Steadfast", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{W}"); this.expansionSetCode = "M15"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, up to one target creature gets +1/+1 and gains first strike, vigilance, and lifelink. - Effect effect = new BoostTargetEffect(1,1, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("Until end of turn, up to one target creature gets +1/+1"); LoyaltyAbility ability = new LoyaltyAbility(effect, 1); effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); @@ -93,16 +91,16 @@ public class AjaniSteadfast extends CardImpl { effect = new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); effect.setText(", and lifelink"); ability.addEffect(effect); - ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.addTarget(new TargetCreaturePermanent(0, 1)); this.addAbility(ability); - + // -2: Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control. ability = new LoyaltyAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()), -2); effect = new AddCountersAllEffect(CounterType.LOYALTY.createInstance(), filter); effect.setText("and a loyalty counter on each other planeswalker you control"); ability.addEffect(effect); this.addAbility(ability); - + // -7: You get an emblem with "If a source would deal damage to you or a planeswalker you control, prevent all but 1 of that damage." this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new AjaniSteadfastEmblem()), -7)); } @@ -121,7 +119,7 @@ class AjaniSteadfastEmblem extends Emblem { public AjaniSteadfastEmblem() { setName("EMBLEM: Ajani Steadfast"); - this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new AjaniSteadfastPreventEffect())); + this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new AjaniSteadfastPreventEffect())); this.setExpansionSetCodeForImage("M15"); } } @@ -143,7 +141,7 @@ class AjaniSteadfastPreventEffect extends PreventionEffectImpl { int damage = event.getAmount(); if (damage > 1) { amountToPrevent = damage - 1; - preventDamageAction(event, source, game); + preventDamageAction(event, source, game); } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java b/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java index 12075176452..d5f432ff10e 100644 --- a/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java +++ b/Mage.Sets/src/mage/sets/magic2015/BoonweaverGiant.java @@ -97,8 +97,8 @@ class BoonweaverGiantEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } @@ -108,18 +108,18 @@ class BoonweaverGiantEffect extends OneShotEffect { Card card = null; Zone zone = null; - if (player.chooseUse(Outcome.Neutral, "Search your graveyard for an Aura card?", source, game)) { + if (controller.chooseUse(Outcome.Neutral, "Search your graveyard for an Aura card?", source, game)) { TargetCardInYourGraveyard target = new TargetCardInYourGraveyard(filter); - if (player.choose(Outcome.PutCardInPlay, player.getGraveyard(), target, game)) { + if (controller.choose(Outcome.PutCardInPlay, controller.getGraveyard(), target, game)) { card = game.getCard(target.getFirstTarget()); if (card != null) { zone = Zone.GRAVEYARD; } } } - if (card == null && player.chooseUse(Outcome.Neutral, "Search your Hand for an Aura card?", source, game)) { + if (card == null && controller.chooseUse(Outcome.Neutral, "Search your Hand for an Aura card?", source, game)) { TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutCardInPlay, player.getHand(), target, game)) { + if (controller.choose(Outcome.PutCardInPlay, controller.getHand(), target, game)) { card = game.getCard(target.getFirstTarget()); if (card != null) { zone = Zone.HAND; @@ -128,13 +128,13 @@ class BoonweaverGiantEffect extends OneShotEffect { } if (card == null) { TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { card = game.getCard(target.getFirstTarget()); if (card != null) { zone = Zone.LIBRARY; } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); } // aura card found - attach it if (card != null) { @@ -142,7 +142,7 @@ class BoonweaverGiantEffect extends OneShotEffect { if (permanent != null) { game.getState().setValue("attachTo:" + card.getId(), permanent); } - player.putOntoBattlefieldWithInfo(card, game, zone, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); if (permanent != null) { return permanent.addAttachment(card.getId(), game); } diff --git a/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java index 955c9019f01..dd839d19569 100644 --- a/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java +++ b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java @@ -32,7 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.AttackedByCreatureTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; @@ -50,7 +49,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; @@ -81,7 +79,7 @@ public class GarrukApexPredator extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Garruk"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Destroy another target planeswalker. LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java b/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java index 703a9f5a0cf..03eda36b2ff 100644 --- a/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java +++ b/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java @@ -131,7 +131,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } target1.clearChosen(); } else { @@ -140,11 +140,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect { } else { game.informPlayers("No nonland permanent card with converted mana cost " + count + " or less to choose."); } - while (cards.size() > 0) { - Card card = cards.get(cards.iterator().next(), game); - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + controller.moveCards(cards, Zone.LIBRARY, source, game); controller.shuffleLibrary(game); return true; } diff --git a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java index c644c080918..2938b8d6ca6 100644 --- a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java +++ b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java @@ -43,6 +43,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -108,7 +109,7 @@ class HushwingGryffEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Ability ability = (Ability) getValue("targetAbility"); if (ability != null && AbilityType.TRIGGERED.equals(ability.getAbilityType())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java b/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java index 964c2310133..7d4c32fbbaa 100644 --- a/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java +++ b/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java @@ -30,20 +30,18 @@ package mage.sets.magic2015; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; @@ -69,8 +67,7 @@ public class JaceTheLivingGuildpact extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Jace"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Look at the top two cards of your library. Put one of them into your graveyard. Effect effect = new LookLibraryAndPickControllerEffect( @@ -78,7 +75,7 @@ public class JaceTheLivingGuildpact extends CardImpl { effect.setText("Look at the top two cards of your library. Put one of them into your graveyard"); this.addAbility(new LoyaltyAbility(effect, 1)); - // -3: Return another target nonland permanent to its owner's hand. + // -3: Return another target nonland permanent to its owner's hand. LoyaltyAbility ability = new LoyaltyAbility(new ReturnToHandTargetEffect(), -3); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); @@ -113,15 +110,15 @@ class JaceTheLivingGuildpactEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getHand().getCards(game)) { + for (Card card : player.getHand().getCards(game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - for (Card card: player.getGraveyard().getCards(game)) { + } + for (Card card : player.getGraveyard().getCards(game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + } player.shuffleLibrary(game); } } diff --git a/Mage.Sets/src/mage/sets/magic2015/JaliraMasterPolymorphist.java b/Mage.Sets/src/mage/sets/magic2015/JaliraMasterPolymorphist.java index a9cd3d3260d..cc21944e5c5 100644 --- a/Mage.Sets/src/mage/sets/magic2015/JaliraMasterPolymorphist.java +++ b/Mage.Sets/src/mage/sets/magic2015/JaliraMasterPolymorphist.java @@ -132,10 +132,10 @@ class JaliraMasterPolymorphistEffect extends OneShotEffect { } while (library.size() > 0 && card != null && !filter.match(card, game)); // reveal cards if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getName(), cards, game); + controller.revealCards(sourceObject.getIdName(), cards, game); } // put nonlegendary creature card to battlefield - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); // remove it from revealed card list cards.remove(card); // Put the rest on the bottom of your library in a random order diff --git a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java index 1aa0cb0c7c6..fcfabc49c0f 100644 --- a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java +++ b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java @@ -29,25 +29,17 @@ package mage.sets.magic2015; import java.util.UUID; import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.util.functions.AbilityApplier; /** @@ -56,7 +48,7 @@ import mage.util.functions.AbilityApplier; */ public class MercurialPretender extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature you control except it gains \"{2}{U}{U}: Return this creature to its owner's hand.\""; + private static final String effectText = "as a copy of any creature you control except it gains \"{2}{U}{U}: Return this creature to its owner's hand.\""; public MercurialPretender(UUID ownerId) { super(ownerId, 68, "Mercurial Pretender", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{U}"); @@ -69,9 +61,10 @@ public class MercurialPretender extends CardImpl { // You may have Mercurial Pretender enter the battlefield as a copy of any creature you control // except it gains "{2}{U}{U}: Return this creature to its owner's hand." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new MercurialPretenderCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), + new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}")))); + effect.setText(effectText); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public MercurialPretender(final MercurialPretender card) { @@ -83,41 +76,3 @@ public class MercurialPretender extends CardImpl { return new MercurialPretender(this); } } - -class MercurialPretenderCopyEffect extends OneShotEffect { - - public MercurialPretenderCopyEffect() { - super(Outcome.Copy); - } - - public MercurialPretenderCopyEffect(final MercurialPretenderCopyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterControlledCreaturePermanent()); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, - // {2}{U}{U}: Return this creature to its owner's hand. - new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}"))) - ); - return true; - } - } - } - return false; - } - - @Override - public MercurialPretenderCopyEffect copy() { - return new MercurialPretenderCopyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java b/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java index 3c5177de393..c1fc0b51a84 100644 --- a/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java +++ b/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -46,13 +45,13 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterBasicLandCard; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; import mage.players.Player; import mage.target.TargetPermanent; @@ -79,9 +78,8 @@ public class NissaWorldwaker extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Nissa"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Target land you control becomes a 4/4 Elemental creature with trample. It's still a land. LoyaltyAbility ability = new LoyaltyAbility(new BecomesCreatureTargetEffect(new NissaWorldwakerToken(), false, true, Duration.Custom), 1); ability.addTarget(new TargetLandPermanent(filter)); @@ -89,11 +87,11 @@ public class NissaWorldwaker extends CardImpl { // +1: Untap up to four target Forests. ability = new LoyaltyAbility(new UntapTargetEffect(), 1); - ability.addTarget(new TargetPermanent(0,4,filterForest, false)); + ability.addTarget(new TargetPermanent(0, 4, filterForest, false)); this.addAbility(ability); // -7: Search your library for any number of basic land cards, put them onto the battlefield, then shuffle your library. Those lands become 4/4 Elemental creatures with trample. They're still lands. - this.addAbility(new LoyaltyAbility(new NissaWorldwakerSearchEffect(), -7)); + this.addAbility(new LoyaltyAbility(new NissaWorldwakerSearchEffect(), -7)); } public NissaWorldwaker(final NissaWorldwaker card) { @@ -124,26 +122,30 @@ class NissaWorldwakerSearchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0,Integer.MAX_VALUE, new FilterBasicLandCard()); - if (player.searchLibrary(target, game)) { + TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, new FilterBasicLandCard()); + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - for (UUID cardId: target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); + for (UUID cardId : target.getTargets()) { + Card card = controller.getLibrary().getCard(cardId, game); if (card != null) { - if (player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId())) { - ContinuousEffect effect = new BecomesCreatureTargetEffect(new NissaWorldwakerToken(), false, true, Duration.Custom); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - } + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + Permanent land = game.getPermanent(card.getId()); + if (land != null) { + ContinuousEffect effect = new BecomesCreatureTargetEffect(new NissaWorldwakerToken(), false, true, Duration.Custom); + effect.setTargetPointer(new FixedTarget(land, game)); + game.addEffect(effect, source); + + } + } } } } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } } @@ -159,4 +161,4 @@ class NissaWorldwakerToken extends Token { this.toughness = new MageInt(4); this.addAbility(TrampleAbility.getInstance()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java b/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java index d4a6c4f3a15..7a20f8d5867 100644 --- a/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java +++ b/Mage.Sets/src/mage/sets/magic2015/ObeliskOfUrd.java @@ -32,12 +32,9 @@ import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.abilities.keyword.ConvokeAbility; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -48,8 +45,6 @@ import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.util.CardUtil; /** * @@ -63,10 +58,10 @@ public class ObeliskOfUrd extends CardImpl { // Convoke this.addAbility(new ConvokeAbility()); - + // As Obelisk of Urd enters the battlefield, choose a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new ObeliskOfUrdEnterBattlefieldEffect())); - + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature))); + // Creatures you control of the chosen type get +2/+2. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ObeliskOfUrdBoostEffect())); } @@ -81,43 +76,6 @@ public class ObeliskOfUrd extends CardImpl { } } -class ObeliskOfUrdEnterBattlefieldEffect extends OneShotEffect { - - ObeliskOfUrdEnterBattlefieldEffect() { - super(Outcome.BoostCreature); - staticText = "choose a creature type"; - } - - ObeliskOfUrdEnterBattlefieldEffect(final ObeliskOfUrdEnterBattlefieldEffect effect) { - super(effect); - } - - @Override - public ObeliskOfUrdEnterBattlefieldEffect copy() { - return new ObeliskOfUrdEnterBattlefieldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose a creature type:"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); - } - return false; - } -} - class ObeliskOfUrdBoostEffect extends ContinuousEffectImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); @@ -142,7 +100,7 @@ class ObeliskOfUrdBoostEffect extends ContinuousEffectImpl { if (permanent != null) { String subtype = (String) game.getState().getValue(permanent.getId() + "_type"); if (subtype != null) { - for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent perm : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { if (perm.hasSubtype(subtype)) { perm.addPower(2); perm.addToughness(2); diff --git a/Mage.Sets/src/mage/sets/magic2015/YisanTheWandererBard.java b/Mage.Sets/src/mage/sets/magic2015/YisanTheWandererBard.java index c5c6d4568e9..978e17f81dd 100644 --- a/Mage.Sets/src/mage/sets/magic2015/YisanTheWandererBard.java +++ b/Mage.Sets/src/mage/sets/magic2015/YisanTheWandererBard.java @@ -35,7 +35,6 @@ import mage.abilities.costs.common.PutCountersSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -86,40 +85,36 @@ public class YisanTheWandererBard extends CardImpl { } class YisanTheWandererBardEffect extends OneShotEffect { - + public YisanTheWandererBardEffect() { super(Outcome.Benefit); this.staticText = "Search your library for a creature card with converted mana cost equal to the number of verse counters on {this}, put it onto the battlefield, then shuffle your library"; } - + public YisanTheWandererBardEffect(final YisanTheWandererBardEffect effect) { super(effect); } - + @Override public YisanTheWandererBardEffect copy() { return new YisanTheWandererBardEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (sourcePermanent != null && player != null) { + if (sourcePermanent != null && controller != null) { int newConvertedCost = sourcePermanent.getCounters().getCount("verse"); FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, newConvertedCost)); filter.add(new CardTypePredicate(CardType.CREATURE)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } - } + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java index 45882a2ddcf..fe48e846fa9 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java @@ -33,18 +33,16 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.players.Player; @@ -62,25 +60,24 @@ public class ChandraRoaringFlame extends CardImpl { this.expansionSetCode = "ORI"; this.subtype.add("Chandra"); this.color.setRed(true); - + this.nightCard = true; this.canTransform = true; - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); - + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + // +1: Chandra, Roaring Flame deals 2 damage to target player. LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1); loyaltyAbility.addTarget(new TargetPlayer()); - this.addAbility(loyaltyAbility); - + this.addAbility(loyaltyAbility); + //-2: Chandra, Roaring Flame deals 2 damage to target creature. loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), -2); loyaltyAbility.addTarget(new TargetCreaturePermanent()); - this.addAbility(loyaltyAbility); - + this.addAbility(loyaltyAbility); + //-7: Chandra, Roaring Flame deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." this.addAbility(new LoyaltyAbility(new ChandraRoaringFlameEmblemEffect(), -7)); - } @@ -95,27 +92,27 @@ public class ChandraRoaringFlame extends CardImpl { } class ChandraRoaringFlameEmblemEffect extends OneShotEffect { - + public ChandraRoaringFlameEmblemEffect() { super(Outcome.Damage); this.staticText = "{this} deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with \"At the beginning of your upkeep, this emblem deals 3 damage to you.\""; } - + public ChandraRoaringFlameEmblemEffect(final ChandraRoaringFlameEmblemEffect effect) { super(effect); } - + @Override public ChandraRoaringFlameEmblemEffect copy() { return new ChandraRoaringFlameEmblemEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { List opponentsEmblem = new ArrayList<>(); - for(UUID playerId: game.getOpponents(controller.getId())) { + for (UUID playerId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(playerId); if (opponent != null) { if (opponent.damage(6, source.getSourceId(), game, false, true) > 0) { @@ -132,7 +129,8 @@ class ChandraRoaringFlameEmblemEffect extends OneShotEffect { } /** - * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." + * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to + * you." */ class ChandraRoaringFlameEmblem extends Emblem { @@ -142,4 +140,4 @@ class ChandraRoaringFlameEmblem extends Emblem { effect.setText("this emblem deals 3 damage to you"); this.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, effect, TargetController.YOU, false, true)); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java b/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java index db3331a17ff..48fed631acf 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ConsecratedByBlood.java @@ -66,7 +66,7 @@ public class ConsecratedByBlood extends CardImpl { } public ConsecratedByBlood(UUID ownerId) { - super(ownerId, 87, "Consecrated By Blood", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); + super(ownerId, 87, "Consecrated by Blood", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); this.expansionSetCode = "ORI"; this.subtype.add("Aura"); diff --git a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java index 926b6fab831..70692bfa083 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java +++ b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java @@ -32,14 +32,13 @@ import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.TurnPhase; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -77,7 +75,7 @@ public class GideonBattleForged extends CardImpl { this.nightCard = true; this.canTransform = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new GideonBattleForgedAttacksIfAbleTargetEffect(Duration.Custom), 2); diff --git a/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java index 069802820e9..c4cb42fc138 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java +++ b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java @@ -36,6 +36,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; @@ -90,8 +91,7 @@ class HallowedMoonlightEffect extends ReplacementEffectImpl { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { EntersTheBattlefieldEvent entersTheBattlefieldEvent = (EntersTheBattlefieldEvent) event; - controller.moveCardToExileWithInfo(entersTheBattlefieldEvent.getTarget(), null, "", - source.getSourceId(), game, entersTheBattlefieldEvent.getFromZone(), true); + controller.moveCards(entersTheBattlefieldEvent.getTarget(), Zone.EXILED, source, game, false, false, false, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java b/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java index 7fabc195698..7e87bf53d0c 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java +++ b/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java @@ -30,7 +30,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.AsThoughEffectType; @@ -49,7 +48,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -77,7 +75,7 @@ public class JaceTelepathUnbound extends CardImpl { this.nightCard = true; this.canTransform = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Up to one target creature gets -2/-0 until your next turn. Effect effect = new BoostTargetEffect(-2, 0, Duration.UntilYourNextTurn); diff --git a/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java b/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java index c3abacd4394..67cdc1e5242 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java +++ b/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java @@ -32,7 +32,7 @@ import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; @@ -40,7 +40,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -49,7 +48,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; @@ -84,7 +82,7 @@ public class LilianaDefiantNecromancer extends CardImpl { this.nightCard = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Each player discards a card. this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2)); diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java index d3a209c463a..c1e5a65d797 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java +++ b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -69,7 +67,7 @@ public class NissaSageAnimist extends CardImpl { this.nightCard = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. this.addAbility(new LoyaltyAbility(new NissaSageAnimistPlusOneEffect(), 1)); diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java b/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java index 442643c5ffc..d6023fed3fa 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java +++ b/Mage.Sets/src/mage/sets/magicorigins/NissasPilgrimage.java @@ -113,8 +113,8 @@ class NissasPilgrimageEffect extends OneShotEffect { Card card = cards.getRandom(game); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), true); - controller.moveCards(cards, Zone.LIBRARY, Zone.HAND, source, game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); + controller.moveCards(cards, Zone.HAND, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java b/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java index c6fc391ddf2..2fcfe39ffe4 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java +++ b/Mage.Sets/src/mage/sets/magicorigins/TheGreatAurora.java @@ -36,8 +36,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSpellEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -92,63 +93,62 @@ class TheGreatAuroraEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { - Map> permanentsOwned = new HashMap<>(); - Collection permanents = game.getBattlefield().getActivePermanents(source.getControllerId(), game); - for (Permanent permanent : permanents) { - List list = permanentsOwned.get(permanent.getOwnerId()); - if (list == null) { - list = new ArrayList<>(); - permanentsOwned.put(permanent.getOwnerId(), list); - } - list.add(permanent); - } - - // shuffle permanents and hand cards into owner's library - Map permanentsCount = new HashMap<>(); - - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int handCards = player.getHand().size(); - player.moveCards(player.getHand(), Zone.HAND, Zone.LIBRARY, source, game); - List list = permanentsOwned.remove(player.getId()); - permanentsCount.put(playerId, handCards + (list != null ? list.size() : 0)); - for (Permanent permanent : list) { - player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, true); + Map> permanentsOwned = new HashMap<>(); + Collection permanents = game.getBattlefield().getActivePermanents(source.getControllerId(), game); + for (Permanent permanent : permanents) { + List list = permanentsOwned.get(permanent.getOwnerId()); + if (list == null) { + list = new ArrayList<>(); + permanentsOwned.put(permanent.getOwnerId(), list); } - player.shuffleLibrary(game); + list.add(permanent); } - } - game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw or put into play + // shuffle permanents and hand cards into owner's library + Map permanentsCount = new HashMap<>(); - // Draw cards - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = permanentsCount.get(playerId); - if (count > 0) { - player.drawCards(count, game); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int handCards = player.getHand().size(); + player.moveCards(player.getHand(), Zone.HAND, Zone.LIBRARY, source, game); + List list = permanentsOwned.remove(player.getId()); + permanentsCount.put(playerId, handCards + (list != null ? list.size() : 0)); + for (Permanent permanent : list) { + player.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, true); + } + player.shuffleLibrary(game); } } - } - // put lands onto the battlefield - for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetCard target = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterLandCard("put any number of land cards from your hand onto the battlefield")); - player.chooseTarget(Outcome.PutLandInPlay, player.getHand(), target, source, game); - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), false); + game.applyEffects(); // so effects from creatures that were on the battlefield won't trigger from draw or put into play + + // Draw cards + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + int count = permanentsCount.get(playerId); + if (count > 0) { + player.drawCards(count, game); } } - } + + // put lands onto the battlefield + Cards toBattlefield = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + TargetCard target = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterLandCard("put any number of land cards from your hand onto the battlefield")); + player.chooseTarget(Outcome.PutLandInPlay, player.getHand(), target, source, game); + toBattlefield.addAll(target.getTargets()); + } + } + return controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); } - return true; + return false; } } diff --git a/Mage.Sets/src/mage/sets/magicorigins/WoodlandBellower.java b/Mage.Sets/src/mage/sets/magicorigins/WoodlandBellower.java index adfa437ce62..3df2f8848c2 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/WoodlandBellower.java +++ b/Mage.Sets/src/mage/sets/magicorigins/WoodlandBellower.java @@ -78,6 +78,7 @@ public class WoodlandBellower extends CardImpl { } class WoodlandBellowerEffect extends OneShotEffect { + WoodlandBellowerEffect() { super(Outcome.PutCreatureInPlay); staticText = "Search your library for a nonlegendary green creature card with converted mana cost 3 or less, put it onto the battlefield, then shuffle your library"; @@ -89,27 +90,25 @@ class WoodlandBellowerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } FilterCard filter = new FilterCard("nonlegendary green creature card with converted mana cost 3 or less"); filter.add(new ColorPredicate(ObjectColor.GREEN)); - filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(Predicates.not(new SupertypePredicate("Legendary"))); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, 4)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } @@ -118,4 +117,4 @@ class WoodlandBellowerEffect extends OneShotEffect { return new WoodlandBellowerEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/masterseditionii/JuniperOrderAdvocate.java b/Mage.Sets/src/mage/sets/masterseditionii/JuniperOrderAdvocate.java new file mode 100644 index 00000000000..16f458ecba6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditionii/JuniperOrderAdvocate.java @@ -0,0 +1,52 @@ +/* + * 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.sets.masterseditionii; + +import java.util.UUID; + +/** + * + * @author LoneFox + */ +public class JuniperOrderAdvocate extends mage.sets.alliances.JuniperOrderAdvocate { + + public JuniperOrderAdvocate(UUID ownerId) { + super(ownerId); + this.cardNumber = 20; + this.expansionSetCode = "ME2"; + } + + public JuniperOrderAdvocate(final JuniperOrderAdvocate card) { + super(card); + } + + @Override + public JuniperOrderAdvocate copy() { + return new JuniperOrderAdvocate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mediainserts/MagisterOfWorth.java b/Mage.Sets/src/mage/sets/mediainserts/MagisterOfWorth.java index 8730131d3ba..0c293502e33 100644 --- a/Mage.Sets/src/mage/sets/mediainserts/MagisterOfWorth.java +++ b/Mage.Sets/src/mage/sets/mediainserts/MagisterOfWorth.java @@ -35,7 +35,6 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -109,8 +108,7 @@ class MagisterOfWorthVoteEffect extends OneShotEffect { if (player.chooseUse(Outcome.DestroyPermanent, "Choose grace?", source, game)) { graceCount++; game.informPlayers(player.getLogName() + " has chosen: grace"); - } - else { + } else { condemnationCount++; game.informPlayers(player.getLogName() + " has chosen: condemnation"); } @@ -130,7 +128,7 @@ class MagisterOfWorthVoteEffect extends OneShotEffect { class MagisterOfWorthDestroyEffect extends OneShotEffect { private static final FilterPermanent filter = new FilterCreaturePermanent("creatures other than {this}"); - + static { filter.add(new AnotherPredicate()); } @@ -175,12 +173,10 @@ class MagisterOfWorthReturnFromGraveyardEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card :player.getGraveyard().getCards(new FilterCreatureCard(), game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); - } + player.moveCards(player.getGraveyard().getCards(new FilterCreatureCard(), game), Zone.BATTLEFIELD, source, game); } } return true; @@ -193,4 +189,4 @@ class MagisterOfWorthReturnFromGraveyardEffect extends OneShotEffect { return new MagisterOfWorthReturnFromGraveyardEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/Bribery.java b/Mage.Sets/src/mage/sets/mercadianmasques/Bribery.java index 199c4f5e1bc..c7aec373447 100644 --- a/Mage.Sets/src/mage/sets/mercadianmasques/Bribery.java +++ b/Mage.Sets/src/mage/sets/mercadianmasques/Bribery.java @@ -27,7 +27,6 @@ */ package mage.sets.mercadianmasques; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -91,13 +90,8 @@ class BriberyEffect extends OneShotEffect { if (controller != null && opponent != null) { TargetCardInLibrary target = new TargetCardInLibrary(0, 1, new FilterCreatureCard("creature card")); if (controller.searchLibrary(target, game, opponent.getId())) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = opponent.getLibrary().getCard(targetId, game); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } - } + Card card = opponent.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } opponent.shuffleLibrary(game); return true; diff --git a/Mage.Sets/src/mage/sets/mirage/ShallowGrave.java b/Mage.Sets/src/mage/sets/mirage/ShallowGrave.java index 67ef2954399..9ee5675fccf 100644 --- a/Mage.Sets/src/mage/sets/mirage/ShallowGrave.java +++ b/Mage.Sets/src/mage/sets/mirage/ShallowGrave.java @@ -100,7 +100,7 @@ class ShallowGraveEffect extends OneShotEffect { } } if (lastCreatureCard != null) { - if (controller.putOntoBattlefieldWithInfo(lastCreatureCard, game, Zone.GRAVEYARD, source.getSourceId())) { + if (controller.moveCards(lastCreatureCard, Zone.BATTLEFIELD, source, game)) { Permanent returnedCreature = game.getPermanent(lastCreatureCard.getId()); if (returnedCreature != null) { FixedTarget fixedTarget = new FixedTarget(returnedCreature, game); diff --git a/Mage.Sets/src/mage/sets/mirage/VigilantMartyr.java b/Mage.Sets/src/mage/sets/mirage/VigilantMartyr.java new file mode 100644 index 00000000000..c0bfb95c423 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/VigilantMartyr.java @@ -0,0 +1,89 @@ +/* + * 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.sets.mirage; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.RegenerateTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.common.FilterEnchantmentPermanent; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.target.TargetSpell; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class VigilantMartyr extends CardImpl { + + private final static FilterSpell filter = new FilterSpell("spell that targets an enchantment"); + + static { + filter.add(new TargetsPermanentPredicate(new FilterEnchantmentPermanent())); + } + + public VigilantMartyr(UUID ownerId) { + super(ownerId, 249, "Vigilant Martyr", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{W}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Sacrifice Vigilant Martyr: Regenerate target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new SacrificeSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + // {W}{W}, {tap}, Sacrifice Vigilant Martyr: Counter target spell that targets an enchantment. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{W}{W}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetSpell(filter)); + this.addAbility(ability); + } + + public VigilantMartyr(final VigilantMartyr card) { + super(card); + } + + @Override + public VigilantMartyr copy() { + return new VigilantMartyr(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java b/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java index 7cfbf933b62..eaf8987852c 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java +++ b/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java @@ -76,21 +76,21 @@ public class ProteusStaff extends CardImpl { } class ProteusStaffEffect extends OneShotEffect { - + ProteusStaffEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of his or her library until he or she reveals a creature card. The player puts that card onto the battlefield and the rest on the bottom of his or her library in any order."; } - + ProteusStaffEffect(final ProteusStaffEffect effect) { super(effect); } - + @java.lang.Override public ProteusStaffEffect copy() { return new ProteusStaffEffect(this); } - + @java.lang.Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); @@ -100,7 +100,7 @@ class ProteusStaffEffect extends OneShotEffect { if (owner != null && controller != null) { // Put target creature on the bottom of its owner's library. owner.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, true); - + // That creature's controller reveals cards from the top of his or her library until he or she reveals a creature card. Cards cards = new CardsImpl(); while (controller.getLibrary().size() > 0) { @@ -108,16 +108,15 @@ class ProteusStaffEffect extends OneShotEffect { if (card != null) { if (card.getCardType().contains(CardType.CREATURE)) { // The player puts that card onto the battlefield - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; - } - else { + } else { cards.add(card); } } } controller.revealCards("Proteus Staff", cards, game); - + // and the rest on the bottom of his or her library in any order. while (cards.size() > 0 && controller.canRespond()) { if (cards.size() == 1) { @@ -125,9 +124,8 @@ class ProteusStaffEffect extends OneShotEffect { if (card != null) { controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); cards.remove(card); - } - } - else { + } + } else { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on bottom of your library (last chosen will be on bottom)")); controller.choose(Outcome.Neutral, cards, target, game); Card card = cards.get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/mirrodin/ScytheOfTheWretched.java b/Mage.Sets/src/mage/sets/mirrodin/ScytheOfTheWretched.java index a0b0f53927a..67e45f89c1a 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/ScytheOfTheWretched.java +++ b/Mage.Sets/src/mage/sets/mirrodin/ScytheOfTheWretched.java @@ -158,8 +158,7 @@ class ScytheOfTheWretchedReanimateEffect extends OneShotEffect { Card card = game.getCard(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (card != null && controller != null) { - Zone currentZone = game.getState().getZone(card.getId()); - controller.putOntoBattlefieldWithInfo(card, game, currentZone, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); Effect effect = new AttachEffect(Outcome.AddAbility); effect.setTargetPointer(new FixedTarget(card.getId())); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/GreenSunsZenith.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/GreenSunsZenith.java index eb95700b42a..03cb3e2fbf8 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/GreenSunsZenith.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/GreenSunsZenith.java @@ -25,18 +25,18 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.mirrodinbesieged; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ShuffleSpellEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterCard; @@ -47,8 +47,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInLibrary; -import java.util.UUID; - /** * @author Loki */ @@ -77,6 +75,7 @@ public class GreenSunsZenith extends CardImpl { } class GreenSunsZenithSearchEffect extends OneShotEffect { + GreenSunsZenithSearchEffect() { super(Outcome.PutCreatureInPlay); staticText = "Search your library for a green creature card with converted mana cost X or less, put it onto the battlefield, then shuffle your library"; @@ -88,28 +87,28 @@ class GreenSunsZenithSearchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } //Set the mana cost one higher to 'emulate' a less than or equal to comparison. int xValue = source.getManaCostsToPay().getX() + 1; FilterCard filter = new FilterCard("green creature card with converted mana cost " + xValue + " or less"); filter.add(new ColorPredicate(ObjectColor.GREEN)); - filter.add(new CardTypePredicate(CardType.CREATURE)); + filter.add(new CardTypePredicate(CardType.CREATURE)); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, xValue)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { + if (controller.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java index 279bd693526..6a51fef04bc 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java @@ -25,32 +25,25 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.mirrodinbesieged; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.NameACardEffect; import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.util.CardUtil; /** * @@ -66,7 +59,7 @@ public class PhyrexianRevoker extends CardImpl { this.toughness = new MageInt(1); // As Phyrexian Revoker enters the battlefield, name a nonland card. - this.addAbility(new AsEntersBattlefieldAbility(new PhyrexianRevokerEffect1())); + this.addAbility(new AsEntersBattlefieldAbility(new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME))); // Activated abilities of sources with the chosen name can't be activated. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PhyrexianRevokerEffect2())); @@ -83,46 +76,6 @@ public class PhyrexianRevoker extends CardImpl { } -class PhyrexianRevokerEffect1 extends OneShotEffect { - - public PhyrexianRevokerEffect1() { - super(Outcome.Detriment); - staticText = "name a nonland card"; - } - - public PhyrexianRevokerEffect1(final PhyrexianRevokerEffect1 effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (controller != null && permanent != null) { - Choice cardChoice = new ChoiceImpl(); - cardChoice.setChoices(CardRepository.instance.getNonLandNames()); - cardChoice.clearChoice(); - while (!controller.choose(Outcome.Detriment, cardChoice, game)) { - if (!controller.canRespond()) { - return false; - } - } - String cardName = cardChoice.getChoice(); - game.informPlayers(permanent.getLogName() + ", named card: [" + cardName + "]"); - game.getState().setValue(source.getSourceId().toString(), cardName); - permanent.addInfo("named card", CardUtil.addToolTipMarkTags("Named card: [" + cardName +"]"), game); - return true; - } - return false; - } - - @Override - public PhyrexianRevokerEffect1 copy() { - return new PhyrexianRevokerEffect1(this); - } - -} - class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl { public PhyrexianRevokerEffect2() { @@ -143,7 +96,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl { public PhyrexianRevokerEffect2 copy() { return new PhyrexianRevokerEffect2(this); } - + @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); @@ -157,7 +110,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ACTIVATE_ABILITY) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { + if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java index df35e2d49d7..90520e0a75a 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java @@ -1,16 +1,16 @@ /* * Copyright 2011 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 @@ -20,16 +20,17 @@ * 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.sets.mirrodinbesieged; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.Effect; @@ -37,13 +38,11 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -52,8 +51,6 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetArtifactPermanent; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -61,6 +58,7 @@ import java.util.UUID; public class TezzeretAgentOfBolas extends CardImpl { private static final FilterCard filter = new FilterCard("an artifact card"); + static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); } @@ -70,8 +68,7 @@ public class TezzeretAgentOfBolas extends CardImpl { this.expansionSetCode = "MBS"; this.subtype.add("Tezzeret"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Look at the top five cards of your library. You may reveal an artifact card from among them and put it into your hand. Put the rest on the bottom of your library in any order. this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(5, 1, filter, true), 1)); @@ -80,7 +77,7 @@ public class TezzeretAgentOfBolas extends CardImpl { Effect effect = new AddCardTypeTargetEffect(CardType.CREATURE, Duration.EndOfGame); effect.setText("Target artifact becomes an artifact creature"); LoyaltyAbility ability1 = new LoyaltyAbility(effect, -1); - effect = new SetPowerToughnessTargetEffect(5,5, Duration.EndOfGame); + effect = new SetPowerToughnessTargetEffect(5, 5, Duration.EndOfGame); effect.setText("with base power and toughness 5/5"); ability1.addEffect(effect); ability1.addTarget(new TargetArtifactPermanent()); diff --git a/Mage.Sets/src/mage/sets/modernmasters/DoublingSeason.java b/Mage.Sets/src/mage/sets/modernmasters/DoublingSeason.java index 4c42462e1fe..1067cb393f1 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/DoublingSeason.java +++ b/Mage.Sets/src/mage/sets/modernmasters/DoublingSeason.java @@ -113,6 +113,7 @@ class DoublingSeasonTokenEffect extends ReplacementEffectImpl { } class DoublingSeasonCounterEffect extends ReplacementEffectImpl { + DoublingSeasonCounterEffect() { super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); staticText = "If an effect would place one or more counters on a permanent you control, it places twice that many of those counters on that permanent instead"; @@ -128,15 +129,18 @@ class DoublingSeasonCounterEffect extends ReplacementEffectImpl { return false; } - @Override + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ADD_COUNTERS; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null && target.getControllerId().equals(source.getControllerId())) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { return true; } return false; diff --git a/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java b/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java index 61a7cc1e97e..6f652e82b4e 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java +++ b/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java @@ -67,7 +67,7 @@ public class Epochrasite extends CardImpl { // Epochrasite enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), - new InvertCondition(new CastFromHandCondition()), true, + new InvertCondition(new CastFromHandCondition()), "{this} enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand",""), new CastFromHandWatcher()); diff --git a/Mage.Sets/src/mage/sets/modernmasters/ToothAndNail.java b/Mage.Sets/src/mage/sets/modernmasters/ToothAndNail.java index 86f2e6936b8..30762aeb3d7 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/ToothAndNail.java +++ b/Mage.Sets/src/mage/sets/modernmasters/ToothAndNail.java @@ -33,8 +33,8 @@ import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.keyword.EntwineAbility; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -102,13 +102,8 @@ class ToothAndNailPutCreatureOnBattlefieldEffect extends OneShotEffect { TargetCardInHand target = new TargetCardInHand(0, 2, new FilterCreatureCard("creature cards")); if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { - for (UUID targetId : target.getTargets()) { - Card card = game.getCard(targetId); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), false); - } - } - return true; + return controller.moveCards(new CardsImpl(getTargetPointer().getTargets(game, source)).getCards(game), + Zone.BATTLEFIELD, source, game, true, false, false, null); } return false; } diff --git a/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java b/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java index 31277520f32..d790518da10 100644 --- a/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java +++ b/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java @@ -139,7 +139,7 @@ public class WorldheartPhoenix extends CardImpl { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { // TODO: No perfect solution because there could be other effects that allow to cast the card for this mana cost if (spellAbility.getManaCosts().getText().equals("{W}{U}{B}{R}{G}")) { permanent.addCounters(CounterType.P1P1.createInstance(2), game); diff --git a/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java b/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java index 51657bef406..7d9eb88b969 100644 --- a/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java +++ b/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java @@ -44,6 +44,7 @@ import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.CounterPredicate; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -52,8 +53,9 @@ import mage.game.permanent.Permanent; * @author emerald000 */ public class BramblewoodParagon extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Each creature you control with a +1/+1 counter on it"); + static { filter.add(new CounterPredicate(CounterType.P1P1)); } @@ -68,15 +70,15 @@ public class BramblewoodParagon extends CardImpl { // Each other Warrior creature you control enters the battlefield with an additional +1/+1 counter on it. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BramblewoodParagonReplacementEffect())); - + // Each creature you control with a +1/+1 counter on it has trample. this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, + Zone.BATTLEFIELD, new GainAbilityAllEffect( - TrampleAbility.getInstance(), - Duration.WhileOnBattlefield, + TrampleAbility.getInstance(), + Duration.WhileOnBattlefield, filter))); - + } public BramblewoodParagon(final BramblewoodParagon card) { @@ -99,16 +101,16 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { BramblewoodParagonReplacementEffect(BramblewoodParagonReplacementEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.hasSubtype("Warrior") && !event.getTargetId().equals(source.getSourceId()); @@ -116,14 +118,13 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } return false; } - @Override public BramblewoodParagonReplacementEffect copy() { return new BramblewoodParagonReplacementEffect(this); diff --git a/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java b/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java index 624ac5cf2dc..e652196c9d1 100644 --- a/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java +++ b/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java @@ -45,6 +45,7 @@ import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -102,7 +103,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.hasSubtype("Rogue") @@ -119,7 +120,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } diff --git a/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java b/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java index a1fdaf96195..e4841e300df 100644 --- a/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java +++ b/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java @@ -54,9 +54,9 @@ public class RecrossThePaths extends CardImpl { super(ownerId, 133, "Recross the Paths", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{G}"); this.expansionSetCode = "MOR"; - // Reveal cards from the top of your library until you reveal a land card. Put that card onto the battlefield and the rest on the bottom of your library in any order. + // Reveal cards from the top of your library until you reveal a land card. Put that card onto the battlefield and the rest on the bottom of your library in any order. this.getSpellAbility().addEffect(new RecrossThePathsEffect()); - + // Clash with an opponent. If you win, return Recross the Paths to its owner's hand. this.getSpellAbility().addEffect(ClashWinReturnToHandSpellEffect.getInstance()); } @@ -96,23 +96,23 @@ class RecrossThePathsEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - + Cards cards = new CardsImpl(); Card cardFound = null; while (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - cards.add(card); - if (filter.match(card, game)){ + cards.add(card); + if (filter.match(card, game)) { cardFound = card; break; } - } + } } if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getName(), cards, game); + controller.revealCards(sourceObject.getIdName(), cards, game); if (cardFound != null) { - controller.putOntoBattlefieldWithInfo(cardFound, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(cardFound, Zone.BATTLEFIELD, source, game); cards.remove(cardFound); } controller.putCardsOnBottomOfLibrary(cards, game, source, true); diff --git a/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java b/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java index c7a423909b4..ee007b91f51 100644 --- a/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java +++ b/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java @@ -44,6 +44,7 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; @@ -64,7 +65,7 @@ public class SageOfFables extends CardImpl { // Each other Wizard creature you control enters the battlefield with an additional +1/+1 counter on it. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SageOfFablesReplacementEffect())); - + // {2}, Remove a +1/+1 counter from a creature you control: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); @@ -91,16 +92,16 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { SageOfFablesReplacementEffect(SageOfFablesReplacementEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.getSubtype().contains("Wizard") && !event.getTargetId().equals(source.getSourceId()); @@ -113,14 +114,13 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } return false; } - @Override public SageOfFablesReplacementEffect copy() { return new SageOfFablesReplacementEffect(this); diff --git a/Mage.Sets/src/mage/sets/morningtide/Scapeshift.java b/Mage.Sets/src/mage/sets/morningtide/Scapeshift.java index f1c69c592e4..5e7f57e6dd5 100644 --- a/Mage.Sets/src/mage/sets/morningtide/Scapeshift.java +++ b/Mage.Sets/src/mage/sets/morningtide/Scapeshift.java @@ -27,16 +27,14 @@ */ package mage.sets.morningtide; -import java.util.List; import java.util.UUID; - +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; import mage.constants.Zone; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterLandCard; @@ -56,7 +54,6 @@ public class Scapeshift extends CardImpl { super(ownerId, 136, "Scapeshift", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); this.expansionSetCode = "MOR"; - // Sacrifice any number of lands. Search your library for that many land cards, put them onto the battlefield tapped, then shuffle your library. this.getSpellAbility().addEffect(new ScapeshiftEffect()); } @@ -71,12 +68,11 @@ public class Scapeshift extends CardImpl { } } - class ScapeshiftEffect extends OneShotEffect { public ScapeshiftEffect() { super(Outcome.Neutral); - staticText = "Sacrifice any number of lands. Search your library for that many land cards, put them onto the battlefield tapped, then shuffle your library"; + staticText = "Sacrifice any number of lands. Search your library for that many land cards, put them onto the battlefield tapped, then shuffle your library"; } public ScapeshiftEffect(final ScapeshiftEffect effect) { @@ -90,35 +86,29 @@ class ScapeshiftEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null){ + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } int amount = 0; TargetControlledPermanent sacrificeLand = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledLandPermanent("lands you control"), true); - if(player.chooseTarget(Outcome.Sacrifice, sacrificeLand, source, game)){ - for(Object uuid : sacrificeLand.getTargets()){ - Permanent land = game.getPermanent((UUID)uuid); - if(land != null){ + if (controller.chooseTarget(Outcome.Sacrifice, sacrificeLand, source, game)) { + for (Object uuid : sacrificeLand.getTargets()) { + Permanent land = game.getPermanent((UUID) uuid); + if (land != null) { land.sacrifice(source.getSourceId(), game); amount++; } } } TargetCardInLibrary target = new TargetCardInLibrary(amount, new FilterLandCard("lands")); - if (player.searchLibrary(target, game)) { - if (target.getTargets().size() > 0) { - for (UUID cardId: (List)target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getControllerId(), true); - } - } - } - player.shuffleLibrary(game); + if (controller.searchLibrary(target, game)) { + controller.moveCards(new CardsImpl(target.getTargets()).getCards(game), + Zone.BATTLEFIELD, source, game, true, false, false, null); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } diff --git a/Mage.Sets/src/mage/sets/nemesis/Infiltrate.java b/Mage.Sets/src/mage/sets/nemesis/Infiltrate.java new file mode 100644 index 00000000000..cb8f7fbc9ea --- /dev/null +++ b/Mage.Sets/src/mage/sets/nemesis/Infiltrate.java @@ -0,0 +1,60 @@ +/* + * 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.sets.nemesis; + +import java.util.UUID; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author AlumiuN + */ +public class Infiltrate extends CardImpl { + + public Infiltrate(UUID ownerId) { + super(ownerId, 33, "Infiltrate", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{U}"); + this.expansionSetCode = "NMS"; + + // Target creature is unblockable this turn. + this.getSpellAbility().addEffect(new CantBeBlockedTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public Infiltrate(final Infiltrate card) { + super(card); + } + + @Override + public Infiltrate copy() { + return new Infiltrate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/nemesis/LinSivviDefiantHero.java b/Mage.Sets/src/mage/sets/nemesis/LinSivviDefiantHero.java index efc9dcd7c22..3748ad54259 100644 --- a/Mage.Sets/src/mage/sets/nemesis/LinSivviDefiantHero.java +++ b/Mage.Sets/src/mage/sets/nemesis/LinSivviDefiantHero.java @@ -59,16 +59,16 @@ import mage.target.common.TargetCardInYourGraveyard; * @author fireshoes */ public class LinSivviDefiantHero extends CardImpl { - + private static final FilterCard filter = new FilterCard("Rebel card from your graveyard"); - + static { filter.add(new OwnerPredicate(TargetController.YOU)); filter.add(new SubtypePredicate("Rebel")); } - + static final String rule = "Put target Rebel card from your graveyard on the bottom of your library"; - + public LinSivviDefiantHero(UUID ownerId) { super(ownerId, 12, "Lin Sivvi, Defiant Hero", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); this.expansionSetCode = "NMS"; @@ -84,7 +84,7 @@ public class LinSivviDefiantHero extends CardImpl { new ManaCostsImpl("{X}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - + // {3}: Put target Rebel card from your graveyard on the bottom of your library. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutOnLibraryTargetEffect(false, rule), new GenericManaCost(3)); ability.addTarget(new TargetCardInYourGraveyard(1, filter)); @@ -119,8 +119,8 @@ class LinSivviDefiantHeroEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } @@ -131,15 +131,15 @@ class LinSivviDefiantHeroEffect extends OneShotEffect { filter.add(new SubtypePredicate("Rebel")); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java index 6b1311d8f0e..f2c46b36031 100644 --- a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java +++ b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java @@ -36,7 +36,6 @@ import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.keyword.FadingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -60,10 +59,9 @@ public class ParallaxWave extends CardImpl { super(ownerId, 17, "Parallax Wave", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); this.expansionSetCode = "NMS"; - // Fading 5 this.addAbility(new FadingAbility(5, this)); - + // Remove a fade counter from Parallax Wave: Exile target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new RemoveCountersSourceCost(CounterType.FADE.createInstance())); ability.addTarget(new TargetCreaturePermanent()); @@ -103,21 +101,16 @@ class ParallaxWaveEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null) { - int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1; + Player controller = game.getPlayer(source.getControllerId()); + if (sourceObject != null && controller != null) { + int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter); if (exileZoneId != null) { ExileZone exileZone = game.getExile().getExileZone(exileZoneId); if (exileZone != null) { - for (Card card: exileZone.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - } - exileZone.clear(); + return controller.moveCards(exileZone.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); } - return true; + return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/BirthingPod.java b/Mage.Sets/src/mage/sets/newphyrexia/BirthingPod.java index 03790814187..8109def52a8 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/BirthingPod.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/BirthingPod.java @@ -28,9 +28,6 @@ package mage.sets.newphyrexia; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.Cost; @@ -40,7 +37,9 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.Filter; import mage.filter.FilterCard; @@ -61,7 +60,6 @@ public class BirthingPod extends CardImpl { super(ownerId, 104, "Birthing Pod", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}{GP}"); this.expansionSetCode = "NPH"; - // {1}{GP}, {tap}, Sacrifice a creature: Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card onto the battlefield, then shuffle your library. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl("{1}{GP}")); ability.addCost(new TapSourceCost()); @@ -80,6 +78,7 @@ public class BirthingPod extends CardImpl { } class BirthingPodEffect extends OneShotEffect { + BirthingPodEffect() { super(Outcome.Benefit); staticText = "Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, put that card onto the battlefield, then shuffle your library"; @@ -101,22 +100,18 @@ class BirthingPodEffect extends OneShotEffect { break; } } - Player player = game.getPlayer(source.getControllerId()); - if (sacrificedPermanent != null && player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (sacrificedPermanent != null && controller != null) { int newConvertedCost = sacrificedPermanent.getManaCost().convertedManaCost() + 1; FilterCard filter = new FilterCard("creature card with converted mana cost " + newConvertedCost); filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, newConvertedCost)); filter.add(new CardTypePredicate(CardType.CREATURE)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { - for (UUID cardId : target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } - } + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java b/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java index 2fef2672aa1..d59865ecdbd 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java @@ -28,15 +28,16 @@ package mage.sets.newphyrexia; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -50,7 +51,6 @@ public class DueRespect extends CardImpl { super(ownerId, 8, "Due Respect", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.expansionSetCode = "NPH"; - // Permanents enter the battlefield tapped this turn. this.getSpellAbility().addEffect(new DueRespectEffect()); // Draw a card. @@ -85,18 +85,18 @@ class DueRespectEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { permanent.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return true; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java b/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java index 5b5a30d8035..e51d4c7d16e 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java @@ -34,11 +34,10 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileFromZoneTargetEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -47,7 +46,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.game.ExileZone; import mage.game.Game; @@ -72,7 +70,7 @@ public class KarnLiberated extends CardImpl { super(ownerId, 1, "Karn Liberated", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{7}"); this.expansionSetCode = "NPH"; this.subtype.add("Karn"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); // +4: Target player exiles a card from his or her hand. LoyaltyAbility ability1 = new LoyaltyAbility(new ExileFromZoneTargetEffect(Zone.HAND, exileId, this.getIdName(), new FilterCard()), 4); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/MeliraSylvokOutcast.java b/Mage.Sets/src/mage/sets/newphyrexia/MeliraSylvokOutcast.java index b43ddb45473..0e370f97e18 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/MeliraSylvokOutcast.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/MeliraSylvokOutcast.java @@ -29,13 +29,6 @@ package mage.sets.newphyrexia; import java.util.Set; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -43,6 +36,13 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.InfectAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -63,7 +63,6 @@ public class MeliraSylvokOutcast extends CardImpl { this.subtype.add("Human"); this.subtype.add("Scout"); - this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -113,7 +112,7 @@ class MeliraSylvokOutcastEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ADD_COUNTER; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return event.getData().equals(CounterType.POISON.getName()) && event.getTargetId().equals(source.getControllerId()); @@ -141,16 +140,19 @@ class MeliraSylvokOutcastEffect2 extends ReplacementEffectImpl { public boolean replaceEvent(GameEvent event, Ability source, Game game) { return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ADD_COUNTER; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getData().equals(CounterType.M1M1.getName())) { Permanent perm = game.getPermanent(event.getTargetId()); + if (perm == null) { + perm = game.getPermanentEntering(event.getTargetId()); + } if (perm != null && perm.getCardType().contains(CardType.CREATURE) && perm.getControllerId().equals(source.getControllerId())) { return true; } @@ -181,7 +183,7 @@ class MeliraSylvokOutcastEffect3 extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { Set opponents = game.getOpponents(source.getControllerId()); - for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { + for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { if (opponents.contains(perm.getControllerId())) { perm.getAbilities().remove(InfectAbility.getInstance()); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java b/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java index 5f88e32d91f..6f7bf4cf1a4 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java @@ -28,11 +28,6 @@ package mage.sets.newphyrexia; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.BeginningOfDrawTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -40,7 +35,12 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -125,9 +125,8 @@ class OmenMachineEffect2 extends OneShotEffect { if (card != null) { player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); if (card.getCardType().contains(CardType.LAND)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - else { + player.moveCards(card, Zone.BATTLEFIELD, source, game); + } else { if (card.getSpellAbility().canChooseTarget(game)) { player.cast(card.getSpellAbility(), game, true); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java b/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java index 59519623423..eb91ef9938c 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java @@ -40,6 +40,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -77,23 +78,24 @@ class TorporOrbEffect extends ContinuousRuleModifyingEffectImpl { TorporOrbEffect(final TorporOrbEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { Ability ability = (Ability) getValue("targetAbility"); if (ability != null && AbilityType.TRIGGERED.equals(ability.getAbilityType())) { - Permanent p = game.getPermanent(event.getTargetId()); - if (p != null && p.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } return false; } + @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(event.getSourceId()); @@ -103,7 +105,7 @@ class TorporOrbEffect extends ContinuousRuleModifyingEffectImpl { } return null; } - + @Override public TorporOrbEffect copy() { return new TorporOrbEffect(this); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java b/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java index 45d79931645..9c0a62aa76d 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java @@ -28,18 +28,21 @@ package mage.sets.newphyrexia; import java.util.UUID; - -import mage.constants.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.HasteAbility; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -74,6 +77,7 @@ public class UrabraskTheHidden extends CardImpl { } class UrabraskTheHiddenEffect extends ReplacementEffectImpl { + UrabraskTheHiddenEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Creatures your opponents control enter the battlefield tapped"; @@ -85,7 +89,7 @@ class UrabraskTheHiddenEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } @@ -96,21 +100,20 @@ class UrabraskTheHiddenEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Card card = game.getCard(event.getTargetId()); - if (card != null && card.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } return false; } - @Override public UrabraskTheHiddenEffect copy() { return new UrabraskTheHiddenEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java b/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java index df7da676226..0bcb89be3a9 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/Xenograft.java @@ -29,6 +29,12 @@ package mage.sets.newphyrexia; import java.util.List; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,19 +42,9 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.CardImpl; -import mage.cards.repository.CardRepository; -import mage.choices.Choice; -import mage.choices.ChoiceImpl; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; /** * @@ -60,9 +56,8 @@ public class Xenograft extends CardImpl { super(ownerId, 51, "Xenograft", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}"); this.expansionSetCode = "NPH"; - // As Xenograft enters the battlefield, choose a creature type. - this.addAbility(new AsEntersBattlefieldAbility(new XenograftEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Detriment))); // Each creature you control is the chosen type in addition to its other types. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new XenograftAddSubtypeEffect())); } @@ -77,43 +72,6 @@ public class Xenograft extends CardImpl { } } -class XenograftEffect extends OneShotEffect { - - public XenograftEffect() { - super(Outcome.DrawCard); - staticText = "choose a creature type"; - } - - public XenograftEffect(final XenograftEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - Choice typeChoice = new ChoiceImpl(true); - typeChoice.setMessage("Choose creature type"); - typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.BoostCreature, typeChoice, game)) { - if (!player.canRespond()) { - return false; - } - } - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + typeChoice.getChoice()); - game.getState().setValue(source.getSourceId() + "_XenograftType", typeChoice.getChoice()); - permanent.addInfo("chosen type", "Chosen type: " + typeChoice.getChoice().toString() + "", game); - } - return false; - } - - @Override - public XenograftEffect copy() { - return new XenograftEffect(this); - } -} - class XenograftAddSubtypeEffect extends ContinuousEffectImpl { public XenograftAddSubtypeEffect() { @@ -127,7 +85,7 @@ class XenograftAddSubtypeEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - String subtype = (String) game.getState().getValue(source.getSourceId() + "_XenograftType"); + String subtype = (String) game.getState().getValue(source.getSourceId() + "_type"); if (subtype != null) { List permanents = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game); for (Permanent permanent : permanents) { diff --git a/Mage.Sets/src/mage/sets/odyssey/Zoologist.java b/Mage.Sets/src/mage/sets/odyssey/Zoologist.java index 5780599cfe9..cc7330b0491 100644 --- a/Mage.Sets/src/mage/sets/odyssey/Zoologist.java +++ b/Mage.Sets/src/mage/sets/odyssey/Zoologist.java @@ -29,6 +29,7 @@ package mage.sets.odyssey; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -36,7 +37,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -94,25 +94,23 @@ class ZoologistEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller == null || sourceObject == null) { return false; } - if (player.getLibrary().size() > 0) { - Card card = player.getLibrary().getFromTop(game); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Zoologist", cards, game); - + if (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().getFromTop(game); + controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); if (card != null) { if (card.getCardType().contains(CardType.CREATURE)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } } } - return false; + return true; } } diff --git a/Mage.Sets/src/mage/sets/onslaught/PatriarchsBidding.java b/Mage.Sets/src/mage/sets/onslaught/PatriarchsBidding.java index 42b4dfd2de0..61d54f0c357 100644 --- a/Mage.Sets/src/mage/sets/onslaught/PatriarchsBidding.java +++ b/Mage.Sets/src/mage/sets/onslaught/PatriarchsBidding.java @@ -35,7 +35,6 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.repository.CardRepository; import mage.choices.Choice; @@ -78,7 +77,7 @@ class PatriarchsBiddingEffect extends OneShotEffect { public PatriarchsBiddingEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "Each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to the battlefield."; + this.staticText = "each player chooses a creature type. Each player returns all creature cards of a type chosen this way from his or her graveyard to the battlefield"; } public PatriarchsBiddingEffect(final PatriarchsBiddingEffect effect) { @@ -91,12 +90,12 @@ class PatriarchsBiddingEffect extends OneShotEffect { } @Override - public boolean apply(Game game, Ability ability) { - Player controller = game.getPlayer(ability.getControllerId()); - MageObject sourceObject = game.getObject(ability.getSourceId()); + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null) { Set chosenTypes = new HashSet<>(); - for (UUID playerId : controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose a creature type"); @@ -108,24 +107,21 @@ class PatriarchsBiddingEffect extends OneShotEffect { } String chosenType = typeChoice.getChoice(); if (chosenType != null) { - game.informPlayers(sourceObject.getName() + ": " + player.getLogName() + " has chosen " + chosenType); + game.informPlayers(sourceObject.getLogName() + ": " + player.getLogName() + " has chosen " + chosenType); chosenTypes.add(chosenType); } } - + List predicates = new ArrayList<>(); for (String type : chosenTypes) { predicates.add(new SubtypePredicate(type)); } FilterCard filter = new FilterCreatureCard(); filter.add(Predicates.or(predicates)); - - for (UUID playerId : controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card : player.getGraveyard().getCards(filter, game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, ability.getSourceId()); - } + player.moveCards(player.getGraveyard().getCards(filter, game), Zone.BATTLEFIELD, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/onslaught/RiptideShapeshifter.java b/Mage.Sets/src/mage/sets/onslaught/RiptideShapeshifter.java index 0f4b766a2cd..72ff1eb3c97 100644 --- a/Mage.Sets/src/mage/sets/onslaught/RiptideShapeshifter.java +++ b/Mage.Sets/src/mage/sets/onslaught/RiptideShapeshifter.java @@ -29,6 +29,7 @@ package mage.sets.onslaught; import java.util.UUID; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; @@ -79,47 +80,46 @@ public class RiptideShapeshifter extends CardImpl { } class RiptideShapeshifterEffect extends OneShotEffect { - + RiptideShapeshifterEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Choose a creature type. Reveal cards from the top of your library until you reveal a creature card of that type. Put that card onto the battlefield and shuffle the rest into your library"; } - + RiptideShapeshifterEffect(final RiptideShapeshifterEffect effect) { super(effect); } - + @Override public RiptideShapeshifterEffect copy() { return new RiptideShapeshifterEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose a creature type:"); choice.setChoices(CardRepository.instance.getCreatureTypes()); - while (!player.choose(Outcome.BoostCreature, choice, game)) { - if (!player.canRespond()) { + while (!controller.choose(Outcome.BoostCreature, choice, game)) { + if (!controller.canRespond()) { return false; } } Cards revealedCards = new CardsImpl(); - while (player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + while (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); if (card.getCardType().contains(CardType.CREATURE) && card.getSubtype().contains(choice.getChoice())) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; } revealedCards.add(card); } - player.revealCards("Riptide Shapeshifter", revealedCards, game); - for (Card card: revealedCards.getCards(game)) { - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - player.shuffleLibrary(game); + controller.revealCards(sourceObject.getIdName(), revealedCards, game); + controller.moveCards(revealedCards, Zone.LIBRARY, source, game); + controller.shuffleLibrary(game); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java b/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java index 39c827a0a17..5c84fa60d09 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java +++ b/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java @@ -38,6 +38,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -67,6 +68,7 @@ public class FrozenAEther extends CardImpl { } class FrozenAEtherTapEffect extends ReplacementEffectImpl { + FrozenAEtherTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts, creatures, and lands your opponents control enter the battlefield tapped"; @@ -78,7 +80,7 @@ class FrozenAEtherTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } @@ -89,15 +91,15 @@ class FrozenAEtherTapEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && - (permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND) || - permanent.getCardType().contains(CardType.ARTIFACT))) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null + && (permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND) + || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/planarchaos/RebuffTheWicked.java b/Mage.Sets/src/mage/sets/planarchaos/RebuffTheWicked.java new file mode 100644 index 00000000000..cf3e1780ce9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planarchaos/RebuffTheWicked.java @@ -0,0 +1,70 @@ +/* + * 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.sets.planarchaos; + +import java.util.UUID; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.target.TargetSpell; + +/** + * + * @author LoneFox + */ +public class RebuffTheWicked extends CardImpl { + + private final static FilterSpell filter = new FilterSpell("spell that targets a permanent you control"); + + static { + filter.add(new TargetsPermanentPredicate(new FilterControlledPermanent())); + } + + public RebuffTheWicked(UUID ownerId) { + super(ownerId, 12, "Rebuff the Wicked", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "PLC"; + + // Counter target spell that targets a permanent you control. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + } + + public RebuffTheWicked(final RebuffTheWicked card) { + super(card); + } + + @Override + public RebuffTheWicked copy() { + return new RebuffTheWicked(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java index 9292efe16a6..92ebfdb6731 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java +++ b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java @@ -35,6 +35,7 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.NameACardEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.repository.CardRepository; @@ -69,7 +70,7 @@ public class VoidstoneGargoyle extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // As Voidstone Gargoyle enters the battlefield, name a nonland card. - this.addAbility(new AsEntersBattlefieldAbility(new VoidstoneGargoyleChooseCardEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new NameACardEffect(NameACardEffect.TypeOfName.NON_LAND_NAME))); // The named card can't be cast. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VoidstoneGargoyleReplacementEffect1())); // Activated abilities of sources with the chosen name can't be activated. @@ -100,7 +101,7 @@ class VoidstoneGargoyleChooseCardEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { Choice cardChoice = new ChoiceImpl(); cardChoice.setChoices(CardRepository.instance.getNonLandNames()); @@ -160,7 +161,8 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifyingEffectI public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { + if (object != null + && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { return true; } } @@ -203,7 +205,7 @@ class VoidstoneGargoyleRuleModifyingEffect2 extends ContinuousRuleModifyingEffec public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ACTIVATE_ABILITY) { MageObject object = game.getObject(event.getSourceId()); - if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { + if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java index 4d91881eea1..55b7eb6adb2 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java +++ b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java @@ -45,6 +45,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -66,7 +67,7 @@ public class PrimalPlasma extends CardImpl { this.toughness = new MageInt(0); // As Primal Plasma enters the battlefield, it becomes your choice of a 3/3 creature, a 2/2 creature with flying, or a 1/6 creature with defender. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalPlasmaReplacementEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new PrimalPlasmaReplacementEffect())); } public PrimalPlasma(final PrimalPlasma card) { @@ -102,7 +103,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -117,7 +118,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what " + permanent.getIdName() + " becomes to"); diff --git a/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java b/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java index e16d11cbd58..2797a6b8908 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java +++ b/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java @@ -29,19 +29,16 @@ package mage.sets.planechase2012; import java.util.UUID; import mage.MageInt; -import mage.MageObject; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.keyword.NinjutsuAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.functions.ApplyToPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.util.functions.AddSubtypeApplier; /** * @@ -60,11 +57,11 @@ public class SakashimasStudent extends CardImpl { // Ninjutsu {1}{U} this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{1}{U}"))); + // You may have Sakashima's Student enter the battlefield as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(new SakashimasStudentApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new AddSubtypeApplier("Ninja")); + effect.setText("as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } @@ -77,23 +74,3 @@ public class SakashimasStudent extends CardImpl { return new SakashimasStudent(this); } } - -class SakashimasStudentApplyToPermanent extends ApplyToPermanent { - - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSubtype().contains("Ninja")) { - permanent.getSubtype().add("Ninja"); - } - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSubtype().contains("Ninja")) { - mageObject.getSubtype().add("Ninja"); - } - return true; - } - -} diff --git a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java index 0125728af80..0bdfbb25581 100644 --- a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java +++ b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java @@ -61,8 +61,7 @@ public class ArcticMerfolk extends CardImpl { // If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - KickedCondition.getInstance(), - true,"If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.","")); + KickedCondition.getInstance(),"If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.","")); } public ArcticMerfolk(final ArcticMerfolk card) { diff --git a/Mage.Sets/src/mage/sets/planeshift/Confound.java b/Mage.Sets/src/mage/sets/planeshift/Confound.java new file mode 100644 index 00000000000..44f266b00bf --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/Confound.java @@ -0,0 +1,73 @@ +/* + * 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.sets.planeshift; + +import java.util.UUID; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.TargetsPermanentPredicate; +import mage.target.TargetSpell; + +/** + * + * @author LoneFox + */ +public class Confound extends CardImpl { + + private final static FilterSpell filter = new FilterSpell("spell that targets one or more creatures"); + + static { + filter.add(new TargetsPermanentPredicate(new FilterCreaturePermanent())); + } + + public Confound(UUID ownerId) { + super(ownerId, 22, "Confound", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "PLS"; + + // Counter target spell that targets one or more creatures. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public Confound(final Confound card) { + super(card); + } + + @Override + public Confound copy() { + return new Confound(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java b/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java index 5a94ca0d4ee..bf5b2311558 100644 --- a/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java +++ b/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java @@ -75,7 +75,7 @@ public class DralnusPet extends CardImpl { kickerCosts.add(new DiscardCardCost(new FilterCreatureCard())); this.addAbility(new KickerAbility(kickerCosts)); // If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost. - Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.getInstance(), true, + Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); @@ -115,7 +115,7 @@ class DralnusPetEffect extends OneShotEffect { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { int cmc = 0; for (Cost cost : spellAbility.getCosts()) { if (cost instanceof DiscardCardCost && ((DiscardCardCost) cost).getCards().size() > 0) { diff --git a/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java b/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java index 5a43de13839..8dae36a679d 100644 --- a/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java +++ b/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java @@ -56,8 +56,7 @@ public class PhyrexianScuta extends CardImpl { // Kicker-Pay 3 life. this.addAbility(new KickerAbility(new PayLifeCost(3))); // If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), - true, "If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it.", "")); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), "If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it.", "")); } public PhyrexianScuta(final PhyrexianScuta card) { diff --git a/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java b/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java index f8c469ed658..e1a02355e1b 100644 --- a/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java +++ b/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java @@ -30,16 +30,14 @@ package mage.sets.ravnica; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterEnchantmentPermanent; import mage.game.Game; @@ -58,13 +56,8 @@ public class CopyEnchantment extends CardImpl { super(ownerId, 42, "Copy Enchantment", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); this.expansionSetCode = "RAV"; - // You may have Copy Enchantment enter the battlefield as a copy of any enchantment on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyEnchantmentEffect(new FilterEnchantmentPermanent()), - "You may have {this} enter the battlefield as a copy of any enchantment on the battlefield", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyEnchantmentEffect(new FilterEnchantmentPermanent("any enchantment")), true)); } public CopyEnchantment(final CopyEnchantment card) { @@ -82,15 +75,15 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { public CopyEnchantmentEffect(FilterPermanent filter) { super(filter, new EmptyApplyToPermanent()); } - + public CopyEnchantmentEffect(final CopyEnchantmentEffect effect) { super(effect); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && sourcePermanent != null) { if (super.apply(game, source)) { Permanent permanentToCopy = getBluePrintPermanent(); @@ -98,9 +91,10 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { if (permanentToCopy.getSubtype().contains("Aura")) { Target target = getBluePrintPermanent().getSpellAbility().getTargets().get(0); Outcome auraOutcome = Outcome.BoostCreature; - Ability: for (Ability ability: getBluePrintPermanent().getAbilities()) { + Ability: + for (Ability ability : getBluePrintPermanent().getAbilities()) { if (ability instanceof SpellAbility) { - for (Effect effect: ability.getEffects()) { + for (Effect effect : ability.getEffects()) { if (effect instanceof AttachEffect) { auraOutcome = effect.getOutcome(); break Ability; @@ -108,6 +102,7 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { } } } + target.setNotTarget(true); if (controller.choose(auraOutcome, target, source.getSourceId(), game)) { UUID targetId = target.getFirstTarget(); Permanent targetPermanent = game.getPermanent(targetId); @@ -127,10 +122,10 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { } return false; } - + @Override public CopyEnchantmentEffect copy() { return new CopyEnchantmentEffect(this); } - + } diff --git a/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java b/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java index 5b4297fba72..b11584bdd31 100644 --- a/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java +++ b/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java @@ -30,20 +30,20 @@ package mage.sets.ravnica; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.cards.CardImpl; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; - /** * * @author fireshoes @@ -75,6 +75,7 @@ public class LoxodonGatekeeper extends CardImpl { } class LoxodonGatekeeperTapEffect extends ReplacementEffectImpl { + LoxodonGatekeeperTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts, creatures, and lands your opponents control enter the battlefield tapped"; @@ -86,26 +87,26 @@ class LoxodonGatekeeperTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && - (permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND) || - permanent.getCardType().contains(CardType.ARTIFACT))) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null + && (permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND) + || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/ravnica/SistersOfStoneDeath.java b/Mage.Sets/src/mage/sets/ravnica/SistersOfStoneDeath.java index 200188ec098..13fa2e682d0 100644 --- a/Mage.Sets/src/mage/sets/ravnica/SistersOfStoneDeath.java +++ b/Mage.Sets/src/mage/sets/ravnica/SistersOfStoneDeath.java @@ -43,7 +43,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.BlockedByIdPredicate; @@ -101,7 +101,7 @@ public class SistersOfStoneDeath extends CardImpl { class SistersOfStoneDeathEffect extends OneShotEffect { - private UUID exileId; + private final UUID exileId; public SistersOfStoneDeathEffect(UUID exileId) { super(Outcome.PutCreatureInPlay); @@ -117,19 +117,19 @@ class SistersOfStoneDeathEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { CardsImpl cardsInExile = new CardsImpl(); - TargetCard target = new TargetCard(Zone.PICK, new FilterCard()); - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { + TargetCard target = new TargetCard(Zone.EXILED, new FilterCreatureCard()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { ExileZone exile = game.getExile().getExileZone(exileId); if (exile != null) { - LinkedList cards = new LinkedList(exile); + LinkedList cards = new LinkedList<>(exile); for (UUID cardId : cards) { Card card = game.getCard(cardId); cardsInExile.add(card); } - if (you.choose(Outcome.PutCreatureInPlay, cardsInExile, target, game)) { + if (controller.choose(Outcome.PutCreatureInPlay, cardsInExile, target, game)) { Card chosenCard = game.getCard(target.getFirstTarget()); - return you.putOntoBattlefieldWithInfo(chosenCard, game, Zone.EXILED, source.getSourceId()); + return controller.moveCards(chosenCard, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java b/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java index 91dd5a1a86c..58085795567 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java @@ -28,30 +28,30 @@ package mage.sets.returntoravnica; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; /** - * http://www.wizards.com/magic/magazine/article.aspx?x=mtg/faq/rtr + * http://www.wizards.com/magic/magazine/article.aspx?x=mtg/faq/rtr * - * If a creature you control would enter the battlefield with a number of +1/+1 - * counters on it, it enters with twice that many instead. + * If a creature you control would enter the battlefield with a number of +1/+1 + * counters on it, it enters with twice that many instead. * - * If you control two Corpsejack Menaces, the number of +1/+1 counters placed - * is four times the original number. Three Corpsejack Menaces multiplies the - * original number by eight, and so on. + * If you control two Corpsejack Menaces, the number of +1/+1 counters placed is + * four times the original number. Three Corpsejack Menaces multiplies the + * original number by eight, and so on. * * @author LevelX2 */ @@ -80,8 +80,8 @@ public class CorpsejackMenace extends CardImpl { } } - class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl { + CorpsejackMenaceReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); staticText = "If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead"; @@ -93,24 +93,24 @@ class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent p = game.getPermanent(event.getTargetId()); - if (p != null) { - p.addCounters(CounterType.P1P1.createInstance(event.getAmount()*2), game, event.getAppliedEffects()); - } - return true; + event.setAmount(event.getAmount() * 2); + return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ADD_COUNTERS; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getData().equals(CounterType.P1P1.getName())) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null && target.getControllerId().equals(source.getControllerId()) - && target.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java index 93753306a08..cdce3f264d5 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java @@ -34,11 +34,10 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; import mage.game.ExileZone; @@ -76,7 +74,7 @@ public class JaceArchitectOfThought extends CardImpl { this.expansionSetCode = "RTR"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn. this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtStartEffect1(), 1)); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java b/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java index ffe0df331bd..5d838ca5ddd 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java @@ -28,10 +28,6 @@ package mage.sets.returntoravnica; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; @@ -39,6 +35,9 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.filter.FilterSpell; import mage.game.Game; import mage.game.permanent.Permanent; @@ -59,7 +58,7 @@ public class TabletOfTheGuilds extends CardImpl { this.addAbility(new AsEntersBattlefieldAbility(new TabletOfTheGuildsEntersBattlefieldEffect())); // Whenever you cast a spell, if it's at least one of the chosen colors, you gain 1 life for each of the chosen colors it is. - this.addAbility(new SpellCastControllerTriggeredAbility(new TabletOfTheGuildsGainLifeEffect(), new FilterSpell("a spell"), false, true )); + this.addAbility(new SpellCastControllerTriggeredAbility(new TabletOfTheGuildsGainLifeEffect(), new FilterSpell("a spell"), false, true)); } public TabletOfTheGuilds(final TabletOfTheGuilds card) { @@ -86,7 +85,7 @@ class TabletOfTheGuildsEntersBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (player != null && permanent != null) { String colors; ChoiceColor colorChoice = new ChoiceColor(); @@ -101,7 +100,7 @@ class TabletOfTheGuildsEntersBattlefieldEffect extends OneShotEffect { colorChoice.getChoices().remove(colorChoice.getChoice()); colorChoice.setMessage("Choose the second color"); - while (!player.choose(Outcome.GainLife, colorChoice, game) && player.canRespond()) { + while (!player.choose(Outcome.GainLife, colorChoice, game) && player.canRespond()) { game.debugMessage("player canceled choosing type. retrying."); } game.getState().setValue(permanent.getId() + "_color2", colorChoice.getColor().toString()); @@ -157,4 +156,4 @@ class TabletOfTheGuildsGainLifeEffect extends OneShotEffect { public TabletOfTheGuildsGainLifeEffect copy() { return new TabletOfTheGuildsGainLifeEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/returntoravnica/VolatileRig.java b/Mage.Sets/src/mage/sets/returntoravnica/VolatileRig.java index cc804adcfad..8a43a92c249 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/VolatileRig.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/VolatileRig.java @@ -195,7 +195,7 @@ class VolatileRigEffect2 extends OneShotEffect { for (Permanent permanent: permanents) { permanent.damage(4, source.getSourceId(), game, false, true); } - for (UUID playerId: player.getInRange()) { + for (UUID playerId: game.getState().getPlayersInRange(player.getId(), game)) { Player damageToPlayer = game.getPlayer(playerId); if (damageToPlayer != null) { damageToPlayer.damage(4, source.getSourceId(), game, false, true); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java index 3c890808dd2..776fd85498b 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java @@ -33,13 +33,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseGameTargetPlayerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.events.DamagedPlaneswalkerEvent; import mage.game.events.GameEvent; @@ -76,7 +74,7 @@ public class VraskaTheUnseen extends CardImpl { this.expansionSetCode = "RTR"; this.subtype.add("Vraska"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Until your next turn, whenever a creature deals combat damage to Vraska the Unseen, destroy that creature. this.addAbility(new LoyaltyAbility(new VraskaTheUnseenGainAbilityEffect(new VraskaTheUnseenTriggeredAbility()), 1)); diff --git a/Mage.Sets/src/mage/sets/revisededition/Chaoslace.java b/Mage.Sets/src/mage/sets/revisededition/Chaoslace.java new file mode 100644 index 00000000000..247ae5fe06d --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/Chaoslace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Chaoslace extends mage.sets.fourthedition.Chaoslace { + + public Chaoslace(UUID ownerId) { + super(ownerId); + this.cardNumber = 140; + this.expansionSetCode = "3ED"; + } + + public Chaoslace(final Chaoslace card) { + super(card); + } + + @Override + public Chaoslace copy() { + return new Chaoslace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/revisededition/Deathlace.java b/Mage.Sets/src/mage/sets/revisededition/Deathlace.java new file mode 100644 index 00000000000..55e0d3a6a95 --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/Deathlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Deathlace extends mage.sets.limitedbeta.Deathlace { + + public Deathlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 10; + this.expansionSetCode = "3ED"; + } + + public Deathlace(final Deathlace card) { + super(card); + } + + @Override + public Deathlace copy() { + return new Deathlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/revisededition/Lifelace.java b/Mage.Sets/src/mage/sets/revisededition/Lifelace.java new file mode 100644 index 00000000000..3012b263eb7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/Lifelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Lifelace extends mage.sets.limitedalpha.Lifelace { + + public Lifelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 115; + this.expansionSetCode = "3ED"; + } + + public Lifelace(final Lifelace card) { + super(card); + } + + @Override + public Lifelace copy() { + return new Lifelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/revisededition/Purelace.java b/Mage.Sets/src/mage/sets/revisededition/Purelace.java new file mode 100644 index 00000000000..35bf375c635 --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/Purelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Purelace extends mage.sets.unlimitededition.Purelace { + + public Purelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 216; + this.expansionSetCode = "3ED"; + } + + public Purelace(final Purelace card) { + super(card); + } + + @Override + public Purelace copy() { + return new Purelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/revisededition/Thoughtlace.java b/Mage.Sets/src/mage/sets/revisededition/Thoughtlace.java new file mode 100644 index 00000000000..a0415d3b7e2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/revisededition/Thoughtlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.revisededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Thoughtlace extends mage.sets.limitedbeta.Thoughtlace { + + public Thoughtlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 85; + this.expansionSetCode = "3ED"; + } + + public Thoughtlace(final Thoughtlace card) { + super(card); + } + + @Override + public Thoughtlace copy() { + return new Thoughtlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java index bd4d6e4b53f..db2d0e39027 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/CurseOfWizardry.java @@ -29,13 +29,11 @@ package mage.sets.riseoftheeldrazi; import java.util.UUID; import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseColorEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.cards.CardImpl; -import mage.choices.ChoiceColor; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -45,7 +43,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.stack.Spell; -import mage.players.Player; import mage.target.targetpointer.FixedTarget; /** @@ -57,9 +54,8 @@ public class CurseOfWizardry extends CardImpl { super(ownerId, 104, "Curse of Wizardry", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); this.expansionSetCode = "ROE"; - // As Curse of Wizardry enters the battlefield, choose a color. - this.addAbility(new AsEntersBattlefieldAbility(new CurseOfWizardryChooseColorEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral))); // Whenever a player casts a spell of the chosen color, that player loses 1 life. this.addAbility(new CurseOfWizardryPlayerCastsSpellChosenColorTriggeredAbility()); @@ -76,38 +72,6 @@ public class CurseOfWizardry extends CardImpl { } } -class CurseOfWizardryChooseColorEffect extends OneShotEffect { - - public CurseOfWizardryChooseColorEffect() { - super(Outcome.Detriment); - staticText = "choose a color"; - } - - public CurseOfWizardryChooseColorEffect(final CurseOfWizardryChooseColorEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent curseOfWizardry = game.getPermanent(source.getSourceId()); - if (player != null && curseOfWizardry != null) { - ChoiceColor colorChoice = new ChoiceColor(); - if (player.choose(Outcome.Detriment, colorChoice, game)) { - game.informPlayers(curseOfWizardry.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice()); - game.getState().setValue(curseOfWizardry.getId() + "_color", colorChoice.getColor()); - curseOfWizardry.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); - } - } - return false; - } - - @Override - public CurseOfWizardryChooseColorEffect copy() { - return new CurseOfWizardryChooseColorEffect(this); - } -} - class CurseOfWizardryPlayerCastsSpellChosenColorTriggeredAbility extends TriggeredAbilityImpl { public CurseOfWizardryPlayerCastsSpellChosenColorTriggeredAbility() { diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java index 45fdec326b5..52140b5319a 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,12 +20,11 @@ * 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.sets.riseoftheeldrazi; import java.util.UUID; @@ -33,19 +32,17 @@ import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TurnPhase; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; @@ -71,9 +68,8 @@ public class GideonJura extends CardImpl { this.expansionSetCode = "ROE"; this.subtype.add("Gideon"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); - // +2: During target opponent's next turn, creatures that player controls attack Gideon Jura if able. LoyaltyAbility ability1 = new LoyaltyAbility(new GideonJuraEffect(), 2); ability1.addTarget(new TargetOpponent()); @@ -148,9 +144,9 @@ class GideonJuraEffect extends RequirementEffect { @Override public boolean isInactive(Ability source, Game game) { - return (startingTurn != game.getTurnNum() && - (game.getPhase().getType() == TurnPhase.END && - game.getActivePlayerId().equals(source.getFirstTarget()))) + return (startingTurn != game.getTurnNum() + && (game.getPhase().getType() == TurnPhase.END + && game.getActivePlayerId().equals(source.getFirstTarget()))) || // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all. creatingPermanent.getPermanent(game) == null; } @@ -169,4 +165,4 @@ class GideonJuraEffect extends RequirementEffect { public boolean mustBlock(Game game) { return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/NotOfThisWorld.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/NotOfThisWorld.java index 97363cb0aa8..42b6e9c8f46 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/NotOfThisWorld.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/NotOfThisWorld.java @@ -27,6 +27,8 @@ */ package mage.sets.riseoftheeldrazi; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -39,17 +41,17 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.Filter; -import mage.filter.FilterSpell; -import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; -import mage.filter.predicate.other.TargetsPermanentPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackAbility; import mage.game.stack.StackObject; import mage.target.Target; -import mage.target.TargetSpell; +import mage.target.TargetObject; +import mage.target.Targets; /** * @@ -57,19 +59,14 @@ import mage.target.TargetSpell; */ public class NotOfThisWorld extends CardImpl { - private final static FilterSpell filter = new FilterSpell("spell that targets a permanent you control"); - - static { - filter.add(new TargetsPermanentPredicate(new FilterControlledPermanent())); - } - public NotOfThisWorld(UUID ownerId) { super(ownerId, 8, "Not of This World", Rarity.UNCOMMON, new CardType[]{CardType.TRIBAL, CardType.INSTANT}, "{7}"); this.expansionSetCode = "ROE"; this.subtype.add("Eldrazi"); // Counter target spell or ability that targets a permanent you control. - this.getSpellAbility().addTarget(new TargetSpell(filter)); + this.getSpellAbility().addTarget( + new TargetStackObjectTargetingControlledPermanent()); this.getSpellAbility().addEffect(new CounterTargetEffect()); // Not of This World costs {7} less to cast if it targets a spell or ability that targets a creature you control with power 7 or greater. this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(7, NotOfThisWorldCondition.getInstance()))); @@ -85,6 +82,92 @@ public class NotOfThisWorld extends CardImpl { } } +class TargetStackObjectTargetingControlledPermanent extends TargetObject { + + public TargetStackObjectTargetingControlledPermanent() { + this.minNumberOfTargets = 1; + this.maxNumberOfTargets = 1; + this.zone = Zone.STACK; + this.targetName = "spell or ability that targets a permanent you control"; + } + + public TargetStackObjectTargetingControlledPermanent(final TargetStackObjectTargetingControlledPermanent target) { + super(target); + } + + @Override + public Filter getFilter() { + throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + StackObject stackObject = game.getStack().getStackObject(id); + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + return true; + } + return false; + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + return canChoose(sourceControllerId, game); + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null && targetedPermanent.getControllerId().equals(sourceControllerId)) { + return true; + } + } + } + } + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, + Game game) { + return possibleTargets(sourceControllerId, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null && targetedPermanent.getControllerId().equals(sourceControllerId)) { + possibleTargets.add(stackObject.getId()); + } + } + } + } + } + } + return possibleTargets; + } + + @Override + public TargetStackObjectTargetingControlledPermanent copy() { + return new TargetStackObjectTargetingControlledPermanent(this); + } + +} + class NotOfThisWorldCondition implements Condition { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control with power 7 or greater"); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java index 8cdd3585f79..8252432060e 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java @@ -33,9 +33,8 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; @@ -43,7 +42,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -65,7 +63,7 @@ public class SarkhanTheMad extends CardImpl { super(ownerId, 214, "Sarkhan the Mad", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{B}{R}"); this.expansionSetCode = "ROE"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(7)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(7)); this.addAbility(new LoyaltyAbility(new SarkhanTheMadRevealAndDrawEffect(), 0)); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java index 2b68b4fc8c4..67375b8e9c8 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,22 +20,21 @@ * 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.sets.riseoftheeldrazi; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -51,7 +50,10 @@ public class WallOfOmens extends CardImpl { this.power = new MageInt(0); this.toughness = new MageInt(4); + // Defender this.addAbility(DefenderAbility.getInstance()); + + // When Wall of Omens enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/EnduringIdeal.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/EnduringIdeal.java index b3483485a0a..02c4cf52ea5 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/EnduringIdeal.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/EnduringIdeal.java @@ -46,7 +46,7 @@ import mage.target.common.TargetCardInLibrary; /** * * @author jeffwadsworth - + * */ public class EnduringIdeal extends CardImpl { @@ -54,13 +54,12 @@ public class EnduringIdeal extends CardImpl { super(ownerId, 9, "Enduring Ideal", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{W}{W}"); this.expansionSetCode = "SOK"; - // Search your library for an enchantment card and put it onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new EnduringIdealEffect()); - + // Epic this.getSpellAbility().addEffect(new EpicEffect()); - + } public EnduringIdeal(final EnduringIdeal card) { @@ -74,9 +73,9 @@ public class EnduringIdeal extends CardImpl { } class EnduringIdealEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard(); - + static { filter.add(new CardTypePredicate(CardType.ENCHANTMENT)); } @@ -93,16 +92,16 @@ class EnduringIdealEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { boolean applied = false; - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { TargetCardInLibrary target = new TargetCardInLibrary(filter); - you.searchLibrary(target, game); + controller.searchLibrary(target, game); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard == null) { applied = false; - } else{ - applied = you.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); - you.shuffleLibrary(game); + } else { + applied = controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); + controller.shuffleLibrary(game); } } return applied; diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/EternalDominion.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/EternalDominion.java index cd5d754421b..7b63cd400fe 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/EternalDominion.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/EternalDominion.java @@ -56,12 +56,11 @@ public class EternalDominion extends CardImpl { super(ownerId, 36, "Eternal Dominion", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{7}{U}{U}{U}"); this.expansionSetCode = "SOK"; - // Search target opponent's library for an artifact, creature, enchantment, or land card. // Put that card onto the battlefield under your control. Then that player shuffles his or her library. this.getSpellAbility().addEffect(new EternalDominionEffect()); this.getSpellAbility().addTarget(new TargetOpponent()); - + // Epic this.getSpellAbility().addEffect(new EpicEffect()); @@ -78,9 +77,9 @@ public class EternalDominion extends CardImpl { } class EternalDominionEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("an artifact, creature, enchantment, or land card"); - + static { filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), @@ -101,13 +100,13 @@ class EternalDominionEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { boolean applied = false; Player opponent = game.getPlayer(source.getFirstTarget()); - Player you = game.getPlayer(source.getControllerId()); - if (opponent != null && you != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (opponent != null && controller != null) { TargetCardInLibrary target = new TargetCardInLibrary(filter); - you.searchLibrary(target, game, opponent.getId()); + controller.searchLibrary(target, game, opponent.getId()); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - applied = you.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); + applied = controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); } opponent.shuffleLibrary(game); } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/FootstepsOfTheGoryo.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/FootstepsOfTheGoryo.java index 1e3be38179f..1fe60da5cad 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/FootstepsOfTheGoryo.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/FootstepsOfTheGoryo.java @@ -28,7 +28,6 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; @@ -37,7 +36,10 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; @@ -93,7 +95,7 @@ class FootstepsOfTheGoryoEffect extends OneShotEffect { if (controller != null) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { // Sacrifice it at end of turn @@ -104,11 +106,10 @@ class FootstepsOfTheGoryoEffect extends OneShotEffect { delayedAbility.setControllerId(source.getControllerId()); delayedAbility.setSourceObject(source.getSourceObject(game), game); game.addDelayedTriggeredAbility(delayedAbility); - return true; - } } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java index 3a4232607be..f468e0e748b 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java @@ -30,26 +30,21 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; /** @@ -58,8 +53,6 @@ import mage.util.functions.ApplyToPermanent; */ public class SakashimaTheImpostor extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains \"{2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step.\""; - public SakashimaTheImpostor(UUID ownerId) { super(ownerId, 53, "Sakashima the Impostor", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.expansionSetCode = "SOK"; @@ -70,9 +63,9 @@ public class SakashimaTheImpostor extends CardImpl { this.toughness = new MageInt(1); // You may have Sakashima the Impostor enter the battlefield as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains "{2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new SakashimaTheImpostorCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new SakashimaTheImpostorApplier()); + effect.setText("as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains \"{2}{U}{U}: Return {this} to its owner's hand at the beginning of the next end step.\""); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public SakashimaTheImpostor(final SakashimaTheImpostor card) { @@ -85,67 +78,34 @@ public class SakashimaTheImpostor extends CardImpl { } } -class SakashimaTheImpostorCopyEffect extends OneShotEffect { - - public SakashimaTheImpostorCopyEffect() { - super(Outcome.Copy); - } - - public SakashimaTheImpostorCopyEffect(final SakashimaTheImpostorCopyEffect effect) { - super(effect); - } +class SakashimaTheImpostorApplier extends ApplyToPermanent { @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterCreaturePermanent()); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSupertype().contains("Legendary")) { - permanent.getSubtype().add("Legendary"); - } - permanent.setName("Sakashima the Impostor"); - // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step - permanent.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), - new ManaCostsImpl("{2}{U}{U}") - ), game); - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSupertype().contains("Legendary")) { - mageObject.getSubtype().add("Legendary"); - } - mageObject.setName("Sakashima the Impostor"); - // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step - mageObject.getAbilities().add(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), - new ManaCostsImpl("{2}{U}{U}") - )); - return true; - } - - }); - - return true; - } - } + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSupertype().contains("Legendary")) { + permanent.getSubtype().add("Legendary"); } - return false; + permanent.setName("Sakashima the Impostor"); + // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step + permanent.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), + new ManaCostsImpl("{2}{U}{U}") + ), game); + return true; } @Override - public SakashimaTheImpostorCopyEffect copy() { - return new SakashimaTheImpostorCopyEffect(this); + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSupertype().contains("Legendary")) { + mageObject.getSubtype().add("Legendary"); + } + mageObject.setName("Sakashima the Impostor"); + // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step + mageObject.getAbilities().add(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), + new ManaCostsImpl("{2}{U}{U}") + )); + return true; } + } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java index 9de094b78e4..893edc2be14 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java @@ -25,20 +25,18 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.scarsofmirrodin; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -46,28 +44,25 @@ import mage.game.permanent.PermanentToken; import mage.game.permanent.token.SoldierToken; import mage.players.Player; -import java.util.UUID; - /** * * @author Loki */ public class ElspethTirel extends CardImpl { - public ElspethTirel (UUID ownerId) { + public ElspethTirel(UUID ownerId) { super(ownerId, 6, "Elspeth Tirel", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{W}"); this.expansionSetCode = "SOM"; this.subtype.add("Elspeth"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new LoyaltyAbility(new ElspethTirelFirstEffect(), 2)); this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken(), 3), -2)); this.addAbility(new LoyaltyAbility(new ElspethTirelThirdEffect(), -5)); } - public ElspethTirel (final ElspethTirel card) { + public ElspethTirel(final ElspethTirel card) { super(card); } @@ -78,6 +73,7 @@ public class ElspethTirel extends CardImpl { } class ElspethTirelFirstEffect extends OneShotEffect { + public ElspethTirelFirstEffect() { super(Outcome.GainLife); staticText = "You gain 1 life for each creature you control"; @@ -105,6 +101,7 @@ class ElspethTirelFirstEffect extends OneShotEffect { } class ElspethTirelThirdEffect extends OneShotEffect { + public ElspethTirelThirdEffect() { super(Outcome.DestroyPermanent); staticText = "Destroy all other permanents except for lands and tokens"; @@ -116,9 +113,10 @@ class ElspethTirelThirdEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { - if (!perm.getId().equals(source.getSourceId()) && !(perm instanceof PermanentToken) && ! (perm.getCardType().contains(CardType.LAND))) + for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { + if (!perm.getId().equals(source.getSourceId()) && !(perm instanceof PermanentToken) && !(perm.getCardType().contains(CardType.LAND))) { perm.destroy(source.getSourceId(), game, false); + } } return true; } @@ -128,4 +126,4 @@ class ElspethTirelThirdEffect extends OneShotEffect { return new ElspethTirelThirdEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java index c9c727992b0..1af105c5b8e 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.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.sets.scarsofmirrodin; import java.util.UUID; @@ -33,7 +32,7 @@ import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; @@ -44,7 +43,6 @@ import mage.abilities.effects.common.DynamicManaEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -54,7 +52,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; @@ -70,6 +67,7 @@ import mage.target.common.TargetLandPermanent; * @author Loki, North */ public class KothOfTheHammer extends CardImpl { + static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); private static final FilterLandPermanent filterCount = new FilterLandPermanent("Mountain you control"); @@ -80,15 +78,13 @@ public class KothOfTheHammer extends CardImpl { filterCount.add(new ControllerPredicate(TargetController.YOU)); } - public KothOfTheHammer (UUID ownerId) { + public KothOfTheHammer(UUID ownerId) { super(ownerId, 94, "Koth of the Hammer", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{R}"); this.expansionSetCode = "SOM"; this.subtype.add("Koth"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Untap target Mountain. It becomes a 4/4 red Elemental creature until end of turn. It's still a land. Ability ability = new LoyaltyAbility(new UntapTargetEffect(), 1); ability.addEffect(new BecomesCreatureTargetEffect(new KothOfTheHammerToken(), false, true, Duration.EndOfTurn)); @@ -102,7 +98,7 @@ public class KothOfTheHammer extends CardImpl { this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KothOfTheHammerEmblem()), -5)); } - public KothOfTheHammer (final KothOfTheHammer card) { + public KothOfTheHammer(final KothOfTheHammer card) { super(card); } @@ -111,6 +107,7 @@ public class KothOfTheHammer extends CardImpl { return new KothOfTheHammer(this); } } + class KothOfTheHammerToken extends Token { public KothOfTheHammerToken() { @@ -125,7 +122,9 @@ class KothOfTheHammerToken extends Token { } class KothOfTheHammerEmblem extends Emblem { + // "Mountains you control have '{T}: This land deals 1 damage to target creature or player.'" + public KothOfTheHammerEmblem() { this.setName("EMBLEM: Koth of the Hammer"); this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new KothOfTheHammerThirdEffect())); @@ -133,6 +132,7 @@ class KothOfTheHammerEmblem extends Emblem { } class KothOfTheHammerThirdEffect extends ContinuousEffectImpl { + public KothOfTheHammerThirdEffect() { super(Duration.EndOfGame, Outcome.AddAbility); staticText = "You get an emblem with \"Mountains you control have '{T}: This land deals 1 damage to target creature or player.'\""; diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java index 0b2216e27f9..806759e787d 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.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.sets.scarsofmirrodin; import java.util.HashMap; @@ -76,7 +75,8 @@ public class TunnelIgnus extends CardImpl { } class TunnelIgnusWatcher extends Watcher { - protected Map counts = new HashMap(); + + protected Map counts = new HashMap<>(); public TunnelIgnusWatcher() { super("LandPlayedCount", WatcherScope.PLAYER); @@ -84,7 +84,7 @@ class TunnelIgnusWatcher extends Watcher { public TunnelIgnusWatcher(final TunnelIgnusWatcher watcher) { super(watcher); - for (Entry entry: watcher.counts.entrySet()) { + for (Entry entry : watcher.counts.entrySet()) { counts.put(entry.getKey(), entry.getValue()); } } @@ -116,6 +116,7 @@ class TunnelIgnusWatcher extends Watcher { } class TunnelIgnusTriggeredAbility extends TriggeredAbilityImpl { + TunnelIgnusTriggeredAbility() { super(Zone.BATTLEFIELD, new DamageTargetEffect(3)); } @@ -153,4 +154,4 @@ class TunnelIgnusTriggeredAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever a land enters the battlefield under an opponent's control, if that player had another land enter the battlefield under his or her control this turn, {this} deals 3 damage to that player."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java index 2f4def3ecfd..b3d27b48775 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java @@ -32,7 +32,7 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromExileEffect; import mage.abilities.effects.common.combat.CantBeBlockedAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.FilterSpell; import mage.filter.common.FilterCreaturePermanent; @@ -80,7 +78,7 @@ public class VenserTheSojourner extends CardImpl { this.expansionSetCode = "SOM"; this.subtype.add("Venser"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Exile target permanent you own. Return it to the battlefield under your control at the beginning of the next end step. LoyaltyAbility ability1 = new LoyaltyAbility(new VenserTheSojournerEffect(), 2); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java b/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java index 43423eb386c..c18b7e9d8e5 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java @@ -51,7 +51,6 @@ public class FlourishingDefenses extends CardImpl { super(ownerId, 114, "Flourishing Defenses", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); this.expansionSetCode = "SHM"; - // Whenever a -1/-1 counter is placed on a creature, you may put a 1/1 green Elf Warrior creature token onto the battlefield. this.addAbility(new FlourishingDefensesTriggeredAbility()); @@ -91,7 +90,7 @@ class FlourishingDefensesTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getData().equals(CounterType.M1M1.getName())) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent.getCardType().contains(CardType.CREATURE)) { + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java b/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java index e94e6b2e98e..1f031527630 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java @@ -126,7 +126,8 @@ class GlamerSpinnersEffect extends OneShotEffect { LinkedList auras = new LinkedList<>(); auras.addAll(targetPermanent.getAttachments()); - if (controller.choose(Outcome.Neutral, chosenPermanentToAttachAuras, source.getSourceId(), game)) { + if (chosenPermanentToAttachAuras.canChoose(source.getSourceId(), source.getControllerId(), game) + && controller.choose(Outcome.Neutral, chosenPermanentToAttachAuras, source.getSourceId(), game)) { Permanent permanentToAttachAuras = game.getPermanent(chosenPermanentToAttachAuras.getFirstTarget()); if (permanentToAttachAuras != null) { for (UUID auraId : auras) { @@ -163,7 +164,7 @@ class GlamerSpinnersEffect extends OneShotEffect { } return true; } - + return false; } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/ImpromptuRaid.java b/Mage.Sets/src/mage/sets/shadowmoor/ImpromptuRaid.java index 690b42690dd..de9ede0bc2d 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/ImpromptuRaid.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/ImpromptuRaid.java @@ -117,7 +117,7 @@ class ImpromptuRaidEffect extends OneShotEffect { controller.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); return true; } - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java index 1964cd1cc43..ba232975d03 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/LureboundScarecrow.java @@ -32,9 +32,11 @@ import mage.MageInt; import mage.ObjectColor; import mage.abilities.StateTriggeredAbility; import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.effects.common.ChooseColorEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; @@ -56,7 +58,7 @@ public class LureboundScarecrow extends CardImpl { this.toughness = new MageInt(4); // As Lurebound Scarecrow enters the battlefield, choose a color. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Detriment))); // When you control no permanents of the chosen color, sacrifice Lurebound Scarecrow. this.addAbility(new LureboundScarecrowTriggeredAbility()); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java b/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java index 10364727e8c..8ec07fbc98f 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PaintersServant.java @@ -35,10 +35,9 @@ import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseColorEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.choices.ChoiceColor; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -68,7 +67,7 @@ public class PaintersServant extends CardImpl { this.toughness = new MageInt(3); // As Painter's Servant enters the battlefield, choose a color. - this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Detriment))); // All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PaintersServantEffect())); @@ -84,40 +83,6 @@ public class PaintersServant extends CardImpl { } } -class ChooseColorEffect extends OneShotEffect { - - public ChooseColorEffect() { - super(Outcome.Detriment); - staticText = "choose a color"; - } - - public ChooseColorEffect(final ChooseColorEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - ChoiceColor colorChoice = new ChoiceColor(); - if (player.choose(Outcome.Neutral, colorChoice, game)) { - game.informPlayers(new StringBuilder(permanent.getName()).append(": ").append(player.getLogName()).append(" has chosen ").append(colorChoice.getChoice()).toString()); - game.getState().setValue(source.getSourceId() + "_color", colorChoice.getColor()); - permanent.addInfo("chosen color", "Chosen color: " + colorChoice.getColor().getDescription() + "", game); - } - return true; - } - return false; - } - - @Override - public ChooseColorEffect copy() { - return new ChooseColorEffect(this); - } - -} - class PaintersServantEffect extends ContinuousEffectImpl { public PaintersServantEffect() { @@ -175,10 +140,10 @@ class PaintersServantEffect extends ContinuousEffectImpl { } return false; } - + protected static void setCardColor(Card card, String colorString, Game game) { ObjectColor color = game.getState().getCreateCardAttribute(card).getColor(); - switch (colorString) { + switch (colorString) { case "W": color.setWhite(true); break; diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PuppeteerClique.java b/Mage.Sets/src/mage/sets/shadowmoor/PuppeteerClique.java index 3fb47b66b54..c0568cfaf3a 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/PuppeteerClique.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/PuppeteerClique.java @@ -116,16 +116,16 @@ class PuppeteerCliqueEffect extends OneShotEffect { boolean result = false; Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - if (you.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { ContinuousEffect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); - hasteEffect.setTargetPointer(new FixedTarget(permanent.getId())); + hasteEffect.setTargetPointer(new FixedTarget(permanent, game)); game.addEffect(hasteEffect, source); ExileTargetEffect exileEffect = new ExileTargetEffect("exile " + permanent.getLogName()); - exileEffect.setTargetPointer(new FixedTarget(card.getId())); + exileEffect.setTargetPointer(new FixedTarget(permanent, game)); DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect, TargetController.YOU); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java index ee4ee7cc2ca..a21eeaa672c 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java @@ -1,46 +1,43 @@ /* -* 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. -*/ - + * 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.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DestroyAllControlledTargetEffect; -import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.target.TargetPermanent; @@ -52,7 +49,7 @@ import mage.target.common.TargetCreatureOrPlayer; * @author BetaSteward_at_googlemail.com */ public class AjaniVengeant extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("lands"); static { @@ -64,8 +61,7 @@ public class AjaniVengeant extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Target permanent doesn't untap during its controller's next untap step. LoyaltyAbility ability1 = new LoyaltyAbility(new DontUntapInControllersNextUntapStepTargetEffect(), 1); @@ -85,7 +81,6 @@ public class AjaniVengeant extends CardImpl { ability3.addTarget(new TargetPlayer()); this.addAbility(ability3); - } public AjaniVengeant(final AjaniVengeant card) { diff --git a/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java b/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java index b37b88c0d95..6cd0c9bdef5 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,21 +20,16 @@ * 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.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; @@ -43,11 +38,13 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -67,8 +64,7 @@ public class ElspethKnightErrant extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Elspeth"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a 1/1 white Soldier creature token onto the battlefield. Token token = new SoldierToken(); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java b/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java index 4377e3fb628..43196e13e7b 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java @@ -1,50 +1,47 @@ /* -* 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. -*/ - + * 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.sets.shardsofalara; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; import java.util.UUID; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.Effects; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.Effects; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.DragonToken; import mage.target.common.TargetCreaturePermanent; @@ -62,8 +59,7 @@ public class SarkhanVol extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Sarkhan"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Creatures you control get +1/+1 and gain haste until end of turn. Effects effects1 = new Effects(); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java b/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java index 9cae9ec46d7..d4a44c46efb 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java @@ -31,13 +31,12 @@ import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter.ComparisonType; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterArtifactPermanent; @@ -69,7 +67,7 @@ public class TezzeretTheSeeker extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Tezzeret"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Untap up to two target artifacts. LoyaltyAbility ability = new LoyaltyAbility(new UntapTargetEffect(), 1); @@ -109,8 +107,8 @@ class TezzeretTheSeekerEffect2 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } @@ -125,15 +123,15 @@ class TezzeretTheSeekerEffect2 extends OneShotEffect { filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, cmc + 1)); TargetCardInLibrary target = new TargetCardInLibrary(filter); - if (player.searchLibrary(target, game)) { - Card card = player.getLibrary().getCard(target.getFirstTarget(), game); + if (controller.searchLibrary(target, game)) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return true; } - player.shuffleLibrary(game); + controller.shuffleLibrary(game); return false; } } diff --git a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java index 803b119ff50..c286fd7ffbe 100644 --- a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java +++ b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java @@ -44,6 +44,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -65,11 +66,10 @@ public class AquamorphEntity extends CardImpl { this.toughness = new MageInt(0); // As Aquamorph Entity enters the battlefield or is turned face up, it becomes your choice of 5/1 or 1/5. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new AquamorphEntityReplacementEffect()); + Ability ability = new SimpleStaticAbility(Zone.ALL, new AquamorphEntityReplacementEffect()); ability.setWorksFaceDown(true); this.addAbility(ability); - // Morph {2}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{U}"))); } @@ -84,7 +84,6 @@ public class AquamorphEntity extends CardImpl { } } - class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { private final String choice51 = "a 5/1 creature"; @@ -101,7 +100,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { @Override public boolean checksEventType(GameEvent event, Game game) { - switch(event.getType()) { + switch (event.getType()) { case ENTERS_THE_BATTLEFIELD: case TURNFACEUP: return true; @@ -114,7 +113,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = ((EntersTheBattlefieldEvent) event).getTarget();; if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -135,7 +134,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what the creature becomes to"); @@ -143,7 +142,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { choice.getChoices().add(choice15); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - while(!choice.isChosen()) { + while (!choice.isChosen()) { controller.choose(Outcome.Neutral, choice, game); if (!controller.canRespond()) { return false; @@ -168,7 +167,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { } } return false; - + } @Override diff --git a/Mage.Sets/src/mage/sets/tempest/CorpseDance.java b/Mage.Sets/src/mage/sets/tempest/CorpseDance.java index a7589fdc5c7..0087bb59d0c 100644 --- a/Mage.Sets/src/mage/sets/tempest/CorpseDance.java +++ b/Mage.Sets/src/mage/sets/tempest/CorpseDance.java @@ -45,6 +45,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; @@ -58,7 +59,6 @@ public class CorpseDance extends CardImpl { super(ownerId, 10, "Corpse Dance", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{B}"); this.expansionSetCode = "TMP"; - // Buyback {2} this.addAbility(new BuybackAbility("{2}")); @@ -97,26 +97,29 @@ class CorpseDanceEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Card lastCreatureCard = null; - for (Card card :controller.getGraveyard().getCards(game)) { + for (Card card : controller.getGraveyard().getCards(game)) { if (card.getCardType().contains(CardType.CREATURE)) { lastCreatureCard = card; } } if (lastCreatureCard != null) { - if (controller.putOntoBattlefieldWithInfo(lastCreatureCard, game, Zone.GRAVEYARD, source.getSourceId())) { - FixedTarget fixedTarget = new FixedTarget(lastCreatureCard.getId()); - // Gains Haste - ContinuousEffect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); - hasteEffect.setTargetPointer(fixedTarget); - game.addEffect(hasteEffect, source); - // Exile it at end of turn - ExileTargetEffect exileEffect = new ExileTargetEffect(null,"",Zone.BATTLEFIELD); - exileEffect.setTargetPointer(fixedTarget); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + if (controller.moveCards(lastCreatureCard, Zone.BATTLEFIELD, source, game)) { + Permanent creature = game.getPermanent(lastCreatureCard.getId()); + if (creature != null) { + FixedTarget fixedTarget = new FixedTarget(creature, game); + // Gains Haste + ContinuousEffect hasteEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn); + hasteEffect.setTargetPointer(fixedTarget); + game.addEffect(hasteEffect, source); + // Exile it at end of turn + ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD); + exileEffect.setTargetPointer(fixedTarget); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + } } } return true; diff --git a/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java b/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java index a53c41a32c6..8776797ba03 100644 --- a/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java +++ b/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java @@ -48,6 +48,7 @@ import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -69,10 +70,10 @@ public class Dracoplasm extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // As Dracoplasm enters the battlefield, sacrifice any number of creatures. Dracoplasm's power becomes the total power of those creatures and its toughness becomes their total toughness. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DracoplasmEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.ALL, new DracoplasmEffect())); + // {R}: Dracoplasm gets +1/+0 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.R))); } @@ -88,41 +89,41 @@ public class Dracoplasm extends CardImpl { } class DracoplasmEffect extends ReplacementEffectImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); - + static { filter.add(new AnotherPredicate()); } - + public DracoplasmEffect() { - super(Duration.WhileOnBattlefield, Outcome.BoostCreature); + super(Duration.EndOfGame, Outcome.BoostCreature); this.staticText = "As {this} enters the battlefield, sacrifice any number of creatures. {this}'s power becomes the total power of those creatures and its toughness becomes their total toughness"; } - + public DracoplasmEffect(final DracoplasmEffect effect) { super(effect); } - + @Override public DracoplasmEffect copy() { return new DracoplasmEffect(this); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(source.getSourceId()); + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true); @@ -133,7 +134,7 @@ class DracoplasmEffect extends ReplacementEffectImpl { if (target.getTargets().size() > 0) { int power = 0; int toughness = 0; - for (UUID targetId: target.getTargets()) { + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature != null && targetCreature.sacrifice(source.getSourceId(), game)) { power += targetCreature.getPower().getValue(); @@ -146,5 +147,5 @@ class DracoplasmEffect extends ReplacementEffectImpl { } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/tempest/LivingDeath.java b/Mage.Sets/src/mage/sets/tempest/LivingDeath.java index fd01450856a..1980018d64a 100644 --- a/Mage.Sets/src/mage/sets/tempest/LivingDeath.java +++ b/Mage.Sets/src/mage/sets/tempest/LivingDeath.java @@ -27,6 +27,9 @@ */ package mage.sets.tempest; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -39,10 +42,10 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; -import mage.game.ExileZone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; + /** * * @author Plopman @@ -53,7 +56,6 @@ public class LivingDeath extends CardImpl { super(ownerId, 36, "Living Death", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{B}{B}"); this.expansionSetCode = "TMP"; - // Each player exiles all creature cards from his or her graveyard, then sacrifices all creatures he or she controls, then puts all cards he or she exiled this way onto the battlefield. this.getSpellAbility().addEffect(new LivingDeathEffect()); } @@ -67,6 +69,7 @@ public class LivingDeath extends CardImpl { return new LivingDeath(this); } } + class LivingDeathEffect extends OneShotEffect { public LivingDeathEffect() { @@ -88,26 +91,31 @@ class LivingDeathEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { + Map> exiledCards = new HashMap<>(); // move creature cards from graveyard to exile - for (UUID playerId: controller.getInRange()){ + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card :player.getGraveyard().getCards(new FilterCreatureCard(), game)) { - controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true); + Set cardsPlayer = player.getGraveyard().getCards(new FilterCreatureCard(), game); + if (!cardsPlayer.isEmpty()) { + exiledCards.put(player.getId(), cardsPlayer); + player.moveCards(cardsPlayer, Zone.EXILED, source, game); } } } + game.applyEffects(); // sacrifice all creatures - for (Permanent permanent :game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { permanent.sacrifice(source.getSourceId(), game); } + game.applyEffects(); // put exiled cards to battlefield - ExileZone exileZone = game.getState().getExile().getExileZone(source.getSourceId()); - if (exileZone != null) { - for (Card card : exileZone.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Set cardsPlayer = exiledCards.get(playerId); + if (cardsPlayer != null && !cardsPlayer.isEmpty()) { + player.moveCards(cardsPlayer, Zone.BATTLEFIELD, source, game, false, false, false, null); } } } diff --git a/Mage.Sets/src/mage/sets/tempest/RootMaze.java b/Mage.Sets/src/mage/sets/tempest/RootMaze.java index 36109448c25..eb573226647 100644 --- a/Mage.Sets/src/mage/sets/tempest/RootMaze.java +++ b/Mage.Sets/src/mage/sets/tempest/RootMaze.java @@ -38,6 +38,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; @@ -67,6 +68,7 @@ public class RootMaze extends CardImpl { } class RootMazeEffect extends ReplacementEffectImpl { + RootMazeEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts and lands enter the battlefield tapped"; @@ -78,21 +80,21 @@ class RootMazeEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); return permanent != null && (permanent.getCardType().contains(CardType.LAND) || permanent.getCardType().contains(CardType.ARTIFACT)); } diff --git a/Mage.Sets/src/mage/sets/tempest/StaunchDefenders.java b/Mage.Sets/src/mage/sets/tempest/StaunchDefenders.java index 39fe7dbece7..cfaeaa21ead 100644 --- a/Mage.Sets/src/mage/sets/tempest/StaunchDefenders.java +++ b/Mage.Sets/src/mage/sets/tempest/StaunchDefenders.java @@ -28,12 +28,12 @@ package mage.sets.tempest; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -49,6 +49,8 @@ public class StaunchDefenders extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(4); + + // When Staunch Defenders enters the battlefield, you gain 4 life. this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(4), false)); } diff --git a/Mage.Sets/src/mage/sets/tempestremastered/VolrathsLaboratory.java b/Mage.Sets/src/mage/sets/tempestremastered/VolrathsLaboratory.java index 10b1208bbe7..70f4a27f8c7 100644 --- a/Mage.Sets/src/mage/sets/tempestremastered/VolrathsLaboratory.java +++ b/Mage.Sets/src/mage/sets/tempestremastered/VolrathsLaboratory.java @@ -35,6 +35,7 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseColorEffect; import mage.abilities.effects.common.ChooseCreatureTypeEffect; @@ -57,10 +58,12 @@ public class VolrathsLaboratory extends CardImpl { this.expansionSetCode = "TPR"; // As Volrath's Laboratory enters the battlefield, choose a color and a creature type. - Ability ability = new EntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral), null, true, "As Volrath's Laboratory enters the battlefield, choose a color and a creature type.", ""); + Ability ability = new EntersBattlefieldAbility(new ChooseColorEffect(Outcome.Neutral)); + Effect effect = new ChooseColorEffect(Outcome.Neutral); + effect.setText("and a creature type"); ability.addEffect(new ChooseCreatureTypeEffect(Outcome.Neutral)); this.addAbility(ability); - + // {5}, {T}: Put a 2/2 creature token of the chosen color and type onto the battlefield. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VolrathsLaboratoryEffect(), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); @@ -78,21 +81,21 @@ public class VolrathsLaboratory extends CardImpl { } class VolrathsLaboratoryEffect extends OneShotEffect { - + VolrathsLaboratoryEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Put a 2/2 creature token of the chosen color and type onto the battlefield"; } - + VolrathsLaboratoryEffect(final VolrathsLaboratoryEffect effect) { super(effect); } - + @Override public VolrathsLaboratoryEffect copy() { return new VolrathsLaboratoryEffect(this); } - + @Override public boolean apply(Game game, Ability source) { ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); diff --git a/Mage.Sets/src/mage/sets/tenthedition/AcademyResearchers.java b/Mage.Sets/src/mage/sets/tenthedition/AcademyResearchers.java index febe7582f76..f3d2fec5dd3 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/AcademyResearchers.java +++ b/Mage.Sets/src/mage/sets/tenthedition/AcademyResearchers.java @@ -76,35 +76,35 @@ public class AcademyResearchers extends CardImpl { } class AcademyResearchersEffect extends OneShotEffect { - + AcademyResearchersEffect() { super(Outcome.PutCardInPlay); this.staticText = "you may put an Aura card from your hand onto the battlefield attached to {this}."; } - + AcademyResearchersEffect(final AcademyResearchersEffect effect) { super(effect); } - + @Override public AcademyResearchersEffect copy() { return new AcademyResearchersEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null){ + if (controller != null && permanent != null) { FilterCard filter = new FilterCard(); filter.add(new SubtypePredicate("Aura")); filter.add(new AuraCardCanAttachToPermanentId(permanent.getId())); TargetCardInHand target = new TargetCardInHand(0, 1, filter); - if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { game.getState().setValue("attachTo:" + auraInHand.getId(), permanent); - if (player.putOntoBattlefieldWithInfo(auraInHand, game, Zone.HAND, source.getSourceId())) { + if (controller.moveCards(auraInHand, Zone.BATTLEFIELD, source, game)) { permanent.addAttachment(auraInHand.getId(), game); } } diff --git a/Mage.Sets/src/mage/sets/tenthedition/Clone.java b/Mage.Sets/src/mage/sets/tenthedition/Clone.java index 2412dacd079..6869479699a 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/Clone.java +++ b/Mage.Sets/src/mage/sets/tenthedition/Clone.java @@ -25,19 +25,15 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.tenthedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -54,11 +50,12 @@ public class Clone extends CardImpl { this.toughness = new MageInt(0); // You may have Clone enter the battlefield as a copy of any creature on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield", - true)); - this.addAbility(ability); +// ; +// Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( +// new CopyPermanentEffect(), +// "You may have {this} enter the battlefield as a copy of any creature on the battlefield", +// true)); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(), true)); } public Clone(final Clone card) { diff --git a/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java b/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java index eb3d8d91876..7edca1e49b4 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java +++ b/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java @@ -28,14 +28,11 @@ package mage.sets.tenthedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -44,9 +41,9 @@ import mage.filter.predicate.mageobject.CardTypePredicate; * @author jeffwadsworth */ public class SculptingSteel extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("artifact"); - + static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); } @@ -56,11 +53,7 @@ public class SculptingSteel extends CardImpl { this.expansionSetCode = "10E"; // You may have Sculpting Steel enter the battlefield as a copy of any artifact on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(filter), - "You may have {this} enter the battlefield as a copy of any artifact on the battlefield", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public SculptingSteel(final SculptingSteel card) { diff --git a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java index 25c3342c95b..f9749475e70 100644 --- a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java +++ b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; @@ -73,7 +71,7 @@ public class AshiokNightmareWeaver extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Ashiok"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Exile the top three cards of target opponent's library. LoyaltyAbility ability = new LoyaltyAbility(new AshiokNightmareWeaverExileEffect(), 2); @@ -169,16 +167,14 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect { if (target.canChoose(source.getSourceId(), controller.getId(), game)) { if (controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); - if (card != null && controller.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId())) { - // why is this change of controller neccessary? + if (card != null + && controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { - permanent.changeControllerId(source.getControllerId(), game); + ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect(); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); } - - ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect(); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); return true; } } diff --git a/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java b/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java index ec4d805c92a..1710de8c1c3 100644 --- a/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java +++ b/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java @@ -30,21 +30,19 @@ package mage.sets.theros; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; @@ -58,6 +56,7 @@ import mage.game.permanent.token.SoldierToken; public class ElspethSunsChampion extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 4 or greater"); + static { filter.add(new PowerPredicate(Filter.ComparisonType.GreaterThan, 3)); } @@ -67,8 +66,7 @@ public class ElspethSunsChampion extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Elspeth"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put three 1/1 white Soldier creature tokens onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken(), 3), 1)); @@ -95,7 +93,7 @@ class ElspethSunsChampionEmblem extends Emblem { public ElspethSunsChampionEmblem() { this.setName("EMBLEM: Elspeth, Sun's Champion"); - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new BoostControlledEffect(2,2, Duration.WhileOnBattlefield, filter, false)); + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new BoostControlledEffect(2, 2, Duration.WhileOnBattlefield, filter, false)); ability.addEffect(new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter)); this.getAbilities().add(ability); diff --git a/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java b/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java index 62ce1a931bb..ae89cc24db2 100644 --- a/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java +++ b/Mage.Sets/src/mage/sets/theros/PyxisOfPandemonium.java @@ -39,6 +39,8 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -161,8 +163,8 @@ class PyxisOfPandemoniumPutOntoBattlefieldEffect extends OneShotEffect { } else { return true; } - - for (UUID playerId : controller.getInRange()) { + Cards cardsToBringIntoPlay = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { String exileKey = playerId.toString() + CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()).toString(); @@ -173,13 +175,14 @@ class PyxisOfPandemoniumPutOntoBattlefieldEffect extends OneShotEffect { for (Card card : exileZone.getCards(game)) { card.setFaceDown(false, game); if (CardUtil.isPermanentCard(card)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + cardsToBringIntoPlay.add(card); } } } } } } + controller.moveCards(cardsToBringIntoPlay.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/theros/WhipOfErebos.java b/Mage.Sets/src/mage/sets/theros/WhipOfErebos.java index 6b345fdd021..8d9dd84c469 100644 --- a/Mage.Sets/src/mage/sets/theros/WhipOfErebos.java +++ b/Mage.Sets/src/mage/sets/theros/WhipOfErebos.java @@ -115,19 +115,22 @@ class WhipOfErebosEffect extends OneShotEffect { Card card = game.getCard(this.getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { - if (controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) { - // gains haste - ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - // Exile at begin of next end step - ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD); - exileEffect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + Permanent creature = game.getPermanent(card.getId()); + if (creature != null) { + // gains haste + ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + // Exile at begin of next end step + ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD); + exileEffect.setTargetPointer(new FixedTarget(creature, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + } } return true; } diff --git a/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java b/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java index 0166753702c..8dca6413956 100644 --- a/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java +++ b/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java @@ -34,12 +34,10 @@ import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.HasteAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; @@ -49,7 +47,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.Predicates; @@ -70,20 +67,17 @@ public class XenagosTheReveler extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Xenagos"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Add X mana in any combination of {R} and/or {G} to your mana pool, where X is the number of creatures you control. this.addAbility(new LoyaltyAbility(new XenagosManaEffect(), +1)); - + // 0: Put a 2/2 red and green Satyr creature token with haste onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new XenagosSatyrToken()), 0)); // -6: Exile the top seven cards of your library. You may put any number of creature and/or land cards from among them onto the battlefield. this.addAbility(new LoyaltyAbility(new XenagosExileEffect(), -6)); - - } public XenagosTheReveler(final XenagosTheReveler card) { @@ -115,7 +109,7 @@ class XenagosManaEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null){ + if (player != null) { int x = game.getBattlefield().count(new FilterControlledCreaturePermanent(), source.getSourceId(), source.getControllerId(), game); Choice manaChoice = new ChoiceImpl(); Set choices = new LinkedHashSet<>(); @@ -124,7 +118,7 @@ class XenagosManaEffect extends OneShotEffect { manaChoice.setChoices(choices); manaChoice.setMessage("Select color of mana to add"); - for (int i = 0; i < x; i++){ + for (int i = 0; i < x; i++) { Mana mana = new Mana(); while (!player.choose(Outcome.Benefit, manaChoice, game)) { if (!player.canRespond()) { @@ -150,7 +144,6 @@ class XenagosManaEffect extends OneShotEffect { } } - class XenagosSatyrToken extends Token { public XenagosSatyrToken() { @@ -167,7 +160,6 @@ class XenagosSatyrToken extends Token { } - class XenagosExileEffect extends OneShotEffect { public XenagosExileEffect() { @@ -186,28 +178,19 @@ class XenagosExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Cards cards = new CardsImpl(Zone.EXILED); - int count = Math.min(player.getLibrary().size(), 7); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().getFromTop(game); - cards.add(card); - card.moveToExile(null, null, source.getSourceId(), game); - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards exiledCards = new CardsImpl(); + exiledCards.addAll(controller.getLibrary().getTopCards(game, 7)); + controller.moveCards(exiledCards, Zone.EXILED, source, game); FilterCard filter = new FilterCard("creature and/or land cards to put onto the battlefield"); filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.LAND))); + new CardTypePredicate(CardType.LAND))); TargetCard target1 = new TargetCard(0, Integer.MAX_VALUE, Zone.EXILED, filter); - if (cards.size() > 0 + if (exiledCards.size() > 0 && target1.canChoose(source.getSourceId(), source.getControllerId(), game) - && player.choose(Outcome.PutCardInPlay, cards, target1, game)) { - for (UUID targetId: target1.getTargets()) { - Card card = cards.get(targetId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - } + && controller.choose(Outcome.PutCardInPlay, exiledCards, target1, game)) { + controller.moveCards(new CardsImpl(target1.getTargets()), Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/timeshifted/AvoidFate.java b/Mage.Sets/src/mage/sets/timeshifted/AvoidFate.java new file mode 100644 index 00000000000..7d4f7d23cfb --- /dev/null +++ b/Mage.Sets/src/mage/sets/timeshifted/AvoidFate.java @@ -0,0 +1,54 @@ +/* + * 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.sets.timeshifted; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class AvoidFate extends mage.sets.legends.AvoidFate { + + public AvoidFate(UUID ownerId) { + super(ownerId); + this.cardNumber = 73; + this.expansionSetCode = "TSB"; + this.rarity = Rarity.SPECIAL; + } + + public AvoidFate(final AvoidFate card) { + super(card); + } + + @Override + public AvoidFate copy() { + return new AvoidFate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/CastleRaptors.java b/Mage.Sets/src/mage/sets/timespiral/CastleRaptors.java new file mode 100644 index 00000000000..08b2bb0502b --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/CastleRaptors.java @@ -0,0 +1,74 @@ +/* + * 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.sets.timespiral; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.SourceTappedCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class CastleRaptors extends CardImpl { + + public CastleRaptors(UUID ownerId) { + super(ownerId, 5, "Castle Raptors", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{W}"); + this.expansionSetCode = "TSP"; + this.subtype.add("Bird"); + this.subtype.add("Soldier"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // As long as Castle Raptors is untapped, it gets +0/+2. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(0, 2, Duration.WhileOnBattlefield), new InvertCondition(new SourceTappedCondition()), + "As long as {this} is untapped, it gets +0/+2."))); + } + + public CastleRaptors(final CastleRaptors card) { + super(card); + } + + @Override + public CastleRaptors copy() { + return new CastleRaptors(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java index de7538b305a..d2b840b0cb1 100644 --- a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java +++ b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java @@ -60,7 +60,7 @@ public class Hypergenesis extends CardImpl { // Suspend 3-{1}{G}{G} this.addAbility(new SuspendAbility(3, new ManaCostsImpl("{1}{G}{G}"), this)); - + // Starting with you, each player may put an artifact, creature, enchantment, or land card from his or her hand onto the battlefield. Repeat this process until no one puts a card onto the battlefield. this.getSpellAbility().addEffect(new HypergenesisEffect()); } @@ -77,8 +77,9 @@ public class Hypergenesis extends CardImpl { @SuppressWarnings("unchecked") class HypergenesisEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("an artifact, creature, enchantment, or land card"); + static { filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ENCHANTMENT), new CardTypePredicate(CardType.LAND))); } @@ -109,7 +110,7 @@ class HypergenesisEffect extends OneShotEffect { UUID firstInactivePlayer = null; Target target = new TargetCardInHand(filter); - while (controller.canRespond()) { + while (controller.canRespond()) { if (currentPlayer != null && currentPlayer.canRespond() && controller.getInRange().contains(currentPlayer.getId())) { if (firstInactivePlayer == null) { firstInactivePlayer = currentPlayer.getId(); @@ -120,7 +121,7 @@ class HypergenesisEffect extends OneShotEffect { if (target.chooseTarget(outcome, currentPlayer.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - currentPlayer.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); + currentPlayer.moveCards(card, Zone.BATTLEFIELD, source, game); firstInactivePlayer = null; } } diff --git a/Mage.Sets/src/mage/sets/timespiral/LivingEnd.java b/Mage.Sets/src/mage/sets/timespiral/LivingEnd.java index 398a3e28fc2..cf26eed618f 100644 --- a/Mage.Sets/src/mage/sets/timespiral/LivingEnd.java +++ b/Mage.Sets/src/mage/sets/timespiral/LivingEnd.java @@ -27,6 +27,9 @@ */ package mage.sets.timespiral; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; @@ -41,7 +44,6 @@ import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; -import mage.game.ExileZone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -63,7 +65,7 @@ public class LivingEnd extends CardImpl { // Each player exiles all creature cards from his or her graveyard, then sacrifices all creatures // he or she controls, then puts all cards he or she exiled this way onto the battlefield. this.getSpellAbility().addEffect(new LivingEndEffect()); - + } public LivingEnd(final LivingEnd card) { @@ -97,26 +99,29 @@ class LivingEndEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); if (controller != null && sourceObject != null) { + Map> exiledCards = new HashMap<>(); // move creature cards from graveyard to exile - for (UUID playerId: controller.getInRange()){ + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card :player.getGraveyard().getCards(new FilterCreatureCard(), game)) { - controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.GRAVEYARD, true); + Set cardsPlayer = player.getGraveyard().getCards(new FilterCreatureCard(), game); + if (!cardsPlayer.isEmpty()) { + exiledCards.put(player.getId(), cardsPlayer); + player.moveCards(cardsPlayer, Zone.EXILED, source, game); } } } // sacrifice all creatures - for (Permanent permanent :game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { permanent.sacrifice(source.getSourceId(), game); } // put exiled cards to battlefield - ExileZone exileZone = game.getState().getExile().getExileZone(source.getSourceId()); - if (exileZone != null) { - for (Card card : exileZone.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Set cardsPlayer = exiledCards.get(playerId); + if (cardsPlayer != null && !cardsPlayer.isEmpty()) { + player.moveCards(cardsPlayer, Zone.BATTLEFIELD, source, game, false, false, false, null); } } } diff --git a/Mage.Sets/src/mage/sets/timespiral/Moonlace.java b/Mage.Sets/src/mage/sets/timespiral/Moonlace.java new file mode 100644 index 00000000000..8babbebfc6b --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/Moonlace.java @@ -0,0 +1,62 @@ +/* + * 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.sets.timespiral; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author AlumiuN + */ +public class Moonlace extends CardImpl { + + public Moonlace(UUID ownerId) { + super(ownerId, 68, "Moonlace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{U}"); + this.expansionSetCode = "TSP"; + + // Target spell or permanent becomes colorless. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(new ObjectColor(), Duration.Custom)); + } + + public Moonlace(final Moonlace card) { + super(card); + } + + @Override + public Moonlace copy() { + return new Moonlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/StuffyDoll.java b/Mage.Sets/src/mage/sets/timespiral/StuffyDoll.java index 7927019a7b4..2a30d327984 100644 --- a/Mage.Sets/src/mage/sets/timespiral/StuffyDoll.java +++ b/Mage.Sets/src/mage/sets/timespiral/StuffyDoll.java @@ -35,6 +35,7 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChoosePlayerEffect; import mage.abilities.effects.common.DamageSelfEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; @@ -45,10 +46,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetPlayer; - /** * @@ -64,7 +62,7 @@ public class StuffyDoll extends CardImpl { this.toughness = new MageInt(1); // As Stuffy Doll enters the battlefield, choose a player. - this.addAbility(new AsEntersBattlefieldAbility(new StuffyDollChoosePlayerEffect())); + this.addAbility(new AsEntersBattlefieldAbility(new ChoosePlayerEffect(Outcome.Damage))); // Stuffy Doll is indestructible. this.addAbility(IndestructibleAbility.getInstance()); // Whenever Stuffy Doll is dealt damage, it deals that much damage to the chosen player. @@ -83,41 +81,6 @@ public class StuffyDoll extends CardImpl { } } -class StuffyDollChoosePlayerEffect extends OneShotEffect { - - public StuffyDollChoosePlayerEffect() { - super(Outcome.Detriment); - this.staticText = "choose a player"; - } - - public StuffyDollChoosePlayerEffect(final StuffyDollChoosePlayerEffect effect) { - super(effect); - } - - @Override - public StuffyDollChoosePlayerEffect copy() { - return new StuffyDollChoosePlayerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { - TargetPlayer target = new TargetPlayer(); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { - Player chosenPlayer = game.getPlayer(target.getFirstTarget()); - if (chosenPlayer != null) { - game.informPlayers(permanent.getName() + ": " + player.getLogName() + " has chosen " + chosenPlayer.getLogName()); - game.getState().setValue(permanent.getId() + "_player", target.getFirstTarget()); - return true; - } - } - } - return false; - } -} - class StuffyDollTriggeredAbility extends TriggeredAbilityImpl { public StuffyDollTriggeredAbility() { @@ -179,4 +142,3 @@ class StuffyDollGainLifeEffect extends OneShotEffect { return true; } } - diff --git a/Mage.Sets/src/mage/sets/timespiral/Vesuva.java b/Mage.Sets/src/mage/sets/timespiral/Vesuva.java index 197107be0c8..99f6571e913 100644 --- a/Mage.Sets/src/mage/sets/timespiral/Vesuva.java +++ b/Mage.Sets/src/mage/sets/timespiral/Vesuva.java @@ -28,14 +28,14 @@ package mage.sets.timespiral; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.TapSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -56,12 +56,13 @@ public class Vesuva extends CardImpl { this.expansionSetCode = "TSP"; // You may have Vesuva enter the battlefield tapped as a copy of any land on the battlefield. - EntersBattlefieldEffect effect = new EntersBattlefieldEffect( - new TapSourceEffect(true), - "You may have {this} enter the battlefield tapped as a copy of any land on the battlefield", - true); - effect.addEffect(new CopyPermanentEffect(filter)); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + Effect effect = new TapSourceEffect(true); + effect.setText("tapped"); + Ability ability = new EntersBattlefieldAbility(effect, true); + effect = new CopyPermanentEffect(filter); + effect.setText("as a copy of any land on the battlefield"); + ability.addEffect(effect); + this.addAbility(ability); } public Vesuva(final Vesuva card) { diff --git a/Mage.Sets/src/mage/sets/torment/CabalTorturer.java b/Mage.Sets/src/mage/sets/torment/CabalTorturer.java new file mode 100644 index 00000000000..9c68435e04f --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/CabalTorturer.java @@ -0,0 +1,84 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class CabalTorturer extends CardImpl { + + public CabalTorturer(UUID ownerId) { + super(ownerId, 53, "Cabal Torturer", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Human"); + this.subtype.add("Minion"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {B}, {tap}: Target creature gets -1/-1 until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1, -1, Duration.EndOfTurn), new ManaCostsImpl("{B}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + // Threshold - {3}{B}{B}, {tap}: Target creature gets -2/-2 until end of turn. Activate this ability only if seven or more cards are in your graveyard. + ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), + new ManaCostsImpl("{3}{B}{B}"), new CardsInControllerGraveCondition(7)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public CabalTorturer(final CabalTorturer card) { + super(card); + } + + @Override + public CabalTorturer copy() { + return new CabalTorturer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/CentaurChieftain.java b/Mage.Sets/src/mage/sets/torment/CentaurChieftain.java new file mode 100644 index 00000000000..a548a2bb0c9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/CentaurChieftain.java @@ -0,0 +1,90 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class CentaurChieftain extends CardImpl { + + public CentaurChieftain(UUID ownerId) { + super(ownerId, 122, "Centaur Chieftain", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Centaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Haste + this.addAbility(HasteAbility.getInstance()); + // Threshold - As long as seven or more cards are in your graveyard, Centaur Chieftain has "When Centaur Chieftain enters the battlefield, creatures you control get +1/+1 and gain trample until end of turn." + Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn); + effect.setText("creatures you control get +1/+1"); + Ability gainedAbility = new EntersBattlefieldTriggeredAbility(effect); + effect = new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, + new FilterControlledCreaturePermanent()); + effect.setText("and gain trample until end of turn"); + gainedAbility.addEffect(effect); + + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new GainAbilitySourceEffect(gainedAbility), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} has \"When {this} enters the battlefield, creatures you control get +1/+1 and gain trample until end of turn.\"")); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public CentaurChieftain(final CentaurChieftain card) { + super(card); + } + + @Override + public CentaurChieftain copy() { + return new CentaurChieftain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/PardicArsonist.java b/Mage.Sets/src/mage/sets/torment/PardicArsonist.java new file mode 100644 index 00000000000..0a7b965bfab --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/PardicArsonist.java @@ -0,0 +1,79 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + */ +public class PardicArsonist extends CardImpl { + + public PardicArsonist(UUID ownerId) { + super(ownerId, 105, "Pardic Arsonist", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Human"); + this.subtype.add("Barbarian"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Threshold - As long as seven or more cards are in your graveyard, Pardic Arsonist has "When Pardic Arsonist enters the battlefield, it deals 3 damage to target creature or player." + Ability gainedAbility = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(3)); + gainedAbility.addTarget(new TargetCreatureOrPlayer()); + + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new GainAbilitySourceEffect(gainedAbility), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} has \"When {this} enters the battlefield, it deals 3 damage to target creature or player.\"")); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public PardicArsonist(final PardicArsonist card) { + super(card); + } + + @Override + public PardicArsonist copy() { + return new PardicArsonist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/PossessedAven.java b/Mage.Sets/src/mage/sets/torment/PossessedAven.java new file mode 100644 index 00000000000..e51fc4f6625 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/PossessedAven.java @@ -0,0 +1,107 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class PossessedAven extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue creature"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLUE)); + } + + public PossessedAven(UUID ownerId) { + super(ownerId, 45, "Possessed Aven", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Bird"); + this.subtype.add("Soldier"); + this.subtype.add("Horror"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Threshold - As long as seven or more cards are in your graveyard, Possessed Aven gets +1/+1, is black, and has "{2}{B}, {tap}: Destroy target blue creature." + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +1/+1")); + + Effect effect = new ConditionalContinuousEffect(new BecomesColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), ", is black"); + ability.addEffect(effect); + + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{B}")); + gainedAbility.addCost(new TapSourceCost()); + gainedAbility.addTarget(new TargetCreaturePermanent(filter)); + effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(gainedAbility), + new CardsInControllerGraveCondition(7), ", and has \"{2}{B}, {T}: Destroy target blue creature.\""); + ability.addEffect(effect); + + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public PossessedAven(final PossessedAven card) { + super(card); + } + + @Override + public PossessedAven copy() { + return new PossessedAven(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/PossessedBarbarian.java b/Mage.Sets/src/mage/sets/torment/PossessedBarbarian.java new file mode 100644 index 00000000000..311f0475080 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/PossessedBarbarian.java @@ -0,0 +1,107 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class PossessedBarbarian extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("red creature"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + } + + public PossessedBarbarian(UUID ownerId) { + super(ownerId, 111, "Possessed Barbarian", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Human"); + this.subtype.add("Barbarian"); + this.subtype.add("Horror"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + // Threshold - As long as seven or more cards are in your graveyard, Possessed Barbarian gets +1/+1, is black, and has "{2}{B}, {tap}: Destroy target red creature." + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +1/+1")); + + Effect effect = new ConditionalContinuousEffect(new BecomesColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), ", is black"); + ability.addEffect(effect); + + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{B}")); + gainedAbility.addCost(new TapSourceCost()); + gainedAbility.addTarget(new TargetCreaturePermanent(filter)); + effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(gainedAbility), + new CardsInControllerGraveCondition(7), ", and has \"{2}{B}, {T}: Destroy target red creature.\""); + ability.addEffect(effect); + + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public PossessedBarbarian(final PossessedBarbarian card) { + super(card); + } + + @Override + public PossessedBarbarian copy() { + return new PossessedBarbarian(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/PossessedCentaur.java b/Mage.Sets/src/mage/sets/torment/PossessedCentaur.java new file mode 100644 index 00000000000..8117de8c695 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/PossessedCentaur.java @@ -0,0 +1,106 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class PossessedCentaur extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("green creature"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + public PossessedCentaur(UUID ownerId) { + super(ownerId, 137, "Possessed Centaur", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Centaur"); + this.subtype.add("Horror"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Threshold - As long as seven or more cards are in your graveyard, Possessed Centaur gets +1/+1, is black, and has "{2}{B}, {tap}: Destroy target green creature." + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +1/+1")); + + Effect effect = new ConditionalContinuousEffect(new BecomesColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), ", is black"); + ability.addEffect(effect); + + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{B}")); + gainedAbility.addCost(new TapSourceCost()); + gainedAbility.addTarget(new TargetCreaturePermanent(filter)); + effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(gainedAbility), + new CardsInControllerGraveCondition(7), ", and has \"{2}{B}, {T}: Destroy target green creature.\""); + ability.addEffect(effect); + + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public PossessedCentaur(final PossessedCentaur card) { + super(card); + } + + @Override + public PossessedCentaur copy() { + return new PossessedCentaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/PossessedNomad.java b/Mage.Sets/src/mage/sets/torment/PossessedNomad.java new file mode 100644 index 00000000000..2f8f67b3e07 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/PossessedNomad.java @@ -0,0 +1,107 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class PossessedNomad extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creature"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public PossessedNomad(UUID ownerId) { + super(ownerId, 13, "Possessed Nomad", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{W}{W}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Human"); + this.subtype.add("Nomad"); + this.subtype.add("Horror"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + // Threshold - As long as seven or more cards are in your graveyard, Possessed Nomad gets +1/+1, is black, and has "{2}{B}, {tap}: Destroy target white creature." + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 1, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +1/+1")); + + Effect effect = new ConditionalContinuousEffect(new BecomesColorSourceEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), ", is black"); + ability.addEffect(effect); + + Ability gainedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{2}{B}")); + gainedAbility.addCost(new TapSourceCost()); + gainedAbility.addTarget(new TargetCreaturePermanent(filter)); + effect = new ConditionalContinuousEffect(new GainAbilitySourceEffect(gainedAbility), + new CardsInControllerGraveCondition(7), ", and has \"{2}{B}, {T}: Destroy target white creature.\""); + ability.addEffect(effect); + + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public PossessedNomad(final PossessedNomad card) { + super(card); + } + + @Override + public PossessedNomad copy() { + return new PossessedNomad(this); + } +} diff --git a/Mage.Sets/src/mage/sets/torment/SetonsScout.java b/Mage.Sets/src/mage/sets/torment/SetonsScout.java new file mode 100644 index 00000000000..cced148dca5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/SetonsScout.java @@ -0,0 +1,79 @@ +/* + * 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.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CardsInControllerGraveCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class SetonsScout extends CardImpl { + + public SetonsScout(UUID ownerId) { + super(ownerId, 138, "Seton's Scout", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Centaur"); + this.subtype.add("Druid"); + this.subtype.add("Scout"); + this.subtype.add("Archer"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Reach + this.addAbility(ReachAbility.getInstance()); + // Threshold - Seton's Scout gets +2/+2 as long as seven or more cards are in your graveyard. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), new CardsInControllerGraveCondition(7), + "As long as seven or more cards are in your graveyard, {this} gets +2/+2")); + ability.setAbilityWord(AbilityWord.THRESHOLD); + this.addAbility(ability); + } + + public SetonsScout(final SetonsScout card) { + super(card); + } + + @Override + public SetonsScout copy() { + return new SetonsScout(this); + } +} diff --git a/Mage.Sets/src/mage/sets/unlimitededition/Chaoslace.java b/Mage.Sets/src/mage/sets/unlimitededition/Chaoslace.java new file mode 100644 index 00000000000..b42abd03c4b --- /dev/null +++ b/Mage.Sets/src/mage/sets/unlimitededition/Chaoslace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.unlimitededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Chaoslace extends mage.sets.fourthedition.Chaoslace { + + public Chaoslace(UUID ownerId) { + super(ownerId); + this.cardNumber = 140; + this.expansionSetCode = "2ED"; + } + + public Chaoslace(final Chaoslace card) { + super(card); + } + + @Override + public Chaoslace copy() { + return new Chaoslace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/unlimitededition/Deathlace.java b/Mage.Sets/src/mage/sets/unlimitededition/Deathlace.java new file mode 100644 index 00000000000..6dd2d54e012 --- /dev/null +++ b/Mage.Sets/src/mage/sets/unlimitededition/Deathlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.unlimitededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Deathlace extends mage.sets.limitedbeta.Deathlace { + + public Deathlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 10; + this.expansionSetCode = "2ED"; + } + + public Deathlace(final Deathlace card) { + super(card); + } + + @Override + public Deathlace copy() { + return new Deathlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/unlimitededition/Lifelace.java b/Mage.Sets/src/mage/sets/unlimitededition/Lifelace.java new file mode 100644 index 00000000000..d96ebdbe10d --- /dev/null +++ b/Mage.Sets/src/mage/sets/unlimitededition/Lifelace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.unlimitededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Lifelace extends mage.sets.limitedalpha.Lifelace { + + public Lifelace(UUID ownerId) { + super(ownerId); + this.cardNumber = 116; + this.expansionSetCode = "2ED"; + } + + public Lifelace(final Lifelace card) { + super(card); + } + + @Override + public Lifelace copy() { + return new Lifelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/unlimitededition/Purelace.java b/Mage.Sets/src/mage/sets/unlimitededition/Purelace.java new file mode 100644 index 00000000000..d7fb351bf06 --- /dev/null +++ b/Mage.Sets/src/mage/sets/unlimitededition/Purelace.java @@ -0,0 +1,62 @@ +/* + * 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.sets.unlimitededition; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetSpellOrPermanent; + +/** + * + * @author AlumiuN + */ +public class Purelace extends CardImpl { + + public Purelace(UUID ownerId) { + super(ownerId, 217, "Purelace", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{W}"); + this.expansionSetCode = "2ED"; + + // Target spell or permanent becomes white. + this.getSpellAbility().addTarget(new TargetSpellOrPermanent()); + this.getSpellAbility().addEffect(new BecomesColorTargetEffect(ObjectColor.WHITE, Duration.Custom)); + } + + public Purelace(final Purelace card) { + super(card); + } + + @Override + public Purelace copy() { + return new Purelace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/unlimitededition/Thoughtlace.java b/Mage.Sets/src/mage/sets/unlimitededition/Thoughtlace.java new file mode 100644 index 00000000000..e7fb6d39082 --- /dev/null +++ b/Mage.Sets/src/mage/sets/unlimitededition/Thoughtlace.java @@ -0,0 +1,52 @@ +/* + * 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.sets.unlimitededition; + +import java.util.UUID; + +/** + * + * @author AlumiuN + */ +public class Thoughtlace extends mage.sets.limitedbeta.Thoughtlace { + + public Thoughtlace(UUID ownerId) { + super(ownerId); + this.cardNumber = 83; + this.expansionSetCode = "2ED"; + } + + public Thoughtlace(final Thoughtlace card) { + super(card); + } + + @Override + public Thoughtlace copy() { + return new Thoughtlace(this); + } +} diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java b/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java index 393033b9be8..502842da895 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java @@ -106,7 +106,7 @@ class AcademyRectorEffect extends OneShotEffect { controller.searchLibrary(target, game); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - controller.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); } controller.shuffleLibrary(game); return true; diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/Gamekeeper.java b/Mage.Sets/src/mage/sets/urzasdestiny/Gamekeeper.java index 71b6e21e76b..060dd763312 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/Gamekeeper.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/Gamekeeper.java @@ -77,8 +77,6 @@ public class Gamekeeper extends CardImpl { class GamekeeperEffect extends OneShotEffect { - - public GamekeeperEffect() { super(Outcome.Benefit); staticText = "reveal cards from the top of your library until you reveal a creature card. Put that card onto the battlefield and put all other cards revealed this way into your graveyard"; @@ -98,15 +96,13 @@ class GamekeeperEffect extends OneShotEffect { while (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card.getCardType().contains(CardType.CREATURE)) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; } revealedCards.add(card); } - controller.revealCards("Gamekeeper", revealedCards, game); - for (Card card: revealedCards.getCards(game)) { - card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); - } + controller.revealCards(sourceObject.getIdName(), revealedCards, game); + controller.moveCards(revealedCards, Zone.GRAVEYARD, source, game); return true; } return false; @@ -116,4 +112,4 @@ class GamekeeperEffect extends OneShotEffect { public GamekeeperEffect copy() { return new GamekeeperEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/Replenish.java b/Mage.Sets/src/mage/sets/urzasdestiny/Replenish.java index ec46d722ec8..217f77fb07c 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/Replenish.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/Replenish.java @@ -27,17 +27,15 @@ */ package mage.sets.urzasdestiny; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; +import mage.filter.common.FilterEnchantmentCard; import mage.game.Game; import mage.players.Player; @@ -51,7 +49,6 @@ public class Replenish extends CardImpl { super(ownerId, 15, "Replenish", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{W}"); this.expansionSetCode = "UDS"; - // Return all enchantment cards from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ReplenishEffect()); } @@ -67,36 +64,27 @@ public class Replenish extends CardImpl { } class ReplenishEffect extends OneShotEffect { - + ReplenishEffect() { super(Outcome.PutCardInPlay); this.staticText = "Return all enchantment cards from your graveyard to the battlefield"; } - + ReplenishEffect(final ReplenishEffect effect) { super(effect); } - + @Override public ReplenishEffect copy() { return new ReplenishEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - List cards = new ArrayList<>(0); - for (UUID cardId : player.getGraveyard()) { - Card card = game.getCard(cardId); - if (card != null && card.getCardType().contains(CardType.ENCHANTMENT)) { - cards.add(card); - } - } - for (Card card : cards) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); - } - return true; + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + return controller.moveCards(controller.getGraveyard().getCards(new FilterEnchantmentCard(), source.getSourceId(), + source.getControllerId(), game), Zone.BATTLEFIELD, source, game); } return false; } diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/GoblinWelder.java b/Mage.Sets/src/mage/sets/urzaslegacy/GoblinWelder.java index d9ccd3e001c..a34a97f95e3 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/GoblinWelder.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/GoblinWelder.java @@ -30,7 +30,6 @@ package mage.sets.urzaslegacy; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; @@ -78,7 +77,6 @@ public class GoblinWelder extends CardImpl { public GoblinWelder copy() { return new GoblinWelder(this); } - public class GoblinWelderEffect extends OneShotEffect { @@ -87,7 +85,6 @@ public class GoblinWelder extends CardImpl { staticText = "Choose target artifact a player controls and target artifact card in that player's graveyard. If both targets are still legal as this ability resolves, that player simultaneously sacrifices the artifact and returns the artifact card to the battlefield"; } - public GoblinWelderEffect(final GoblinWelderEffect effect) { super(effect); } @@ -106,7 +103,7 @@ public class GoblinWelder extends CardImpl { && currentZone == Zone.GRAVEYARD && card.getOwnerId().equals(artifact.getControllerId())) { boolean sacrifice = artifact.sacrifice(source.getSourceId(), game); - boolean putOnBF = owner.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + boolean putOnBF = owner.moveCards(card, Zone.BATTLEFIELD, source, game); if (sacrifice || putOnBF) { return true; } @@ -121,7 +118,7 @@ public class GoblinWelder extends CardImpl { } } - + class GoblinWelderTarget extends TargetCardInGraveyard { public GoblinWelderTarget() { @@ -146,7 +143,6 @@ public class GoblinWelder extends CardImpl { } return false; } - @Override public GoblinWelderTarget copy() { diff --git a/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java b/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java index 2971de2eda7..145b521c5cb 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java +++ b/Mage.Sets/src/mage/sets/urzassaga/CopperGnomes.java @@ -94,19 +94,18 @@ class PutArtifactOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null || !player.chooseUse(Outcome.PutCardInPlay, choiceText, source, game)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || !controller.chooseUse(Outcome.PutCardInPlay, choiceText, source, game)) { return false; } TargetCardInHand target = new TargetCardInHand(new FilterArtifactCard()); - if (player.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { + if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - return true; + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfGrace.java b/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfGrace.java index b271ba24413..e34548dbd8b 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfGrace.java +++ b/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfGrace.java @@ -53,7 +53,7 @@ public class DiscipleOfGrace extends CardImpl { } public DiscipleOfGrace(UUID ownerId) { - super(ownerId, 10, "Disciple Of Grace", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + super(ownerId, 10, "Disciple of Grace", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.expansionSetCode = "USG"; this.subtype.add("Human"); this.subtype.add("Cleric"); diff --git a/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfLaw.java b/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfLaw.java index 8edffd89acc..b639fb3aaf9 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfLaw.java +++ b/Mage.Sets/src/mage/sets/urzassaga/DiscipleOfLaw.java @@ -53,7 +53,7 @@ public class DiscipleOfLaw extends CardImpl { } public DiscipleOfLaw(UUID ownerId) { - super(ownerId, 11, "Disciple Of Law", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + super(ownerId, 11, "Disciple of Law", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); this.expansionSetCode = "USG"; this.subtype.add("Human"); this.subtype.add("Cleric"); diff --git a/Mage.Sets/src/mage/sets/urzassaga/Exhume.java b/Mage.Sets/src/mage/sets/urzassaga/Exhume.java index 4b853980dd8..6350318c19f 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Exhume.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Exhume.java @@ -52,7 +52,6 @@ public class Exhume extends CardImpl { super(ownerId, 134, "Exhume", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{B}"); this.expansionSetCode = "USG"; - // Each player puts a creature card from his or her graveyard onto the battlefield. this.getSpellAbility().addEffect(new ExhumeEffect()); } @@ -90,17 +89,17 @@ class ExhumeEffect extends OneShotEffect { return false; } - for (UUID playerId : controller.getInRange()) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { FilterCreatureCard filterCreatureCard = new FilterCreatureCard("creature card from your graveyard"); filterCreatureCard.add(new OwnerIdPredicate(playerId)); TargetCardInGraveyard target = new TargetCardInGraveyard(filterCreatureCard); - if (target.canChoose(playerId, game) && - player.chooseTarget(outcome, target, source, game)) { + if (target.canChoose(playerId, game) + && player.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + player.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/urzassaga/PlanarBirth.java b/Mage.Sets/src/mage/sets/urzassaga/PlanarBirth.java index fdd6644437e..7b298acc3d7 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/PlanarBirth.java +++ b/Mage.Sets/src/mage/sets/urzassaga/PlanarBirth.java @@ -30,8 +30,9 @@ package mage.sets.urzassaga; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; @@ -65,33 +66,33 @@ public class PlanarBirth extends CardImpl { } class PlanarBirthEffect extends OneShotEffect { - + PlanarBirthEffect() { super(Outcome.PutLandInPlay); this.staticText = "Return all basic land cards from all graveyards to the battlefield tapped under their owners' control"; } - + PlanarBirthEffect(final PlanarBirthEffect effect) { super(effect); } - + @Override public PlanarBirthEffect copy() { return new PlanarBirthEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId : controller.getInRange()) { + Cards toBattlefield = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card : player.getGraveyard().getCards(new FilterBasicLandCard(), source.getSourceId(), controller.getId(), game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), true); - } + toBattlefield.addAll(player.getGraveyard().getCards(new FilterBasicLandCard(), source.getSourceId(), controller.getId(), game)); } } + controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, true, false, true, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java b/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java index 3720511de42..4cb45d7a1fc 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java +++ b/Mage.Sets/src/mage/sets/urzassaga/SneakAttack.java @@ -96,14 +96,14 @@ class SneakAttackEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - if (player.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { TargetCardInHand target = new TargetCardInHand(new FilterCreatureCard()); - if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { + if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - if (player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom); diff --git a/Mage.Sets/src/mage/sets/urzassaga/VoiceOfGrace.java b/Mage.Sets/src/mage/sets/urzassaga/VoiceOfGrace.java index fa51e7b9e59..2fa195c2d3b 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/VoiceOfGrace.java +++ b/Mage.Sets/src/mage/sets/urzassaga/VoiceOfGrace.java @@ -53,7 +53,7 @@ public class VoiceOfGrace extends CardImpl { } public VoiceOfGrace(UUID ownerId) { - super(ownerId, 54, "Voice Of Grace", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}"); + super(ownerId, 54, "Voice of Grace", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.expansionSetCode = "USG"; this.subtype.add("Angel"); diff --git a/Mage.Sets/src/mage/sets/urzassaga/VoiceOfLaw.java b/Mage.Sets/src/mage/sets/urzassaga/VoiceOfLaw.java index 898152c6247..51fcaf8fcba 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/VoiceOfLaw.java +++ b/Mage.Sets/src/mage/sets/urzassaga/VoiceOfLaw.java @@ -52,7 +52,7 @@ public class VoiceOfLaw extends CardImpl { } public VoiceOfLaw(UUID ownerId) { - super(ownerId, 55, "Voice Of Law", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}"); + super(ownerId, 55, "Voice of Law", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}"); this.expansionSetCode = "USG"; this.subtype.add("Angel"); diff --git a/Mage.Sets/src/mage/sets/vintagemasters/ChaosWarp.java b/Mage.Sets/src/mage/sets/vintagemasters/ChaosWarp.java index 96230a129e5..d4e09af0c93 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/ChaosWarp.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/ChaosWarp.java @@ -35,20 +35,20 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.players.Player; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; +import mage.filter.common.FilterPermanentCard; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.TargetPermanent; -import mage.filter.common.FilterPermanentCard; /** * * @author Mitchel Stein - * + * */ public class ChaosWarp extends CardImpl { @@ -56,14 +56,13 @@ public class ChaosWarp extends CardImpl { super(ownerId, 154, "Chaos Warp", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{2}{R}"); this.expansionSetCode = "VMA"; - // The owner of target permanent shuffles it into his or her library, this.getSpellAbility().addEffect(new ChaosWarpShuffleIntoLibraryEffect()); this.getSpellAbility().addTarget(new TargetPermanent()); - //then reveals the top card of his or her library. + //then reveals the top card of his or her library. //If it's a permanent card, he or she puts it onto the battlefield. this.getSpellAbility().addEffect(new ChaosWarpRevealEffect()); - + } public ChaosWarp(final ChaosWarp card) { @@ -94,9 +93,9 @@ class ChaosWarpShuffleIntoLibraryEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); if (permanent != null) { - Player owner = game.getPlayer(permanent.getOwnerId()); + Player owner = game.getPlayer(permanent.getOwnerId()); if (owner != null) { owner.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, true, true); owner.shuffleLibrary(game); @@ -108,10 +107,10 @@ class ChaosWarpShuffleIntoLibraryEffect extends OneShotEffect { } class ChaosWarpRevealEffect extends OneShotEffect { - -public ChaosWarpRevealEffect() { + + public ChaosWarpRevealEffect() { super(Outcome.PutCardInPlay); - this.staticText = "then reveals the top card of his or her library. If it's a permanent card, he or she puts it onto the battlefield."; + this.staticText = "then reveals the top card of his or her library. If it's a permanent card, he or she puts it onto the battlefield"; } public ChaosWarpRevealEffect(final ChaosWarpRevealEffect effect) { @@ -138,11 +137,10 @@ public ChaosWarpRevealEffect() { if (owner.getLibrary().size() > 0) { Card card = owner.getLibrary().getFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); - owner.revealCards(sourceObject.getName(), cards, game); - if (new FilterPermanentCard().match(card, game)) { - owner.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + Cards cards = new CardsImpl(card); + owner.revealCards(sourceObject.getIdName(), cards, game); + if (new FilterPermanentCard().match(card, game)) { + owner.moveCards(card, Zone.BATTLEFIELD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java b/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java index 467c548ca54..476ad0d3747 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java @@ -30,15 +30,15 @@ package mage.sets.vintagemasters; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.keyword.DethroneAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.functions.ApplyToPermanent; @@ -58,11 +58,9 @@ public class DacksDuplicate extends CardImpl { this.toughness = new MageInt(0); // You may have Dack's Duplicate enter the battlefield as a copy of any creature on the battlefield except it gains haste and dethrone. - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new DacksDuplicateApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains haste and dethrone", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new DacksDuplicateApplyToPermanent()); + effect.setText("as a copy of any creature on the battlefield except it gains haste and dethrone"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public DacksDuplicate(final DacksDuplicate card) { diff --git a/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java b/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java index c47f7887e12..d5dbfa28e5e 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/Eureka.java @@ -53,7 +53,6 @@ public class Eureka extends CardImpl { super(ownerId, 208, "Eureka", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); this.expansionSetCode = "VMA"; - // Starting with you, each player may put a permanent card from his or her hand onto the battlefield. Repeat this process until no one puts a card onto the battlefield. this.getSpellAbility().addEffect(new EurekaEffect()); } @@ -108,7 +107,7 @@ class EurekaEffect extends OneShotEffect { if (target.chooseTarget(outcome, currentPlayer.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - currentPlayer.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); + currentPlayer.moveCards(card, Zone.BATTLEFIELD, source, game); firstInactivePlayer = null; } } diff --git a/Mage.Sets/src/mage/sets/vintagemasters/MistmoonGriffin.java b/Mage.Sets/src/mage/sets/vintagemasters/MistmoonGriffin.java index d6f979dca39..290f1681191 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/MistmoonGriffin.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/MistmoonGriffin.java @@ -97,13 +97,13 @@ class MistmoonGriffinEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Card lastCreatureCard = null; - for (Card card :controller.getGraveyard().getCards(game)) { + for (Card card : controller.getGraveyard().getCards(game)) { if (card.getCardType().contains(CardType.CREATURE)) { lastCreatureCard = card; } } if (lastCreatureCard != null) { - return controller.putOntoBattlefieldWithInfo(lastCreatureCard, game, Zone.GRAVEYARD, source.getSourceId()); + return controller.moveCards(lastCreatureCard, Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/visions/Necromancy.java b/Mage.Sets/src/mage/sets/visions/Necromancy.java index f109d320e53..89910cb3ab9 100644 --- a/Mage.Sets/src/mage/sets/visions/Necromancy.java +++ b/Mage.Sets/src/mage/sets/visions/Necromancy.java @@ -196,13 +196,11 @@ class NecromancyReAttachEffect extends OneShotEffect { Permanent enchantment = game.getPermanent(source.getSourceId()); Card cardInGraveyard = game.getCard(getTargetPointer().getFirst(game, source)); if (controller != null && enchantment != null && cardInGraveyard != null) { - // put card into play - controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(cardInGraveyard, Zone.BATTLEFIELD, source, game); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); - if (enchantedCreature != null) { enchantedCreature.addAttachment(enchantment.getId(), game); - FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Necromancy"); + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with " + enchantment.getIdName()); filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); Target target = new TargetCreaturePermanent(filter); target.addTarget(enchantedCreature.getId(), source, game); diff --git a/Mage.Sets/src/mage/sets/weatherlight/BoneDancer.java b/Mage.Sets/src/mage/sets/weatherlight/BoneDancer.java index 85d29071310..45c623b43b8 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/BoneDancer.java +++ b/Mage.Sets/src/mage/sets/weatherlight/BoneDancer.java @@ -92,15 +92,15 @@ class BoneDancerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player defendingPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if(controller != null && defendingPlayer != null) { + if (controller != null && defendingPlayer != null) { Card lastCreatureCard = null; - for(Card card : defendingPlayer.getGraveyard().getCards(game)) { - if(card.getCardType().contains(CardType.CREATURE)) { + for (Card card : defendingPlayer.getGraveyard().getCards(game)) { + if (card.getCardType().contains(CardType.CREATURE)) { lastCreatureCard = card; } } - if(lastCreatureCard != null) { - return controller.putOntoBattlefieldWithInfo(lastCreatureCard, game, Zone.GRAVEYARD, source.getSourceId()); + if (lastCreatureCard != null) { + controller.moveCards(lastCreatureCard, Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java b/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java index bc0509a505a..5dbc70aa620 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java +++ b/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java @@ -28,11 +28,7 @@ package mage.sets.weatherlight; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -41,6 +37,10 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -68,7 +68,6 @@ public class CallOfTheWild extends CardImpl { } } - class CallOfTheWildEffect extends OneShotEffect { public CallOfTheWildEffect() { @@ -87,22 +86,21 @@ class CallOfTheWildEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller == null || sourceObject == null) { return false; } - if (player.getLibrary().size() > 0) { - Card card = player.getLibrary().getFromTop(game); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Call of the Wild", cards, game); - + if (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { + Cards cards = new CardsImpl(card); + controller.revealCards(sourceObject.getIdName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java index 77ae649901b..d68cd5c7eda 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java +++ b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,21 +20,19 @@ * 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.sets.worldwake; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -43,8 +41,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; -import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; @@ -56,13 +52,12 @@ import mage.target.common.TargetCreaturePermanent; */ public class JaceTheMindSculptor extends CardImpl { - public JaceTheMindSculptor(UUID ownerId) { super(ownerId, 31, "Jace, the Mind Sculptor", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{U}"); this.expansionSetCode = "WWK"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Look at the top card of target player's library. You may put that card on the bottom of that player's library. LoyaltyAbility ability1 = new LoyaltyAbility(new JaceTheMindSculptorEffect1(), 2); @@ -77,7 +72,7 @@ public class JaceTheMindSculptor extends CardImpl { LoyaltyAbility ability3 = new LoyaltyAbility(new ReturnToHandTargetEffect(), -1); ability3.addTarget(new TargetCreaturePermanent()); this.addAbility(ability3); - + // −12: Exile all cards from target player's library, then that player shuffles his or her hand into his or her library. LoyaltyAbility ability4 = new LoyaltyAbility(new JaceTheMindSculptorEffect3(), -12); ability4.addTarget(new TargetPlayer()); @@ -123,7 +118,7 @@ class JaceTheMindSculptorEffect1 extends OneShotEffect { cards.add(card); controller.lookAtCards("Jace, the Mind Sculptor", cards, game); if (controller.chooseUse(outcome, "Do you wish to put card on the bottom of player's library?", source, game)) { - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); + controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); } else { game.informPlayers(controller.getLogName() + " puts the card back on top of the library."); } diff --git a/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java b/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java index c436a967e92..75eaeeef964 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java +++ b/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java @@ -28,15 +28,12 @@ package mage.sets.worldwake; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -47,9 +44,9 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author jeffwadsworth */ public class JwariShapeshifter extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("Ally creature"); - + static { filter.add(new SubtypePredicate("Ally")); filter.add(new CardTypePredicate(CardType.CREATURE)); @@ -66,11 +63,7 @@ public class JwariShapeshifter extends CardImpl { this.toughness = new MageInt(0); // You may have Jwari Shapeshifter enter the battlefield as a copy of any Ally creature on the battlefield. - Ability ability = new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(filter), null, - "You may have {this} enter the battlefield as a copy of any Ally creature on the battlefield", true, true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public JwariShapeshifter(final JwariShapeshifter card) { diff --git a/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java b/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java index d4ae627af11..95eaa8a0b70 100644 --- a/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java +++ b/Mage.Sets/src/mage/sets/worldwake/QuestForUlasTemple.java @@ -62,7 +62,6 @@ public class QuestForUlasTemple extends CardImpl { super(ownerId, 35, "Quest for Ula's Temple", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{U}"); this.expansionSetCode = "WWK"; - // At the beginning of your upkeep, you may look at the top card of your library. If it's a creature card, you may reveal it and put a quest counter on Quest for Ula's Temple. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new QuestForUlasTempleEffect(), TargetController.YOU, true)); @@ -140,7 +139,7 @@ class QuestForUlasTempleTriggeredAbility extends TriggeredAbilityImpl { } @Override -public boolean checkTrigger(GameEvent event, Game game) { + public boolean checkTrigger(GameEvent event, Game game) { Permanent quest = game.getPermanent(super.getSourceId()); return quest != null && quest.getCounters().getCount(CounterType.QUEST) >= 3; } @@ -178,12 +177,10 @@ class QuestForUlasTempleEffect2 extends OneShotEffect { if (controller != null) { TargetCardInHand target = new TargetCardInHand(filter); if (target.canChoose(source.getSourceId(), controller.getId(), game) - &&controller.chooseUse(Outcome.PutCreatureInPlay, query, source, game)) { + && controller.chooseUse(Outcome.PutCreatureInPlay, query, source, game)) { if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - } + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return true; diff --git a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java index da7a28bd75e..d5b4caaa4a7 100644 --- a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java +++ b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,36 +20,31 @@ * 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.sets.zendikar; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.CantBeBlockedSourceAbility; +import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; - /** * @author nantuko, BetaSteward_at_googlemail.com */ public class AetherFigment extends CardImpl { - private static final String staticText = "with two +1/+1 counters on it, if it was kicked"; - public AetherFigment(UUID ownerId) { super(ownerId, 40, "AEther Figment", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.expansionSetCode = "ZEN"; @@ -65,7 +60,11 @@ public class AetherFigment extends CardImpl { this.addAbility(new KickerAbility("{3}")); // If AEther Figment was kicked, it enters the battlefield with two +1/+1 counters on it - Ability ability = new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), ""), staticText); + Ability ability = new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + KickedCondition.getInstance(), + "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it", + ""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java index a64697b5814..7caa34f04f9 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java +++ b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java @@ -32,18 +32,16 @@ import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardHandAllEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -66,7 +64,7 @@ public class ChandraAblaze extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to target creature or player. LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1); diff --git a/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java b/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java index 1a24adaacdf..2306fb65d75 100644 --- a/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java +++ b/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java @@ -28,17 +28,15 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.NamePredicate; @@ -62,11 +60,10 @@ public class NissaRevane extends CardImpl { } public NissaRevane(UUID ownerId) { - super(ownerId, 170, "Nissa Revane", Rarity.MYTHIC, new CardType[]{ CardType.PLANESWALKER }, "{2}{G}{G}"); + super(ownerId, 170, "Nissa Revane", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{G}"); this.expansionSetCode = "ZEN"; this.subtype.add("Nissa"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); LoyaltyAbility ability1 = new LoyaltyAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(1, nissasChosenFilter)), 1); this.addAbility(ability1); diff --git a/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java b/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java index 5ecb9fe0b4c..309684109aa 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java +++ b/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java @@ -27,27 +27,24 @@ */ package mage.sets.zendikar; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.turn.ControlTargetPlayerNextTurnEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author nantuko @@ -59,8 +56,7 @@ public class SorinMarkov extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +2: Sorin Markov deals 2 damage to target creature or player and you gain 2 life. LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(2), 2); diff --git a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java index e2fd1b88a42..61aa2805786 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java +++ b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java @@ -28,12 +28,6 @@ package mage.sets.zendikar; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.WatcherScope; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostImpl; import mage.abilities.costs.Cost; @@ -43,6 +37,11 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.WatcherScope; +import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.events.GameEvent; @@ -179,7 +178,7 @@ class SummoningTrapEffect extends OneShotEffect { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } if (cards.size() > 0) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java index ebea5c555aa..41fdc97851c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java @@ -9,23 +9,19 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - - public class MasterBiomancerTest extends CardTestPlayerBase { /* Master Biomancer {2}{G}{U} * Creature - Elf Wizard * 2/4 - * Each other creature you control enters the battlefield with a number of additional +1/+1 counters + * Each other creature you control enters the battlefield with a number of additional +1/+1 counters * on it equal to Master Biomancer's power and as a Mutant in addition to its other types. * */ - @Test public void testCreatureGetsCounters() { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer - addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); addCard(Zone.HAND, playerA, "Mindeye Drake"); @@ -52,12 +48,12 @@ public class MasterBiomancerTest extends CardTestPlayerBase { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer // doubled by Corpsejack Menace (when he ist cast, his own ability will not apply) // http://blogs.magicjudges.org/rulestips/2013/03/corpsejack-menace-and-master-biomancer/ - addCard(Zone.BATTLEFIELD, playerA, "Island", 2); addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); + // If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead. addCard(Zone.HAND, playerA, "Corpsejack Menace"); addCard(Zone.HAND, playerA, "Mindeye Drake"); @@ -83,30 +79,28 @@ public class MasterBiomancerTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Mindeye Drake", 6, 9); } - /** - * Progenitor Mimic - * Creature - Shapeshifter - * 0/0 - * You may have Progenitor Mimic enter the battlefield as a copy of any creature on - * the battlefield except it gains "At the beginning of your upkeep, if this creature - * isn't a token, put a token onto the battlefield that's a copy of this creature." + * Progenitor Mimic Creature - Shapeshifter 0/0 You may have Progenitor + * Mimic enter the battlefield as a copy of any creature on the battlefield + * except it gains "At the beginning of your upkeep, if this creature isn't + * a token, put a token onto the battlefield that's a copy of this + * creature." * - * If Progenitor Mimic comes into play, it gets two +1/+1 counters from - * the Master Biomancer already in play. It copies the Master Biomancer and - * is therfore a 4/6 creature. - * The Token generated next round from Progenitor Mimic has to get 2 + 4 counters - * and is therefore a 8/10 creature. + * If Progenitor Mimic comes into play, it gets two +1/+1 counters from the + * Master Biomancer already in play. It copies the Master Biomancer and is + * therfore a 4/6 creature. The Token generated next round from Progenitor + * Mimic has to get 2 + 4 counters and is therefore a 8/10 creature. */ - @Test public void testWithProgenitorMimic() { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer - addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); + // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield + // except it gains "At the beginning of your upkeep, if this creature isn't a token, + // put a token onto the battlefield that's a copy of this creature." addCard(Zone.HAND, playerA, "Progenitor Mimic"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Progenitor Mimic"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CyclingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CyclingTest.java index e50598c40b4..472fada8fb9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CyclingTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CyclingTest.java @@ -96,7 +96,7 @@ public class CyclingTest extends CardTestPlayerBase { addCard(Zone.GRAVEYARD, playerA, "Decree of Pain"); // Protection from black // Cycling {2} ({2}, Discard this card: Draw a card.) - addCard(Zone.BATTLEFIELD, playerB, "Disciple Of Grace"); + addCard(Zone.BATTLEFIELD, playerB, "Disciple of Grace"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cycling {3}{B}{B}"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cycling {2}"); @@ -108,7 +108,7 @@ public class CyclingTest extends CardTestPlayerBase { assertHandCount(playerB, 0); assertGraveyardCount(playerA, "Decree of Pain", 1); - assertPermanentCount(playerB, "Disciple Of Grace", 1); + assertPermanentCount(playerB, "Disciple of Grace", 1); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java index e8fcc2a4487..85a451e4298 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/PersistTest.java @@ -195,8 +195,7 @@ public class PersistTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Glen Elendra Archmage", 1); assertPowerToughness(playerB, "Glen Elendra Archmage", 1, 1); - assertPermanentCount(playerA, "Glen Elendra Archmage", 1); - assertPowerToughness(playerA, "Glen Elendra Archmage", 1, 1); + assertGraveyardCount(playerA, "Clever Impersonator", 1); } @Test diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java index 98e3294b084..9ed98cca08f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java @@ -49,6 +49,8 @@ public class SuspendTest extends CardTestPlayerBase { public void testEpochrasite() { addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // Epochrasite enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand. + // When Epochrasite dies, exile it with three time counters on it and it gains suspend. addCard(Zone.HAND, playerA, "Epochrasite", 1); addCard(Zone.HAND, playerB, "Lightning Bolt", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java index 31fc57868bf..058b5e5bed1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/UndyingTest.java @@ -2,6 +2,7 @@ package org.mage.test.cards.abilities.keywords; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.counters.CounterType; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -238,7 +239,8 @@ public class UndyingTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Tatterkite", 1); assertPermanentCount(playerA, "Mikaeus, the Unhallowed", 1); - assertPowerToughness(playerA, "Tatterkite", 3, 2); + assertCounterCount("Tatterkite", CounterType.P1P1, 1); + assertPowerToughness(playerA, "Tatterkite", 4, 3); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExileAndReturnUnderYourControl.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExileAndReturnUnderYourControl.java index 5f1c950fb75..13f434621e6 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/control/ExileAndReturnUnderYourControl.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/ExileAndReturnUnderYourControl.java @@ -7,11 +7,12 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * Tests the effect: - * - Exile target creature you control, then return that card to the battlefield under your control + * Tests the effect: - Exile target creature you control, then return that card + * to the battlefield under your control * - * This effect grants you permanent control over the returned creature. - * So you mail steal opponent's creature with "Act of Treason" and then use this effect for permanent control effect. + * This effect grants you permanent control over the returned creature. So you + * mail steal opponent's creature with "Act of Treason" and then use this effect + * for permanent control effect. * * @author noxx */ @@ -67,7 +68,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase { Assert.assertTrue("player A should play with top card revealed", playerA.isTopCardRevealed()); Assert.assertFalse("player B should play NOT with top card revealed", playerB.isTopCardRevealed()); } - + @Test public void testVillainousWealthExilesBoost() { // Villainous Wealth {X}{B}{G}{U} @@ -76,14 +77,14 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase { // their mana costs. addCard(Zone.HAND, playerA, "Villainous Wealth"); addCard(Zone.HAND, playerA, "Master of Pearls"); - + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); addCard(Zone.BATTLEFIELD, playerA, "Island", 4); // Secret Plans {G}{U} // Face-down creatures you control get +0/+1. - // Whenever a permanent you control is turned face up, draw a card. + // Whenever a permanent you control is turned face up, draw a card. addCard(Zone.LIBRARY, playerB, "Secret Plans"); skipInitShuffling(); // to keep this card on top of library @@ -101,9 +102,50 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase { assertExileCount(playerB, 2); assertExileCount("Secret Plans", 0); assertPermanentCount(playerA, "Secret Plans", 1); - + assertPermanentCount(playerA, "", 1); - assertPowerToughness(playerA, "", 2, 3); - } + assertPowerToughness(playerA, "", 2, 3); + } + + /** + * My opponent cast Villainous Wealth and took control of my Sylvan Library. + * On his next turn, when Sylvan Library's trigger resolved, he kept the two + * extra cards without paying life. + */ + @Test + public void testVillainousWealthExilesSylvanLibrary() { + // Villainous Wealth {X}{B}{G}{U} + // Target opponent exiles the top X cards of his or her library. You may cast any number + // of nonland cards with converted mana cost X or less from among them without paying + // their mana costs. + addCard(Zone.HAND, playerA, "Villainous Wealth"); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + + // At the beginning of your draw step, you may draw two additional cards. + // If you do, choose two cards in your hand drawn this turn. + // For each of those cards, pay 4 life or put the card on top of your library. + addCard(Zone.LIBRARY, playerB, "Sylvan Library"); + skipInitShuffling(); // to keep this card on top of library + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Villainous Wealth", playerB); + setChoice(playerA, "X=3"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sylvan Library"); + + setStopAt(3, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertGraveyardCount(playerA, "Villainous Wealth", 1); + assertExileCount(playerB, 2); + assertExileCount("Sylvan Library", 0); + assertPermanentCount(playerA, "Sylvan Library", 1); + + assertHandCount(playerB, 1); + assertHandCount(playerA, 3); + assertLife(playerA, 12); + assertLife(playerB, 20); + + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java index ff78a4dcf31..6567fa4edd3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java @@ -157,7 +157,7 @@ public class KikiJikiMirrorBreakerTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Island", 5); addCard(Zone.BATTLEFIELD, playerB, "Kiki-Jiki, Mirror Breaker", 1); - // {T}: Draw two cards. Target opponent gains control of Humble Defector. Activate this ability only during your turn. + // You may have Body Double enter the battlefield as a copy of any creature card in a graveyard. addCard(Zone.HAND, playerB, "Body Double", 1); // {4}{U} castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Body Double"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java index 48fc3962b1f..fe600b1e415 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java @@ -92,7 +92,6 @@ public class VesuvaTest extends CardTestPlayerBase { execute(); assertPermanentCount(playerB, "Dark Depths", 1); - assertPermanentCount(playerA, "Vesuva", 0); assertPermanentCount(playerA, "Dark Depths", 1); Permanent darkDepth = getPermanent("Dark Depths", playerA); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/OathOfLiegesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/OathOfLiegesTest.java index 2ad4dc07a44..df0c508f1e2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/OathOfLiegesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/enchantments/OathOfLiegesTest.java @@ -78,6 +78,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase { execute(); assertPermanentCount(playerA, "Oath of Lieges", 1); + assertPermanentCount(playerA, "Plains", 2); assertPermanentCount(playerB, "Plains", 2); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java index 6c1e294d57c..082e3440095 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java @@ -6,22 +6,30 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * Pillar of Flame: - * Pillar of Flame deals 2 damage to target creature or player. If a creature dealt damage this way would die this turn, exile it instead. + * Pillar of Flame: Pillar of Flame deals 2 damage to target creature or player. + * If a creature dealt damage this way would die this turn, exile it instead. * * @author LevelX2 */ public class PillarOfFlameTest extends CardTestPlayerBase { /** - * Tests when cast Pillar of Flame targeting opponent there is no influence on dying creature of opponent + * Tests when cast Pillar of Flame targeting opponent there is no influence + * on dying creature of opponent */ @Test public void testNotTriggeringExileItInstead() { - addCard(Zone.BATTLEFIELD, playerA, "Lightning Mauler"); - addCard(Zone.BATTLEFIELD, playerA, "Rakdos Cackler"); + // Soulbond + // As long as Lightning Mauler is paired with another creature, both creatures have haste. + addCard(Zone.BATTLEFIELD, playerA, "Lightning Mauler"); // 2/1 + // Unleash (You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it.) + addCard(Zone.BATTLEFIELD, playerA, "Rakdos Cackler"); // 1/1 + // Pillar of Flame deals 2 damage to target creature or player. + // If a creature dealt damage this way would die this turn, exile it instead. addCard(Zone.HAND, playerA, "Pillar of Flame"); + // Soulbond + // As long as Stonewright is paired with another creature, each of those creatures has "{R}: This creature gets +1/+0 until end of turn." addCard(Zone.HAND, playerA, "Stonewright"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); @@ -49,7 +57,8 @@ public class PillarOfFlameTest extends CardTestPlayerBase { } /** - * Tests when cast Pillar of Flame targeting creature it goes to exile if dying later + * Tests when cast Pillar of Flame targeting creature it goes to exile if + * dying later */ @Test public void testTriggeringExileItInstead() { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java index 441d68754b9..c8694f3540b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java @@ -6,8 +6,8 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * Torpor Orb: - * Creatures entering the battlefield don't cause abilities to trigger. + * Torpor Orb: Creatures entering the battlefield don't cause abilities to + * trigger. * * @author noxx */ @@ -15,7 +15,10 @@ public class TorporOrbTest extends CardTestPlayerBase { @Test public void testWallOfOmens() { + // Creatures entering the battlefield don't cause abilities to trigger. addCard(Zone.BATTLEFIELD, playerA, "Torpor Orb"); + // Defender + // When Wall of Omens enters the battlefield, draw a card. addCard(Zone.HAND, playerA, "Wall of Omens"); addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); @@ -33,7 +36,8 @@ public class TorporOrbTest extends CardTestPlayerBase { } /** - * Treacherous Pit-Dweller doesnt function properly with Torpor Orb and Hushwing Gryff + * Treacherous Pit-Dweller doesnt function properly with Torpor Orb and + * Hushwing Gryff */ @Test public void testPitTweller() { @@ -42,8 +46,8 @@ public class TorporOrbTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); - - attack(2, playerB, "Treacherous Pit-Dweller"); + + attack(2, playerB, "Treacherous Pit-Dweller"); castSpell(2, PhaseStep.DECLARE_ATTACKERS, playerA, "Lightning Bolt", "Treacherous Pit-Dweller"); setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); @@ -53,9 +57,9 @@ public class TorporOrbTest extends CardTestPlayerBase { assertLife(playerB, 20); assertGraveyardCount(playerA, "Lightning Bolt", 1); - + assertPermanentCount(playerB, "Treacherous Pit-Dweller", 1); - assertPowerToughness(playerB, "Treacherous Pit-Dweller", 5,4); + assertPowerToughness(playerB, "Treacherous Pit-Dweller", 5, 4); } - + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/avr/CavernOfSoulsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/avr/CavernOfSoulsTest.java index eb69c8b1c41..5062c9244ab 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/avr/CavernOfSoulsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/avr/CavernOfSoulsTest.java @@ -33,8 +33,9 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { } /** - * Tests "Cavern of Souls" with "Human" creature type chosen. - * Then tests casting Azure Drake (should fail) and Elite Vanguard (should be ok as it has "Human" subtype) + * Tests "Cavern of Souls" with "Human" creature type chosen. Then tests + * casting Azure Drake (should fail) and Elite Vanguard (should be ok as it + * has "Human" subtype) */ @Test public void testNoCastBecauseOfCreatureType() { @@ -87,6 +88,9 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { @Test public void testDrakeCantBeCountered() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + // As Cavern of Souls enters the battlefield, choose a creature type. + // {T}: Add {1} to your mana pool. + // {T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered. addCard(Zone.HAND, playerA, "Cavern of Souls"); addCard(Zone.HAND, playerA, "Azure Drake"); @@ -108,6 +112,7 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Azure Drake", 0); assertPermanentCount(playerA, "Azure Drake", 1); } + /** * Tests spell can be countered if cast with colorless mana from Cavern */ @@ -136,59 +141,59 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Azure Drake", 1); assertPermanentCount(playerA, "Azure Drake", 0); } - + /** - * Tests conditional mana from Cavern in pool will still work if Cavern got back to hand and is played again with other creature type + * Tests conditional mana from Cavern in pool will still work if Cavern got + * back to hand and is played again with other creature type */ @Test public void testConditionlManaWorksIfCavernIsReplayed() { addCard(Zone.HAND, playerA, "Cavern of Souls"); addCard(Zone.HAND, playerA, "Gladecover Scout"); // Elf costing {G} // addCard(Zone.HAND, playerA, "Fume Spitter"); // Horror costing {B} - + // Instant - {U}{U} - Return target permanent to its owner's hand. addCard(Zone.HAND, playerB, "Boomerang"); addCard(Zone.BATTLEFIELD, playerB, "Island", 2); playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cavern of Souls"); setChoice(playerA, "Elf"); - + // getting green mana for Elf into pool activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add 1 mana of any one color to your mana pool. Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered."); - setChoice(playerA, "Green"); - + setChoice(playerA, "Green"); + // return cavern to hand castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerB, "Boomerang", "Cavern of Souls"); - + // playing the cavern again choose different creature type playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cavern of Souls"); setChoice(playerA, "Horror"); - // the green mana usable for Elf should be in the mana pool + // the green mana usable for Elf should be in the mana pool castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Gladecover Scout"); activateManaAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add 1 mana of any one color to your mana pool. Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered."); - setChoice(playerA, "Black"); + setChoice(playerA, "Black"); - // the black mana usable for Horror should be in the mana pool + // the black mana usable for Horror should be in the mana pool // castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Fume Spitter"); - setStopAt(3, PhaseStep.BEGIN_COMBAT); execute(); - assertGraveyardCount(playerB, "Boomerang", 1); assertPermanentCount(playerA, "Cavern of Souls", 1); - + // Check the elf was cast assertPermanentCount(playerA, "Gladecover Scout", 1); // Check Horror on the Battlefield // assertPermanentCount(playerA, "Fume Spitter", 1); - } + } /** - * Return to the Ranks cannot be countered if mana produced by Cavern of Souls - * was used to pay X. Can be bug also for all other spells with X in their cost, not sure. + * Return to the Ranks cannot be countered if mana produced by Cavern of + * Souls was used to pay X. Can be bug also for all other spells with X in + * their cost, not sure. * */ @Test @@ -205,12 +210,11 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { addCard(Zone.HAND, playerB, "Counterspell"); addCard(Zone.BATTLEFIELD, playerB, "Island", 2); - playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cavern of Souls"); setChoice(playerA, "Drake"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Return to the Ranks", "Silvercoat Lion"); setChoice(playerA, "X=1"); - + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Return to the Ranks"); setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -223,11 +227,12 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Silvercoat Lion", 0); } - + /** - * Cavern of Souls can produce any colour of mana with its second ability when Contamination is in play. + * Cavern of Souls can produce any colour of mana with its second ability + * when Contamination is in play. */ - @Test + @Test public void testUseWithConversionInPlay() { addCard(Zone.BATTLEFIELD, playerA, "Plains", 3); addCard(Zone.HAND, playerA, "Cavern of Souls"); @@ -235,8 +240,6 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Desert Drake"); addCard(Zone.BATTLEFIELD, playerB, "Contamination", 1); - - playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cavern of Souls"); setChoice(playerA, "Drake"); @@ -249,5 +252,5 @@ public class CavernOfSoulsTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Desert Drake", 0); } - + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java index 5d8f468f12c..145785ccc8b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java @@ -2,6 +2,8 @@ package org.mage.test.cards.triggers; import mage.constants.PhaseStep; import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -13,14 +15,16 @@ public class FathomMageTest extends CardTestPlayerBase { /** * Fathom Mage - Creature — Human Wizard 1/1, 2UG * - * Evolve (Whenever a creature enters the battlefield under your control, if that creature has greater power or toughness than this creature, put a +1/+1 counter on this creature.) - * Whenever a +1/+1 counter is placed on Fathom Mage, you may draw a card. + * Evolve (Whenever a creature enters the battlefield under your control, if + * that creature has greater power or toughness than this creature, put a + * +1/+1 counter on this creature.) Whenever a +1/+1 counter is placed on + * Fathom Mage, you may draw a card. + * * - */ @Test public void testDrawCardsAddedCounters() { - // card draw triggered ability will trigger once for each of those counters from Blessings of Nature. + // card draw triggered ability will trigger once for each of those counters from Blessings of Nature. addCard(Zone.HAND, playerA, "Blessings of Nature"); addCard(Zone.BATTLEFIELD, playerA, "Fathom Mage", 1); @@ -38,20 +42,26 @@ public class FathomMageTest extends CardTestPlayerBase { @Test public void testDrawCardsEntersTheBattlefield() { - // card draw triggered ability will trigger once for each of those counters from Master Biomancer. + // card draw triggered ability will trigger once for each of those counters from Master Biomancer. addCard(Zone.HAND, playerA, "Fathom Mage"); + // Each other creature you control enters the battlefield with a number of additional +1/+1 counters on it equal to + // Master Biomancer's power and as a Mutant in addition to its other types. addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); - addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); - addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fathom Mage"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fathom Mage"); // {2}{G}{U} setStopAt(1, PhaseStep.END_TURN); execute(); assertPermanentCount(playerA, "Fathom Mage", 1); assertPowerToughness(playerA, "Fathom Mage", 3, 3); + + Permanent fathomMage = getPermanent("Fathom Mage", playerA); + Assert.assertEquals("Fathom Mage has to be a Mutant", true, fathomMage.getSubtype().contains("Mutant")); + assertHandCount(playerA, 2); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/WorldgorgerDragonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/WorldgorgerDragonTest.java index db1557a3bd4..f21dade9e3c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/WorldgorgerDragonTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/WorldgorgerDragonTest.java @@ -5,7 +5,6 @@ */ package org.mage.test.cards.triggers; - import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Assert; @@ -16,7 +15,6 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - public class WorldgorgerDragonTest extends CardTestPlayerBase { /** @@ -25,20 +23,23 @@ public class WorldgorgerDragonTest extends CardTestPlayerBase { @Test public void testDisabledEffectOnChangeZone() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6); + // Flying + // Trample + // When Worldgorger Dragon enters the battlefield, exile all other permanents you control. + // When Worldgorger Dragon leaves the battlefield, return the exiled cards to the battlefield under their owners' control. addCard(Zone.HAND, playerA, "Worldgorger Dragon"); - + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Gerrard's Battle Cry", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2); // Destroy target nonartifact, nonblack creature. It can't be regenerated. addCard(Zone.HAND, playerB, "Terror", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Worldgorger Dragon"); - + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Terror", "Worldgorger Dragon"); - + setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); @@ -47,30 +48,35 @@ public class WorldgorgerDragonTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Worldgorger Dragon", 1); assertGraveyardCount(playerB, "Terror", 1); - + assertPermanentCount(playerA, "Silvercoat Lion", 1); assertPermanentCount(playerA, "Gerrard's Battle Cry", 1); - + } - /** - 1. Cast Animate Dead, targeting the Dragon - 2. Dragon comes into play, it's ability goes on the stack. - 3. The ability resolves, and all my other permanents leave play - 4. Since Animate Dead left play, Dragon goes to the graveyard - 5. Since the Dragon left play, the land and Animate Dead return to play. Animate Dead triggers, targeting the Dragon. - 6. In response to Animate Dead's ability going on the stack, tap the lands for mana. - 7. Animate Dead resolves, Dragon comes into play, everything else leaves play. - 8. Steps 4-7 repeat endlessly. Your mana pool fills. - 9. You can interrupt the sequence to play an instant. + /* + * 1. Cast Animate Dead, targeting the Dragon + * 2. Dragon comes into play, it's ability goes on the stack. + * 3. The ability resolves, and all my other permanents leave play + * 4. Since Animate Dead left play, Dragon goes to the graveyard + * 5. Since the Dragon left play, the land and Animate Dead return to play. Animate Dead triggers, targeting the Dragon. + * 6. In response to Animate Dead's ability going on the stack, tap the lands for mana. + * 7. Animate Dead resolves, Dragon comes into play, everything else leaves play. + * 8. Steps 4-7 repeat endlessly. Your mana pool fills. + * 9. You can interrupt the sequence to play an instant. */ @Test public void testWithAnimateDead() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); - + // When Worldgorger Dragon enters the battlefield, exile all other permanents you control. // When Worldgorger Dragon leaves the battlefield, return the exiled cards to the battlefield under their owners' control. addCard(Zone.GRAVEYARD, playerA, "Worldgorger Dragon", 1); + // Enchant creature card in a graveyard + // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" + // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield + // under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. + // Enchanted creature gets -1/-0. addCard(Zone.HAND, playerA, "Animate Dead"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); // Instant {X}{R}{R} @@ -78,10 +84,9 @@ public class WorldgorgerDragonTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Volcanic Geyser", 1); // When Staunch Defenders enters the battlefield, you gain 4 life. addCard(Zone.BATTLEFIELD, playerA, "Staunch Defenders", 1); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Animate Dead", "Worldgorger Dragon"); - + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); @@ -107,43 +112,44 @@ public class WorldgorgerDragonTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volcanic Geyser", playerB, 22); setChoice(playerA, "X=20"); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); - assertLife(playerA, 20); + assertLife(playerA, 44); assertLife(playerB, 0); assertGraveyardCount(playerA, "Volcanic Geyser", 1); - + } - + /** - * v9: Worldgorger Dragon + Animate Dead is still acting up (yey complex rules interactions!). - * The first time you return Animate Dead from Worldgorger's exile, it works like it's supposed - * to. You have to pick a creature, and it brings it back. But if you pick Worldgorger Dragon - * again, it allows you to not pick a creature, and regardless of whether you choose to skip or pick - * a different creature, it always returns the first creature you picked. Kind of hard to explain, - * but here's how to reproduce: - * - * 1) Cast Animate Dead, targeting Worldgorger Dragon - * 2) Worldgorger Dragon will exile Animate Dead, killing the dragon and returning the permanents - * 3) Select Worldgorger again - * 4) Step 2 repeats - * 5) Attempt to select a different creature. Worldgorger Dragon is returned instead. - * + * v9: Worldgorger Dragon + Animate Dead is still acting up (yey complex + * rules interactions!). The first time you return Animate Dead from + * Worldgorger's exile, it works like it's supposed to. You have to pick a + * creature, and it brings it back. But if you pick Worldgorger Dragon + * again, it allows you to not pick a creature, and regardless of whether + * you choose to skip or pick a different creature, it always returns the + * first creature you picked. Kind of hard to explain, but here's how to + * reproduce: + * + * 1) Cast Animate Dead, targeting Worldgorger Dragon 2) Worldgorger Dragon + * will exile Animate Dead, killing the dragon and returning the permanents + * 3) Select Worldgorger again 4) Step 2 repeats 5) Attempt to select a + * different creature. Worldgorger Dragon is returned instead. + * */ @Test public void testWithAnimateDeadDifferentTargets() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); - + // When Worldgorger Dragon enters the battlefield, exile all other permanents you control. // When Worldgorger Dragon leaves the battlefield, return the exiled cards to the battlefield under their owners' control. addCard(Zone.GRAVEYARD, playerA, "Worldgorger Dragon", 1); addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 1); - // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" - // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield + // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" + // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield // under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. addCard(Zone.HAND, playerA, "Animate Dead"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); @@ -152,43 +158,42 @@ public class WorldgorgerDragonTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Volcanic Geyser", 1); // When Staunch Defenders enters the battlefield, you gain 4 life. addCard(Zone.BATTLEFIELD, playerA, "Staunch Defenders", 1); - + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Animate Dead", "Worldgorger Dragon"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); setChoice(playerA, "Worldgorger Dragon"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); setChoice(playerA, "Silvercoat Lion"); - activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volcanic Geyser", playerB, 9); + activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volcanic Geyser", playerB, 9); setChoice(playerA, "X=9"); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); assertGraveyardCount(playerA, "Volcanic Geyser", 1); - assertGraveyardCount(playerA, "Worldgorger Dragon", 1); + assertGraveyardCount(playerA, "Worldgorger Dragon", 1); assertPermanentCount(playerA, "Silvercoat Lion", 1); - + assertLife(playerA, 28); assertLife(playerB, 11); Assert.assertEquals("Mana pool", "[]", playerA.getManaAvailable(currentGame).toString()); - } - -} \ No newline at end of file + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 5d0df67f11a..2f80da8fa0d 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1799,21 +1799,6 @@ public class TestPlayer implements Player { return computerPlayer.moveCardToExileWithInfo(card, exileId, exileName, sourceId, game, fromZone, withName); } - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) { - return computerPlayer.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId); - } - - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) { - return computerPlayer.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped); - } - - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) { - return computerPlayer.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, facedown); - } - @Override public boolean hasOpponent(UUID playerToCheckId, Game game) { return computerPlayer.hasOpponent(playerToCheckId, game); @@ -1970,11 +1955,26 @@ public class TestPlayer implements Player { return computerPlayer.scry(value, source, game); } + @Override + public boolean moveCards(Card card, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(card, toZone, source, game); + } + @Override public boolean moveCards(Card card, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } + @Override + public boolean moveCards(Cards cards, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(cards, toZone, source, game); + } + + @Override + public boolean moveCards(Set cards, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(cards, toZone, source, game); + } + @Override public boolean moveCards(Set cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 77d726faea7..8611baa943c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -533,10 +533,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement if (flag) { Assert.assertTrue("No such ability=" + ability.toString() + ", player=" + player.getName() - + ", cardName" + cardName, found.getAbilities().containsRule(ability)); + + ", cardName" + cardName, found.getAbilities(currentGame).containsRule(ability)); } else { Assert.assertFalse("Card shouldn't have such ability=" + ability.toString() + ", player=" + player.getName() - + ", cardName" + cardName, found.getAbilities().containsRule(ability)); + + ", cardName" + cardName, found.getAbilities(currentGame).containsRule(ability)); } } @@ -574,7 +574,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } } } - Assert.assertEquals("(Battlefield) Card counts for " + player.getName() + " are not equal (" + cardName + ")", count, actualCount); + Assert.assertEquals("(Battlefield) Permanents counts for " + player.getName() + " are not equal (" + cardName + ")", count, actualCount); } @Override diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 821abd34d61..d7b581515ba 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -952,7 +952,10 @@ public abstract class AbilityImpl implements Ability { // for singleton abilities like Flying we can't rely on abilities' source because it's only once in continuous effects // so will use the sourceId of the object itself that came as a parameter if it is not null if (object == null) { - object = game.getObject(getSourceId()); + object = game.getPermanentEntering(getSourceId()); + if (object == null) { + object = game.getObject(getSourceId()); + } } if (object != null && !object.getAbilities().contains(this)) { if (object instanceof Permanent) { diff --git a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java index 70113a4564a..963df6092bc 100644 --- a/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesAttachedTriggeredAbility.java @@ -60,6 +60,7 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl { // So check here with the LKI of the enchantment Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId()); if (attachment != null + && zEvent.getTargetId() != null && attachment.getAttachedTo() != null && zEvent.getTargetId().equals(attachment.getAttachedTo()) && attachment.getAttachedToZoneChangeCounter() == zEvent.getTarget().getZoneChangeCounter(game) - 1) { triggered = true; diff --git a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java index aac46fbe9d8..0efbd80e31e 100644 --- a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java @@ -71,7 +71,7 @@ public class DiesTriggeredAbility extends ZoneChangeTriggeredAbility { if (super.checkEventType(event, game)) { return ((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD) && ((ZoneChangeEvent) event).getToZone().equals(Zone.GRAVEYARD); } - return event.getType() == GameEvent.EventType.ZONE_CHANGE; + return false; } @Override diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java index 64bd2c40fe5..40231800591 100644 --- a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java @@ -40,44 +40,50 @@ import mage.constants.Zone; public class EntersBattlefieldAbility extends StaticAbility { protected String abilityRule; + protected boolean optional; public EntersBattlefieldAbility(Effect effect) { - this(effect, true); + this(effect, false); } /** * * @param effect effect that happens when the permanent enters the - * battlefield - * @param showRule show the rule for this ability + * battlefiely + * @param optional */ - public EntersBattlefieldAbility(Effect effect, Boolean showRule) { - this(effect, null, showRule, null, null); + public EntersBattlefieldAbility(Effect effect, boolean optional) { + this(effect, optional, null, null, null); } public EntersBattlefieldAbility(Effect effect, String effectText) { - this(effect, null, true, null, effectText); + this(effect, null, null, effectText); + } + + public EntersBattlefieldAbility(Effect effect, Condition condition, String abilityRule, String effectText) { + this(effect, false, condition, abilityRule, effectText); } /** * * @param effect effect that happens when the permanent enters the * battlefield + * @param optional * @param condition only if this condition is true, the effect will happen - * @param ruleVisible show the rule for this ability * @param abilityRule rule for this ability (no text from effects will be * added) * @param effectText this text will be used for the EnterBattlefieldEffect */ - public EntersBattlefieldAbility(Effect effect, Condition condition, Boolean ruleVisible, String abilityRule, String effectText) { - super(Zone.ALL, new EntersBattlefieldEffect(effect, condition, effectText)); - this.setRuleVisible(ruleVisible); + public EntersBattlefieldAbility(Effect effect, boolean optional, Condition condition, String abilityRule, String effectText) { + super(Zone.ALL, new EntersBattlefieldEffect(effect, condition, effectText, true, optional)); this.abilityRule = abilityRule; + this.optional = optional; } public EntersBattlefieldAbility(final EntersBattlefieldAbility ability) { super(ability); this.abilityRule = ability.abilityRule; + this.optional = ability.optional; } @Override @@ -99,12 +105,9 @@ public class EntersBattlefieldAbility extends StaticAbility { @Override public String getRule() { - if (!ruleVisible) { - return ""; - } if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return "{this} enters the battlefield " + super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield " + super.getRule(); } } diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldTappedAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldTappedAbility.java index 1d8d119f17c..f62f02ab29e 100644 --- a/Mage/src/mage/abilities/common/EntersBattlefieldTappedAbility.java +++ b/Mage/src/mage/abilities/common/EntersBattlefieldTappedAbility.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,18 +20,17 @@ * 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.abilities.common; -import mage.constants.Zone; import mage.abilities.StaticAbility; import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.common.TapSourceEffect; +import mage.constants.Zone; /** * @@ -40,9 +39,9 @@ import mage.abilities.effects.common.TapSourceEffect; public class EntersBattlefieldTappedAbility extends StaticAbility { private String ruleText; - + public EntersBattlefieldTappedAbility() { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new TapSourceEffect(true))); + super(Zone.ALL, new EntersBattlefieldEffect(new TapSourceEffect(true))); } public EntersBattlefieldTappedAbility(String ruleText) { diff --git a/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java b/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java new file mode 100644 index 00000000000..aad230eaf2d --- /dev/null +++ b/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java @@ -0,0 +1,30 @@ +/* + * 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.abilities.common; + +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.counters.CounterType; + +/** + * + * @author LevelX2 + */ +public class PlanswalkerEntersWithLoyalityCountersAbility extends EntersBattlefieldAbility { + + public PlanswalkerEntersWithLoyalityCountersAbility(int loyality) { + super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyality))); + setRuleVisible(false); + } + + public PlanswalkerEntersWithLoyalityCountersAbility(final PlanswalkerEntersWithLoyalityCountersAbility ability) { + super(ability); + } + + @Override + public EntersBattlefieldAbility copy() { + return new PlanswalkerEntersWithLoyalityCountersAbility(this); + } +} diff --git a/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java index 27811130bdc..1abc7306f5f 100644 --- a/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java +++ b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java @@ -12,10 +12,14 @@ import mage.watchers.Watcher; * @author Loki */ public class CastFromHandCondition implements Condition { + @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + permanent = game.getPermanentEntering(source.getSourceId()); + } + if (permanent != null) { Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId()); if (watcher != null && watcher.conditionMet()) { return true; @@ -29,5 +33,4 @@ public class CastFromHandCondition implements Condition { return "you cast it from your hand"; } - } diff --git a/Mage/src/mage/abilities/condition/common/MorbidCondition.java b/Mage/src/mage/abilities/condition/common/MorbidCondition.java index 04de2a9aec9..22a4bc7a74c 100644 --- a/Mage/src/mage/abilities/condition/common/MorbidCondition.java +++ b/Mage/src/mage/abilities/condition/common/MorbidCondition.java @@ -49,4 +49,9 @@ public class MorbidCondition implements Condition { return watcher.conditionMet(); } + @Override + public String toString() { + return "if a creature died this turn"; + } + } diff --git a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java index 03a0be13f47..b69b73b278c 100644 --- a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java +++ b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java @@ -125,8 +125,6 @@ public class AlternativeCost2Impl> extends Cos activated = true; } - ; - /** * Reset the activate and count information * diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index c5b4661816b..2f35dbd4901 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -879,7 +879,7 @@ public class ContinuousEffects implements Serializable { // For example: Vesuva copying a Dark Depth (VesuvaTest:testDarkDepth) // This call should be removed if possible as replacement effects of EntersTheBattlefield events // do no longer work correctly because the entering permanents are not yet on the battlefield (before they were). - game.applyEffects(); + // game.applyEffects(); } while (true); return caught; } diff --git a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java index ef6bb795d16..052d4ee5d4b 100644 --- a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java @@ -34,7 +34,6 @@ import mage.abilities.condition.Condition; import mage.constants.Duration; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; @@ -52,7 +51,6 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { protected Condition condition; protected boolean optional; - public static final String ENTERING_PERMANENT = "enteringPermanent"; public static final String SOURCE_CAST_SPELL_ABILITY = "sourceCastSpellAbility"; public EntersBattlefieldEffect(Effect baseEffect) { @@ -67,10 +65,6 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { this(baseEffect, null, text, true, optional); } - public EntersBattlefieldEffect(Effect baseEffect, Condition condition, String text) { - this(baseEffect, condition, text, true, false); - } - public EntersBattlefieldEffect(Effect baseEffect, Condition condition, String text, boolean selfScope, boolean optional) { super(Duration.WhileOnBattlefield, baseEffect.getOutcome(), selfScope); this.baseEffects.add(baseEffect); @@ -126,18 +120,16 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { } } for (Effect effect : baseEffects) { - if (source.activate(game, false)) { - if (effect instanceof ContinuousEffect) { - game.addEffect((ContinuousEffect) effect, source); - } else { - if (spell != null) { - effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); - } - // Because the permanent is not on the battlefield yet, it has to be taken from the event - effect.setValue(ENTERING_PERMANENT, ((EntersTheBattlefieldEvent) event).getTarget()); - effect.apply(game, source); + // if (source.activate(game, false)) { // Why is this needed???? + if (effect instanceof ContinuousEffect) { + game.addEffect((ContinuousEffect) effect, source); + } else { + if (spell != null) { + effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); } + effect.apply(game, source); } + // } } return false; } diff --git a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java index 4a87a976677..722fc0468d9 100644 --- a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java +++ b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.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 java.util.ArrayList; @@ -62,17 +61,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { this.amount = amount; this.staticText = setText(); } - + public AddManaInAnyCombinationEffect(int amount, String text) { this(amount); this.staticText = text; } - + public AddManaInAnyCombinationEffect(int amount, String text, ColoredManaSymbol... coloredManaSymbols) { this(amount, coloredManaSymbols); this.staticText = text; } - + public AddManaInAnyCombinationEffect(DynamicValue amount, String text, ColoredManaSymbol... coloredManaSymbols) { this(amount, coloredManaSymbols); this.staticText = text; @@ -92,13 +91,13 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null){ + if (player != null) { Mana mana = new Mana(); int amountOfManaLeft = amount.calculate(game, source, this); while (amountOfManaLeft > 0 && player.canRespond()) { - for (ColoredManaSymbol coloredManaSymbol: manaSymbols) { - int number = player.getAmount(0, amountOfManaLeft, new StringBuilder("How many ").append(coloredManaSymbol.name()).append(" mana?").toString(), game); + for (ColoredManaSymbol coloredManaSymbol : manaSymbols) { + int number = player.getAmount(0, amountOfManaLeft, "How many " + coloredManaSymbol.getColorName() + " mana?", game); if (number > 0) { for (int i = 0; i < number; i++) { mana.add(new Mana(coloredManaSymbol)); @@ -111,7 +110,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { } } checkToFirePossibleEvents(mana, game, source); - player.getManaPool().addMana(mana, game, source); + player.getManaPool().addMana(mana, game, source); return true; } return false; @@ -130,7 +129,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { sb.append("colors"); } else { int i = 0; - for (ColoredManaSymbol coloredManaSymbol: manaSymbols) { + for (ColoredManaSymbol coloredManaSymbol : manaSymbols) { i++; if (i > 1) { sb.append(" and/or "); diff --git a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java index a06e008ad7a..b05ddd626c1 100644 --- a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java +++ b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java @@ -19,6 +19,7 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -27,15 +28,13 @@ import mage.target.common.TargetCardInHand; /** * Effect for the AmplifyAbility * - * 702.37. Amplify - * 702.37a Amplify is a static ability. “Amplify N” means “As - * this object enters the battlefield, reveal any number of cards from your hand - * that share a creature type with it. This permanent enters the battlefield - * with N +1/+1 counters on it for each card revealed this way. You can’t reveal - * this card or any other cards that are entering the battlefield at the same - * time as this card.” - * 702.37b If a creature has multiple instances of amplify, - * each one works separately. + * 702.37. Amplify 702.37a Amplify is a static ability. “Amplify N” means “As + * this object enters the battlefield, reveal any number of cards from your hand + * that share a creature type with it. This permanent enters the battlefield + * with N +1/+1 counters on it for each card revealed this way. You can’t reveal + * this card or any other cards that are entering the battlefield at the same + * time as this card.” 702.37b If a creature has multiple instances of amplify, + * each one works separately. * * * @author FenrisulfrX @@ -45,6 +44,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { private final AmplifyFactor amplifyFactor; public enum AmplifyFactor { + Amplify1("Amplify 1", "put one +1/+1 counters on it", 1), Amplify2("Amplify 2", "put two +1/+1 counters on it", 2), Amplify3("Amplify 3", "put three +1/+1 counters on it", 3); @@ -95,7 +95,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent sourceCreature = game.getPermanent(event.getTargetId()); + Permanent sourceCreature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && sourceCreature != null) { FilterCreatureCard filter = new FilterCreatureCard("creatures cards to reveal"); @@ -108,7 +108,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { } else if (filterSubtypes.size() == 1) { filter.add(filterSubtypes.get(0)); } - if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0){ + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { if (controller.chooseUse(outcome, "Reveal cards to Amplify?", source, game)) { TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { @@ -116,7 +116,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { cards.addAll(target.getTargets()); int amountCounters = cards.size() * amplifyFactor.getFactor(); sourceCreature.addCounters(CounterType.P1P1.createInstance(amountCounters), game); - controller.revealCards(sourceCreature.getName(), cards, game); + controller.revealCards(sourceCreature.getIdName(), cards, game); } } } @@ -128,11 +128,11 @@ public class AmplifyEffect extends ReplacementEffectImpl { public String getText(Mode mode) { StringBuilder sb = new StringBuilder(amplifyFactor.toString()); sb.append("(As this enter the battlefield, "); - sb.append(amplifyFactor.getRuleText()).append(" for each card" + - " you reveal that shares a type with it in your hand.)"); + sb.append(amplifyFactor.getRuleText()).append(" for each card" + + " you reveal that shares a type with it in your hand.)"); return sb.toString(); } - + @Override public AmplifyEffect copy() { return new AmplifyEffect(this); diff --git a/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java new file mode 100644 index 00000000000..5d73e8dd40e --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java @@ -0,0 +1,67 @@ +/* + * 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.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.choices.ChoiceImpl; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class ChooseBasicLandTypeEffect extends OneShotEffect { + + public static String VALUE_KEY = "BasicLandType"; + + public ChooseBasicLandTypeEffect(Outcome outcome) { + super(outcome); + this.staticText = "Choose a basic land type"; + } + + public ChooseBasicLandTypeEffect(final ChooseBasicLandTypeEffect effect) { + super(effect); + } + + @Override + public ChooseBasicLandTypeEffect copy() { + return new ChooseBasicLandTypeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { + ChoiceImpl choices = new ChoiceImpl(true); + choices.setMessage("Choose basic land type"); + choices.isRequired(); + choices.getChoices().add("Forest"); + choices.getChoices().add("Plains"); + choices.getChoices().add("Mountain"); + choices.getChoices().add("Island"); + choices.getChoices().add("Swamp"); + if (controller.choose(Outcome.Neutral, choices, game)) { + game.informPlayers(mageObject.getName() + ": Chosen basic land type is " + choices.getChoice()); + game.getState().setValue(mageObject.getId().toString() + VALUE_KEY, choices.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen basic land type: " + choices.getChoice()), game); + } + return true; + } + } + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java index 43836dd2f74..161dec6767e 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java @@ -27,8 +27,8 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.choices.ChoiceColor; import mage.constants.Outcome; @@ -55,11 +55,11 @@ public class ChooseColorEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); } - if (controller != null && permanent != null) { + if (controller != null && mageObject != null) { ChoiceColor choice = new ChoiceColor(); while (!choice.isChosen()) { controller.choose(outcome, choice, game); @@ -68,10 +68,12 @@ public class ChooseColorEffect extends OneShotEffect { } } if (!game.isSimulation()) { - game.informPlayers(permanent.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice()); + game.informPlayers(mageObject.getLogName() + ": " + controller.getLogName() + " has chosen " + choice.getChoice()); + } + game.getState().setValue(mageObject.getId() + "_color", choice.getColor()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game); } - game.getState().setValue(source.getSourceId() + "_color", choice.getColor()); - permanent.addInfo("chosen color", CardUtil.addToolTipMarkTags("Chosen color: " + choice.getChoice()), game); return true; } return false; diff --git a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java index 2ebd99cc9d2..b1d4b0e6f62 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.repository.CardRepository; @@ -42,7 +43,6 @@ import mage.util.CardUtil; * * @author LevelX2 */ - public class ChooseCreatureTypeEffect extends OneShotEffect { public ChooseCreatureTypeEffect(Outcome outcome) { @@ -57,8 +57,11 @@ public class ChooseCreatureTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (controller != null && permanent != null) { + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose creature type"); typeChoice.setChoices(CardRepository.instance.getCreatureTypes()); @@ -68,10 +71,12 @@ public class ChooseCreatureTypeEffect extends OneShotEffect { } } if (!game.isSimulation()) { - game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice()); + game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice()); + } + game.getState().setValue(mageObject.getId() + "_type", typeChoice.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } return false; } diff --git a/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java index 0480effa493..bd59c25c334 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java @@ -5,6 +5,7 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.repository.CardRepository; @@ -34,8 +35,11 @@ public class ChooseLandTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (controller != null && permanent != null) { + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { Choice typeChoice = new ChoiceImpl(true); typeChoice.setMessage("Choose land type"); typeChoice.setChoices(CardRepository.instance.getLandTypes()); @@ -45,10 +49,12 @@ public class ChooseLandTypeEffect extends OneShotEffect { } } if (!game.isSimulation()) { - game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice()); + game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + typeChoice.getChoice()); + } + game.getState().setValue(mageObject.getId() + "_type", typeChoice.getChoice()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } - game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice()); - permanent.addInfo("chosen type", CardUtil.addToolTipMarkTags("Chosen type: " + typeChoice.getChoice()), game); } return false; } diff --git a/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java b/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java index 265b66e9cdd..35ac9818cd5 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseNewTargetsTargetEffect.java @@ -1,38 +1,36 @@ /* -* 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. -*/ - + * 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.abilities.effects.common; -import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; -import mage.filter.Filter; +import mage.constants.Outcome; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.stack.StackObject; @@ -46,21 +44,22 @@ public class ChooseNewTargetsTargetEffect extends OneShotEffect { private boolean forceChange; private boolean onlyOneTarget; private FilterPermanent filterNewTarget; - + public ChooseNewTargetsTargetEffect() { this(false, false); } + public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget) { this(forceChange, onlyOneTarget, null); } /** * - * @param forceChange forces the user to choose another target (only targets with maxtargets = 1 supported) + * @param forceChange forces the user to choose another target (only targets + * with maxtargets = 1 supported) * @param onlyOneTarget only one target can be selected for the change * @param filterNewTarget restriction to the new target */ - public ChooseNewTargetsTargetEffect(boolean forceChange, boolean onlyOneTarget, FilterPermanent filterNewTarget) { super(Outcome.Benefit); this.forceChange = forceChange; diff --git a/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java b/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java new file mode 100644 index 00000000000..bdb32a34a13 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java @@ -0,0 +1,63 @@ +/* + * 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.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class ChooseOpponentEffect extends OneShotEffect { + + public static String VALUE_KEY = "_opponent"; + + public ChooseOpponentEffect(Outcome outcome) { + super(outcome); + this.staticText = "choose an opponent"; + } + + public ChooseOpponentEffect(final ChooseOpponentEffect effect) { + super(effect); + } + + @Override + public ChooseOpponentEffect copy() { + return new ChooseOpponentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { + TargetOpponent target = new TargetOpponent(true); + if (controller.choose(this.outcome, target, source.getSourceId(), game)) { + Player chosenPlayer = game.getPlayer(target.getFirstTarget()); + if (chosenPlayer != null) { + game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + chosenPlayer.getLogName()); + game.getState().setValue(mageObject.getId() + VALUE_KEY, target.getFirstTarget()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen opponent", CardUtil.addToolTipMarkTags("Chosen player: " + chosenPlayer.getLogName()), game); + } + return true; + } + } + } + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java b/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java new file mode 100644 index 00000000000..7f8ce4c72cc --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java @@ -0,0 +1,61 @@ +/* + * 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.abilities.effects.common; + +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class ChoosePlayerEffect extends OneShotEffect { + + public ChoosePlayerEffect(Outcome outcome) { + super(outcome); + this.staticText = "choose a player"; + } + + public ChoosePlayerEffect(final ChoosePlayerEffect effect) { + super(effect); + } + + @Override + public ChoosePlayerEffect copy() { + return new ChoosePlayerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); + if (mageObject == null) { + mageObject = game.getObject(source.getSourceId()); + } + if (controller != null && mageObject != null) { + TargetPlayer target = new TargetPlayer(1, 1, true); + if (controller.choose(this.outcome, target, source.getSourceId(), game)) { + Player chosenPlayer = game.getPlayer(target.getFirstTarget()); + if (chosenPlayer != null) { + game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has chosen " + chosenPlayer.getLogName()); + game.getState().setValue(mageObject.getId() + "_player", target.getFirstTarget()); + if (mageObject instanceof Permanent) { + ((Permanent) mageObject).addInfo("chosen player", CardUtil.addToolTipMarkTags("Chosen player: " + chosenPlayer.getLogName()), game); + } + return true; + } + } + } + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/CopyEffect.java b/Mage/src/mage/abilities/effects/common/CopyEffect.java index 86bc3f060fb..9b6becb7198 100644 --- a/Mage/src/mage/abilities/effects/common/CopyEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyEffect.java @@ -33,6 +33,7 @@ import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.Card; +import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -54,10 +55,10 @@ public class CopyEffect extends ContinuousEffectImpl { /** * Object we copy from */ - private MageObject copyFromObject; + protected MageObject copyFromObject; - private UUID copyToObjectId; - private ApplyToPermanent applier; + protected UUID copyToObjectId; + protected ApplyToPermanent applier; public CopyEffect(MageObject copyFromObject, UUID copyToObjectId) { this(Duration.Custom, copyFromObject, copyToObjectId); @@ -82,14 +83,23 @@ public class CopyEffect extends ContinuousEffectImpl { if (!(copyFromObject instanceof Permanent) && (copyFromObject instanceof Card)) { this.copyFromObject = new PermanentCard((Card) copyFromObject, source.getControllerId(), game); } - + Permanent permanent = game.getPermanent(copyToObjectId); + if (permanent != null) { + affectedObjectList.add(new MageObjectReference(permanent, game)); + } else if (source.getAbilityType().equals(AbilityType.STATIC)) { + // for replacement effects that let a permanent enter the battlefield as a copy of another permanent we need to apply that copy + // before the permanent is added to the battlefield + permanent = game.getPermanentEntering(copyToObjectId); + if (permanent != null) { + copyToPermanent(permanent, game, source); + // set reference to the permanent later on the battlefield so we have to add already one to the zone change counter + affectedObjectList.add(new MageObjectReference(permanent.getId(), game.getState().getZoneChangeCounter(copyToObjectId) + 1, game)); + } + } } @Override public boolean apply(Game game, Ability source) { - if (affectedObjectList.isEmpty()) { - affectedObjectList.add(new MageObjectReference(getSourceId(), game)); - } Permanent permanent = affectedObjectList.get(0).getPermanent(game); if (permanent == null) { permanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, source.getSourceObjectZoneChangeCounter()); @@ -99,6 +109,10 @@ public class CopyEffect extends ContinuousEffectImpl { return false; } } + return copyToPermanent(permanent, game, source); + } + + protected boolean copyToPermanent(Permanent permanent, Game game, Ability source) { permanent.setCopy(true); permanent.setName(copyFromObject.getName()); permanent.getColor(game).setColor(copyFromObject.getColor(game)); diff --git a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java index f6318632ac6..865adb292e8 100644 --- a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java @@ -73,7 +73,7 @@ public class CopyPermanentEffect extends OneShotEffect { this.applier = applier; this.filter = filter; this.useTargetOfAbility = useTarget; - this.staticText = "You may have {this} enter the battlefield as a copy of any " + filter.getMessage() + " on the battlefield"; + this.staticText = "as a copy of any " + filter.getMessage() + " on the battlefield"; } public CopyPermanentEffect(final CopyPermanentEffect effect) { @@ -87,7 +87,10 @@ public class CopyPermanentEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); + MageObject sourceObject = game.getPermanentEntering(source.getSourceId()); + if (sourceObject == null) { + sourceObject = game.getObject(source.getSourceId()); + } if (player != null && sourceObject != null) { Permanent copyFromPermanent = null; if (useTargetOfAbility) { @@ -95,7 +98,7 @@ public class CopyPermanentEffect extends OneShotEffect { } else { Target target = new TargetPermanent(filter); target.setNotTarget(true); - if (target.canChoose(source.getControllerId(), game)) { + if (target.canChoose(source.getSourceId(), player.getId(), game)) { player.choose(Outcome.Copy, target, source.getSourceId(), game); copyFromPermanent = game.getPermanent(target.getFirstTarget()); } diff --git a/Mage/src/mage/abilities/effects/common/DevourEffect.java b/Mage/src/mage/abilities/effects/common/DevourEffect.java index 1d02ab1733d..18432616aa8 100644 --- a/Mage/src/mage/abilities/effects/common/DevourEffect.java +++ b/Mage/src/mage/abilities/effects/common/DevourEffect.java @@ -39,6 +39,7 @@ import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -47,30 +48,32 @@ import mage.target.common.TargetControlledCreaturePermanent; /** * Effect for the DevourAbility - * - * 702.81. Devour - * 702.81a Devour is a static ability. "Devour N" means "As this object enters the battlefield, - * you may sacrifice any number of creatures. This permanent enters the battlefield with N +1/+1 - * counters on it for each creature sacrificed this way." - * 702.81b Some objects have abilities that refer to the number of creatures the permanent devoured. - * "It devoured" means "sacrificed as a result of its devour ability as it entered the battlefield." * - * + * 702.81. Devour 702.81a Devour is a static ability. "Devour N" means "As this + * object enters the battlefield, you may sacrifice any number of creatures. + * This permanent enters the battlefield with N +1/+1 counters on it for each + * creature sacrificed this way." 702.81b Some objects have abilities that refer + * to the number of creatures the permanent devoured. "It devoured" means + * "sacrificed as a result of its devour ability as it entered the battlefield." + * + * * @author LevelX2 */ public class DevourEffect extends ReplacementEffectImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures to devour"); + static { filter.add(new AnotherPredicate()); } private final DevourFactor devourFactor; public enum DevourFactor { - Devour1 ("Devour 1", "that many +1/+1 counters on it", 1), - Devour2 ("Devour 2", "twice that many +1/+1 counters on it", 2), - Devour3 ("Devour 3", "three times that many +1/+1 counters on it", 3), - DevourX ("Devour X, where X is the number of creatures devoured this way", "X +1/+1 counters on it for each of those creatures", Integer.MAX_VALUE); + + Devour1("Devour 1", "that many +1/+1 counters on it", 1), + Devour2("Devour 2", "twice that many +1/+1 counters on it", 2), + Devour3("Devour 3", "three times that many +1/+1 counters on it", 3), + DevourX("Devour X, where X is the number of creatures devoured this way", "X +1/+1 counters on it for each of those creatures", Integer.MAX_VALUE); private final String text; private final String ruleText; @@ -114,9 +117,9 @@ public class DevourEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - game.getState().setValue(sourcePermanent.getId().toString() + "devoured", null); - return true; + Permanent sourcePermanent = ((EntersTheBattlefieldEvent) event).getTarget(); + game.getState().setValue(sourcePermanent.getId().toString() + "devoured", null); + return true; } return false; } @@ -128,7 +131,7 @@ public class DevourEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledCreaturePermanent(1, Integer.MAX_VALUE, filter, true); @@ -141,9 +144,10 @@ public class DevourEffect extends ReplacementEffectImpl { if (target.getTargets().size() > 0) { List> cardSubtypes = new ArrayList<>(); int devouredCreatures = target.getTargets().size(); - if (!game.isSimulation()) - game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString()); - for (UUID targetId: target.getTargets()) { + if (!game.isSimulation()) { + game.informPlayers(creature.getLogName() + " devours " + devouredCreatures + " creatures"); + } + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature != null) { cardSubtypes.add((ArrayList) targetCreature.getSubtype()); @@ -172,7 +176,7 @@ public class DevourEffect extends ReplacementEffectImpl { StringBuilder sb = new StringBuilder(devourFactor.toString()); sb.append(" (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with "); sb.append(devourFactor.getRuleText()).append(")"); - return sb.toString(); + return sb.toString(); } public List> getSubtypes(Game game, UUID permanentId) { diff --git a/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java index 137b33c5145..1a82af11cdf 100644 --- a/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java @@ -34,8 +34,8 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.stack.StackObject; import mage.players.Player; @@ -85,7 +85,7 @@ public class DiscardOntoBattlefieldEffect extends ReplacementEffectImpl { if (card != null) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { - if (owner.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (owner.moveCards(card, Zone.BATTLEFIELD, source, game)) { return true; } } diff --git a/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java b/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java index 999e70423dc..9c704852225 100644 --- a/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java +++ b/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.counters.Counter; import mage.game.Game; @@ -59,11 +60,16 @@ public class EntersBattlefieldWithXCountersEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); + } + } if (permanent != null) { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { if (spellAbility.getSourceId().equals(source.getSourceId())) { // put into play by normal cast int amount = spellAbility.getManaCostsToPay().getX(); if (amount > 0) { diff --git a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java index 6e99909a49e..72874fb2fd0 100644 --- a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java @@ -66,7 +66,7 @@ public class ExileAndReturnTransformedSourceEffect extends OneShotEffect { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); - owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + owner.moveCards(card, Zone.BATTLEFIELD, source, game); if (additionalEffect != null) { if (additionalEffect instanceof ContinuousEffect) { game.addEffect((ContinuousEffect) additionalEffect, source); diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index 89b065c0306..529760e039b 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -29,7 +29,6 @@ */ package mage.abilities.effects.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.dynamicvalue.DynamicValue; @@ -128,28 +127,13 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff if (!optional || player.chooseUse(Outcome.DrawCard, getMayText(), source, game)) { FilterCard pickFilter = filter.copy(); pickFilter.setMessage(getPickText()); - TargetCard target = new TargetCard((upTo ? 0 : numberToPick.calculate(game, source, this)), numberToPick.calculate(game, source, this), Zone.PICK, pickFilter); + TargetCard target = new TargetCard((upTo ? 0 : numberToPick.calculate(game, source, this)), numberToPick.calculate(game, source, this), Zone.LIBRARY, pickFilter); if (player.choose(Outcome.DrawCard, cards, target, game)) { - Cards reveal = new CardsImpl(); - for (UUID cardId : target.getTargets()) { - Card card = cards.get(cardId, game); - if (card != null) { - cards.remove(card); - if (targetZoneLookedCards.equals(Zone.BATTLEFIELD)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } else { - card.moveToZone(targetPickedCards, source.getSourceId(), game, false); - if (!game.isSimulation()) { - game.informPlayers(player.getLogName() + " moves a card to " + targetPickedCards.toString().toLowerCase()); - } - } - if (revealPickedCards) { - reveal.add(card); - } - } - } + Cards pickedCards = new CardsImpl(target.getTargets()); + cards.removeAll(pickedCards); + player.moveCards(pickedCards.getCards(game), targetPickedCards, source, game); if (revealPickedCards) { - player.revealCards(windowName, reveal, game); + player.revealCards(windowName, pickedCards, game); } } diff --git a/Mage/src/mage/abilities/effects/common/NameACardEffect.java b/Mage/src/mage/abilities/effects/common/NameACardEffect.java index 0123f9fd6f6..1a642fac0f0 100644 --- a/Mage/src/mage/abilities/effects/common/NameACardEffect.java +++ b/Mage/src/mage/abilities/effects/common/NameACardEffect.java @@ -71,7 +71,10 @@ public class NameACardEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); + MageObject sourceObject = game.getPermanentEntering(source.getSourceId()); + if (sourceObject == null) { + game.getObject(source.getSourceId()); + } if (controller != null && sourceObject != null) { Choice cardChoice = new ChoiceImpl(); switch (typeOfName) { diff --git a/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java index 8d819291cc3..c08da1ba5b3 100644 --- a/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutLandFromHandOntoBattlefieldEffect.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.abilities.Ability; @@ -50,10 +49,11 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect { public PutLandFromHandOntoBattlefieldEffect() { this(false); } + public PutLandFromHandOntoBattlefieldEffect(boolean tapped) { super(Outcome.PutLandInPlay); this.tapped = tapped; - staticText = "you may put a land card from your hand onto the battlefield" + (tapped ? " tapped":""); + staticText = "you may put a land card from your hand onto the battlefield" + (tapped ? " tapped" : ""); } public PutLandFromHandOntoBattlefieldEffect(final PutLandFromHandOntoBattlefieldEffect effect) { @@ -66,12 +66,12 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { Target target = new TargetCardInHand(new FilterLandCard("land card")); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game) && - controller.chooseUse(outcome, "Put land onto battlefield?", source, game) && - controller.choose(outcome, target, source.getSourceId(), game)) { + if (target.canChoose(source.getSourceId(), source.getControllerId(), game) + && controller.chooseUse(outcome, "Put land onto battlefield?", source, game) + && controller.choose(outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId(), tapped); + controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null); } } return true; @@ -85,4 +85,4 @@ public class PutLandFromHandOntoBattlefieldEffect extends OneShotEffect { return new PutLandFromHandOntoBattlefieldEffect(this); } - } +} diff --git a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java index 12a208ab190..f559340ecce 100644 --- a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java @@ -48,10 +48,9 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player; - if(useTargetController) { + if (useTargetController) { player = game.getPlayer(getTargetPointer().getFirst(game, source)); - } - else { + } else { player = game.getPlayer(source.getControllerId()); } String choiceText = "Put " + filter.getMessage() + " from your hand onto the battlefield?"; @@ -63,23 +62,21 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - return true; + return player.moveCards(card, Zone.BATTLEFIELD, source, game); } } - return false; + return true; } @Override public String getText(Mode mode) { - if(this.staticText != null && !this.staticText.isEmpty()) { + if (this.staticText != null && !this.staticText.isEmpty()) { return staticText; } - if(useTargetController) { + if (useTargetController) { return "that player may put " + filter.getMessage() + " from his or her hand onto the battlefield"; - } - else { + } else { return "you may put " + filter.getMessage() + " from your hand onto the battlefield"; } } diff --git a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java index a87f0360ff8..a1c3ebe28ab 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,19 +20,18 @@ * 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.abilities.effects.common; -import mage.constants.Outcome; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -54,6 +53,7 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect this.tapped = tapped; setText(); } + public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped, boolean ownerControl) { super(Outcome.PutCreatureInPlay); this.tapped = tapped; @@ -76,32 +76,31 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect public boolean apply(Game game, Ability source) { if (!game.getState().getZone(source.getSourceId()).equals(Zone.GRAVEYARD)) { return false; - } + } Card card = game.getCard(source.getSourceId()); if (card == null) { return false; } - - Player player; + + Player player; if (ownerControl) { player = game.getPlayer(card.getOwnerId()); } else { player = game.getPlayer(source.getControllerId()); - } - if (player == null) { + } + if (player == null) { return false; - } - - return player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId(), tapped); + } + return player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, true, null); } private void setText() { StringBuilder sb = new StringBuilder("return {this} from your graveyard to the battlefield"); if (tapped) { sb.append(" tapped"); - } + } if (ownerControl) { - sb.append(" under its owner's control"); + sb.append(" under its owner's control"); } staticText = sb.toString(); } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java index d386e7d944f..650e1c32cbe 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java @@ -88,8 +88,7 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe card = game.getCard(getTargetPointer().getFirst(game, source)); } if (card != null) { - Zone currentZone = game.getState().getZone(card.getId()); - controller.putOntoBattlefieldWithInfo(card, game, currentZone, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage/src/mage/abilities/effects/common/TapSourceEffect.java b/Mage/src/mage/abilities/effects/common/TapSourceEffect.java index fcbc92c1e4c..e510ae4844c 100644 --- a/Mage/src/mage/abilities/effects/common/TapSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapSourceEffect.java @@ -1,36 +1,35 @@ /* -* 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. -*/ - + * 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.abilities.effects.common; -import mage.constants.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -39,6 +38,7 @@ import mage.game.permanent.Permanent; * @author BetaSteward_at_googlemail.com */ public class TapSourceEffect extends OneShotEffect { + private boolean withoutTrigger; public TapSourceEffect() { @@ -64,6 +64,9 @@ public class TapSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + permanent = game.getPermanentEntering(source.getSourceId()); + } if (permanent != null) { if (withoutTrigger) { permanent.setTapped(true); diff --git a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java index 55bc3ad99ed..15fbc93dbff 100644 --- a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,17 +20,17 @@ * 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.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -59,7 +59,10 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); - if (player != null && permanent != null) { + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); + } + if (player != null && permanent != null) { if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) && player.chooseUse(Outcome.Benefit, cost.getText() + "? (otherwise " + permanent.getName() + " becomes tapped)", source, game)) { cost.clearPaid(); @@ -78,5 +81,4 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect { return new TapSourceUnlessPaysEffect(this); } - } diff --git a/Mage/src/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java b/Mage/src/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java index 475a7f8d6b6..e4ed2543d96 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/AddCardSubTypeTargetEffect.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.continuous; import mage.abilities.Ability; @@ -42,7 +41,7 @@ import mage.game.permanent.Permanent; * @author nantuko */ public class AddCardSubTypeTargetEffect extends ContinuousEffectImpl { - + private final String addedSubType; public AddCardSubTypeTargetEffect(String addedSubType, Duration duration) { diff --git a/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java index 81fc17c970c..609ad65d290 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,7 +20,7 @@ * 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. @@ -88,12 +88,17 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou public GainAbilitySourceEffect copy() { return new GainAbilitySourceEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); if (affectedObjectsSet) { - affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent != null) { + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()) + 1, game)); + } else { + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game)); + } } } diff --git a/Mage/src/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java index add455f4b14..d523a5cbd06 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/SetPowerToughnessSourceEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,12 +20,11 @@ * 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.abilities.effects.common.continuous; import mage.MageObject; @@ -76,7 +75,10 @@ public class SetPowerToughnessSourceEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - MageObject mageObject = game.getObject(source.getSourceId()); + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject == null) { + game.getPermanentEntering(source.getSourceId()); + } if (mageObject == null) { if (duration.equals(Duration.Custom)) { discard(); diff --git a/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 0633ff60c63..a39c2b7de8b 100644 --- a/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -30,9 +30,9 @@ package mage.abilities.effects.common.counter; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.counters.Counter; import mage.game.Game; @@ -115,8 +115,8 @@ public class AddCountersSourceEffect extends OneShotEffect { } } else { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); } if (permanent != null) { if (counter != null) { diff --git a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java index 6776adcc8ea..c92cbb7540e 100644 --- a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java +++ b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayEffect.java @@ -1,38 +1,37 @@ /* -* 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. -*/ - + * 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.abilities.effects.common.search; import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.SearchEffect; -import mage.cards.Card; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -90,12 +89,8 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { } if (player.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - for (UUID cardId: target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), tapped); - } - } + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), + Zone.BATTLEFIELD, source, game, true, false, false, null); } player.shuffleLibrary(game); return true; @@ -110,15 +105,13 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { StringBuilder sb = new StringBuilder(); sb.append("search your library for "); if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) { - if ( target.getMaxNumberOfTargets() == Integer.MAX_VALUE ) { + if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) { sb.append("any number of ").append(" "); - } - else { + } else { sb.append("up to ").append(target.getMaxNumberOfTargets()).append(" "); } sb.append(target.getTargetName()).append(" and put them onto the battlefield"); - } - else { + } else { sb.append("a ").append(target.getTargetName()).append(" and put it onto the battlefield"); } if (tapped) { @@ -126,8 +119,7 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { } if (forceShuffle) { sb.append(". Then shuffle your library"); - } - else { + } else { sb.append(". If you do, shuffle your library"); } staticText = sb.toString(); diff --git a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayTargetPlayerEffect.java index 74cf05fbe9f..8c68601cb38 100644 --- a/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayTargetPlayerEffect.java +++ b/Mage/src/mage/abilities/effects/common/search/SearchLibraryPutInPlayTargetPlayerEffect.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.SearchEffect; -import mage.cards.Card; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -20,11 +20,11 @@ import mage.target.common.TargetCardInLibrary; * * @author LevelX2 */ - public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { protected boolean tapped; protected boolean forceShuffle; + protected boolean ownerIsController; public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target) { this(target, false, true, Outcome.PutCardInPlay); @@ -43,9 +43,14 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { } public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target, boolean tapped, boolean forceShuffle, Outcome outcome) { + this(target, tapped, forceShuffle, outcome, false); + } + + public SearchLibraryPutInPlayTargetPlayerEffect(TargetCardInLibrary target, boolean tapped, boolean forceShuffle, Outcome outcome, boolean ownerIsController) { super(target, outcome); this.tapped = tapped; this.forceShuffle = forceShuffle; + this.ownerIsController = ownerIsController; setText(); } @@ -53,6 +58,7 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { super(effect); this.tapped = effect.tapped; this.forceShuffle = effect.forceShuffle; + this.ownerIsController = effect.ownerIsController; } @Override @@ -62,26 +68,22 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null) { if (player.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - for (UUID cardId: target.getTargets()) { - Card card = player.getLibrary().getCard(cardId, game); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId(), tapped); - } - } + player.moveCards(new CardsImpl(target.getTargets()).getCards(game), + Zone.BATTLEFIELD, source, game, tapped, false, ownerIsController, null); } player.shuffleLibrary(game); return true; } - + if (forceShuffle) { player.shuffleLibrary(game); } } - + return false; } @@ -89,15 +91,13 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { StringBuilder sb = new StringBuilder(); sb.append("target player searches his or her library for "); if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) { - if ( target.getMaxNumberOfTargets() == Integer.MAX_VALUE ) { + if (target.getMaxNumberOfTargets() == Integer.MAX_VALUE) { sb.append("any number of ").append(" "); - } - else { + } else { sb.append("up to ").append(target.getMaxNumberOfTargets()).append(" "); } sb.append(target.getTargetName()).append(" and put them onto the battlefield"); - } - else { + } else { sb.append("a ").append(target.getTargetName()).append(" and put it onto the battlefield"); } if (tapped) { @@ -105,8 +105,7 @@ public class SearchLibraryPutInPlayTargetPlayerEffect extends SearchEffect { } if (forceShuffle) { sb.append(". Then that player shuffles his or her library"); - } - else { + } else { sb.append(". If that player does, he or she shuffles his or her library"); } staticText = sb.toString(); diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java index 71e6293628d..0640fc8ed85 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java @@ -86,13 +86,15 @@ public class ManifestEffect extends OneShotEffect { } MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); + + } + controller.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null); + for (Card card : cards) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.setManifested(true); } } - game.applyEffects(); // to apply before ETB triggered or replace Effects are executed return true; } return false; diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java index 897ff83f235..2e904878769 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java @@ -89,7 +89,9 @@ public class ManifestTargetPlayerEffect extends OneShotEffect { } MageObjectReference objectReference = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game) + 1, game); game.addEffect(new BecomesFaceDownCreatureEffect(manaCosts, objectReference, Duration.Custom, FaceDownType.MANIFESTED), newSource); - targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, newSource.getSourceId(), false, true); + } + targetPlayer.moveCards(cards, Zone.BATTLEFIELD, source, game, false, true, false, null); + for (Card card : cards) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.setManifested(true); diff --git a/Mage/src/mage/abilities/keyword/AmplifyAbility.java b/Mage/src/mage/abilities/keyword/AmplifyAbility.java index 22a427c8402..a9cc43d60fc 100644 --- a/Mage/src/mage/abilities/keyword/AmplifyAbility.java +++ b/Mage/src/mage/abilities/keyword/AmplifyAbility.java @@ -39,13 +39,13 @@ import mage.constants.Zone; public class AmplifyAbility extends SimpleStaticAbility { public AmplifyAbility(AmplifyFactor amplifyFactor) { - super(Zone.BATTLEFIELD, new AmplifyEffect(amplifyFactor)); + super(Zone.ALL, new AmplifyEffect(amplifyFactor)); } - + public AmplifyAbility(final AmplifyAbility ability) { super(ability); } - + @Override public AmplifyAbility copy() { return new AmplifyAbility(this); diff --git a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java index ea4ddd1a6aa..385703b6691 100644 --- a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java +++ b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java @@ -104,9 +104,9 @@ class AuraSwapEffect extends OneShotEffect { if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { - controller.putOntoBattlefieldWithInfo(auraInHand, game, Zone.HAND, source.getSourceId()); + controller.moveCards(auraInHand, Zone.BATTLEFIELD, source, game); enchantedPermanent.addAttachment(auraInHand.getId(), game); - controller.moveCards(auraPermanent, null, Zone.HAND, source, game); + controller.moveCards(auraPermanent, Zone.HAND, source, game); return true; } } diff --git a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java index f93ca9824d6..0b8f4d29c61 100644 --- a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java +++ b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java @@ -12,10 +12,11 @@ import mage.util.CardUtil; import mage.watchers.common.BloodthirstWatcher; /** - * + * * @author Loki */ public class BloodthirstAbility extends EntersBattlefieldAbility { + private int amount; public BloodthirstAbility(int amount) { @@ -48,12 +49,13 @@ public class BloodthirstAbility extends EntersBattlefieldAbility { } class BloodthirstEffect extends OneShotEffect { + private final int amount; BloodthirstEffect(int amount) { super(Outcome.BoostCreature); this.amount = amount; - staticText = new StringBuilder("this permanent comes into play with ").append(this.amount).append(" +1/+1 counters on it").toString(); + staticText = "this permanent comes into play with " + this.amount + " +1/+1 counters on it"; } BloodthirstEffect(final BloodthirstEffect effect) { @@ -67,10 +69,9 @@ class BloodthirstEffect extends OneShotEffect { if (player != null) { BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get("DamagedOpponents", source.getControllerId()); if (watcher != null && watcher.conditionMet()) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { - p.addCounters(CounterType.P1P1.createInstance(amount), game); - + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(amount), game); } } return true; @@ -83,4 +84,3 @@ class BloodthirstEffect extends OneShotEffect { return new BloodthirstEffect(this); } } - diff --git a/Mage/src/mage/abilities/keyword/DashAbility.java b/Mage/src/mage/abilities/keyword/DashAbility.java index 4a2d96170f0..b6a876053b0 100644 --- a/Mage/src/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/mage/abilities/keyword/DashAbility.java @@ -76,10 +76,10 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts this.addDashCost(manaString); Ability ability = new EntersBattlefieldAbility( new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), - DashedCondition.getInstance(), false, "", ""); + DashedCondition.getInstance(), "", ""); ability.addEffect(new DashAddDelayedTriggeredAbilityEffect()); addSubAbility(ability); - + } public DashAbility(final DashAbility ability) { @@ -226,16 +226,18 @@ class DashAddDelayedTriggeredAbilityEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Effect effect = new ReturnToHandTargetEffect(); - effect.setText("return the dashed creature from the battlefield to its owner's hand"); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); - // init target pointer now because the dashed creature will only be returned from current zone - effect.getTargetPointer().init(game, source); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + if (game.getPermanentEntering(source.getSourceId()) != null) { + Effect effect = new ReturnToHandTargetEffect(); + effect.setText("return the dashed creature from the battlefield to its owner's hand"); + // init target pointer now because the dashed creature will only be returned from battlefield zone (now in entering state so zone change counter is not raised yet) + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()) + 1)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } return false; } } diff --git a/Mage/src/mage/abilities/keyword/DevourAbility.java b/Mage/src/mage/abilities/keyword/DevourAbility.java index 1d4cdcfa822..ec3148a990a 100644 --- a/Mage/src/mage/abilities/keyword/DevourAbility.java +++ b/Mage/src/mage/abilities/keyword/DevourAbility.java @@ -27,51 +27,51 @@ */ package mage.abilities.keyword; -import mage.constants.Zone; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DevourEffect; import mage.abilities.effects.common.DevourEffect.DevourFactor; +import mage.constants.Zone; /** * 502.82. Devour * - * 502.82a Devour is a static ability. "Devour N" means "As this object comes into play, - * you may sacrifice any number of creatures. This permanent comes into play with N +1/+1 - * counters on it for each creature sacrificed this way." + * 502.82a Devour is a static ability. "Devour N" means "As this object comes + * into play, you may sacrifice any number of creatures. This permanent comes + * into play with N +1/+1 counters on it for each creature sacrificed this way." * - * 502.82b Some objects have abilities that refer to the number of creatures the permanent - * devoured. "It devoured" means "sacrificed as a result of its devour ability as it came - * into play." + * 502.82b Some objects have abilities that refer to the number of creatures the + * permanent devoured. "It devoured" means "sacrificed as a result of its devour + * ability as it came into play." * * Devour appears only on creature cards. * - * A creature with devour can devour other creatures no matter how it comes into play. + * A creature with devour can devour other creatures no matter how it comes into + * play. * * You may choose to not sacrifice any creatures. * - * If you play a creature with devour as a spell, you choose how many and which creatures - * to devour as part of the resolution of that spell. (It can't be countered at this point.) - * The same is true of a spell or ability that lets you put a creature with devour into play. + * If you play a creature with devour as a spell, you choose how many and which + * creatures to devour as part of the resolution of that spell. (It can't be + * countered at this point.) The same is true of a spell or ability that lets + * you put a creature with devour into play. * - * You may sacrifice only creatures that are already in play. If a creature with devour and - * another creature are coming into play under your control at the same time, the creature - * with devour can't devour that other creature. The creature with devour also can't devour - * itself. + * You may sacrifice only creatures that are already in play. If a creature with + * devour and another creature are coming into play under your control at the + * same time, the creature with devour can't devour that other creature. The + * creature with devour also can't devour itself. * - * If multiple creatures with devour are coming into play under your control at the same time, - * you may use each one's devour ability. A creature you already control can be devoured by - * only one of them, however. (In other words, you can't sacrifice the same creature to satisfy - * multiple devour abilities.) All creatures devoured this way are sacrificed at the same time. + * If multiple creatures with devour are coming into play under your control at + * the same time, you may use each one's devour ability. A creature you already + * control can be devoured by only one of them, however. (In other words, you + * can't sacrifice the same creature to satisfy multiple devour abilities.) All + * creatures devoured this way are sacrificed at the same time. * * @author LevelX2 */ +public class DevourAbility extends SimpleStaticAbility { - public class DevourAbility extends SimpleStaticAbility { - - - - public DevourAbility(DevourFactor devourFactor) { - super(Zone.BATTLEFIELD, new DevourEffect(devourFactor)); + public DevourAbility(DevourFactor devourFactor) { + super(Zone.ALL, new DevourEffect(devourFactor)); } public DevourAbility(final DevourAbility ability) { @@ -82,4 +82,4 @@ import mage.abilities.effects.common.DevourEffect.DevourFactor; public DevourAbility copy() { return new DevourAbility(this); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/keyword/EvolveAbility.java b/Mage/src/mage/abilities/keyword/EvolveAbility.java index 16c1b316e01..00712d973c8 100644 --- a/Mage/src/mage/abilities/keyword/EvolveAbility.java +++ b/Mage/src/mage/abilities/keyword/EvolveAbility.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.keyword; import mage.abilities.Ability; @@ -44,46 +43,53 @@ import mage.target.targetpointer.FixedTarget; * FAQ 2013/01/11 * * 702.98. Evolve - * - * 702.98a Evolve is a triggered ability. "Evolve" means "Whenever a creature enters - * the battlefield under your control, if that creature's power is greater than this - * creature's power and/or that creature's toughness is greater than this creature's - * toughness, put a +1/+1 counter on this creature." * - * 702.98b If a creature has multiple instances of evolve, each triggers separately - * + * 702.98a Evolve is a triggered ability. "Evolve" means "Whenever a creature + * enters the battlefield under your control, if that creature's power is + * greater than this creature's power and/or that creature's toughness is + * greater than this creature's toughness, put a +1/+1 counter on this + * creature." + * + * 702.98b If a creature has multiple instances of evolve, each triggers + * separately + * * Rulings - * - * When comparing the stats of the two creatures, you always compare power to power and toughness to toughness. - * Whenever a creature enters the battlefield under your control, check its power and toughness against - * the power and toughness of the creature with evolve. If neither stat of the new creature is greater, - * evolve won't trigger at all. For example, if you control a 2/3 creature with evolve and a 2/2 creature - * enters the battlefield under your control, you won't have the opportunity to cast a spell like Giant Growth - * to make the 2/2 creature large enough to cause evolve to trigger. - * If evolve triggers, the stat comparison will happen again when the ability tries to resolve. If - * neither stat of the new creature is greater, the ability will do nothing. If the creature that - * entered the battlefield leaves the battlefield before evolve tries to resolve, use its last known - * power and toughness to compare the stats. - * If a creature enters the battlefield with +1/+1 counters on it, consider those counters when determining - * if evolve will trigger. For example, a 1/1 creature that enters the battlefield with two +1/+1 counters - * on it will cause the evolve ability of a 2/2 creature to trigger. - * If multiple creatures enter the battlefield at the same time, evolve may trigger multiple times, although the stat - * comparison will take place each time one of those abilities tries to resolve. For example, if you control a 2/2 - * creature with evolve and two 3/3 creatures enter the battlefield, evolve will trigger twice. The first ability - * will resolve and put a +1/+1 counter on the creature with evolve. When the second ability tries to resolve, - * neither the power nor the toughness of the new creature is greater than that of the creature with evolve, - * so that ability does nothing. - * When comparing the stats as the evolve ability resolves, it's possible that the stat that's greater changes - * from power to toughness or vice versa. If this happens, the ability will still resolve and you'll put a +1/+1 - * counter on the creature with evolve. For example, if you control a 2/2 creature with evolve and a 1/3 creature - * enters the battlefield under your control, it toughness is greater so evolve will trigger. In response, the 1/3 - * creature gets +2/-2. When the evolve trigger tries to resolve, its power is greater. You'll put a +1/+1 - * counter on the creature with evolve. - * + * + * When comparing the stats of the two creatures, you always compare power to + * power and toughness to toughness. Whenever a creature enters the battlefield + * under your control, check its power and toughness against the power and + * toughness of the creature with evolve. If neither stat of the new creature is + * greater, evolve won't trigger at all. For example, if you control a 2/3 + * creature with evolve and a 2/2 creature enters the battlefield under your + * control, you won't have the opportunity to cast a spell like Giant Growth to + * make the 2/2 creature large enough to cause evolve to trigger. If evolve + * triggers, the stat comparison will happen again when the ability tries to + * resolve. If neither stat of the new creature is greater, the ability will do + * nothing. If the creature that entered the battlefield leaves the battlefield + * before evolve tries to resolve, use its last known power and toughness to + * compare the stats. If a creature enters the battlefield with +1/+1 counters + * on it, consider those counters when determining if evolve will trigger. For + * example, a 1/1 creature that enters the battlefield with two +1/+1 counters + * on it will cause the evolve ability of a 2/2 creature to trigger. If multiple + * creatures enter the battlefield at the same time, evolve may trigger multiple + * times, although the stat comparison will take place each time one of those + * abilities tries to resolve. For example, if you control a 2/2 creature with + * evolve and two 3/3 creatures enter the battlefield, evolve will trigger + * twice. The first ability will resolve and put a +1/+1 counter on the creature + * with evolve. When the second ability tries to resolve, neither the power nor + * the toughness of the new creature is greater than that of the creature with + * evolve, so that ability does nothing. When comparing the stats as the evolve + * ability resolves, it's possible that the stat that's greater changes from + * power to toughness or vice versa. If this happens, the ability will still + * resolve and you'll put a +1/+1 counter on the creature with evolve. For + * example, if you control a 2/2 creature with evolve and a 1/3 creature enters + * the battlefield under your control, it toughness is greater so evolve will + * trigger. In response, the 1/3 creature gets +2/-2. When the evolve trigger + * tries to resolve, its power is greater. You'll put a +1/+1 counter on the + * creature with evolve. + * * @author LevelX2 */ - - public class EvolveAbility extends TriggeredAbilityImpl { public EvolveAbility() { @@ -169,4 +175,3 @@ class EvolveEffect extends OneShotEffect { return false; } } - diff --git a/Mage/src/mage/abilities/keyword/FadingAbility.java b/Mage/src/mage/abilities/keyword/FadingAbility.java index 4a66d7dcda7..e8e45295810 100644 --- a/Mage/src/mage/abilities/keyword/FadingAbility.java +++ b/Mage/src/mage/abilities/keyword/FadingAbility.java @@ -18,25 +18,17 @@ import mage.game.permanent.Permanent; * 702.31a Fading is a keyword that represents two abilities. “Fading N” means “This permanent enters the battlefield with N fade counters on it” and “At the beginning of your upkeep, remove a fade counter from this permanent. If you can’t, sacrifice the permanent.” * */ - public class FadingAbility extends EntersBattlefieldAbility { - - + private String ruleText; - + public FadingAbility(int fadeCounter, Card card) { super(new AddCountersSourceEffect(CounterType.FADE.createInstance(fadeCounter)), "with"); Ability ability = new BeginningOfUpkeepTriggeredAbility(new FadingEffect(), TargetController.YOU, false); ability.setRuleVisible(false); addSubAbility(ability); - StringBuilder sb = new StringBuilder("Fading "); - sb.append(fadeCounter); - sb.append(" (This permanent enters the battlefield with ") - .append(fadeCounter) - .append(" fade counters on it. ") - .append(" At the beginning of your upkeep, remove a fade counter from this permanent. If you can’t, sacrifice the permanent.") - .append(")"); - ruleText = sb.toString(); + ruleText = "Fading " + fadeCounter + " (This permanent enters the battlefield with " + fadeCounter + " fade counters on it." + + " At the beginning of your upkeep, remove a fade counter from this permanent. If you can’t, sacrifice the permanent."; } public FadingAbility(final FadingAbility ability) { @@ -54,7 +46,9 @@ public class FadingAbility extends EntersBattlefieldAbility { return ruleText; } } + class FadingEffect extends OneShotEffect { + FadingEffect() { super(Outcome.Sacrifice); staticText = "remove a fade counter from this permanent. If you can’t, sacrifice the permanent"; @@ -64,18 +58,15 @@ class FadingEffect extends OneShotEffect { super(effect); } - @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { - int amount = p.getCounters().getCount(CounterType.FADE); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + int amount = permanent.getCounters().getCount(CounterType.FADE); if (amount > 0) { - p.removeCounters(CounterType.FADE.createInstance(), game); - } - else - { - p.sacrifice(source.getSourceId(), game); + permanent.removeCounters(CounterType.FADE.createInstance(), game); + } else { + permanent.sacrifice(source.getSourceId(), game); } return true; } @@ -86,4 +77,4 @@ class FadingEffect extends OneShotEffect { public FadingEffect copy() { return new FadingEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/keyword/GraftAbility.java b/Mage/src/mage/abilities/keyword/GraftAbility.java index 45eed19b928..14132f4f128 100644 --- a/Mage/src/mage/abilities/keyword/GraftAbility.java +++ b/Mage/src/mage/abilities/keyword/GraftAbility.java @@ -1,30 +1,30 @@ /* -* 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. -*/ + * 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.abilities.keyword; import java.util.Locale; @@ -48,18 +48,19 @@ import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; /** - * 702.56. Graft - * 702.56a. Graft represents both a static ability and a triggered ability. Graft N means, - * "This permanent enters the battlefield with N +1/+1 counters on it" and, "Whenever - * another creature enters the battlefield, if this permanent has a +1/+1 counter on it, - * you may move a +1/+1 counter from this permanent onto that creature." + * 702.56. Graft 702.56a. Graft represents both a static ability and a triggered + * ability. Graft N means, "This permanent enters the battlefield with N +1/+1 + * counters on it" and, "Whenever another creature enters the battlefield, if + * this permanent has a +1/+1 counter on it, you may move a +1/+1 counter from + * this permanent onto that creature." * - * 702.56b. If a creature has multiple instances of graft, each one works separately. + * 702.56b. If a creature has multiple instances of graft, each one works + * separately. * * @author LevelX2 */ - public class GraftAbility extends TriggeredAbilityImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); private int amount; @@ -112,10 +113,10 @@ public class GraftAbility extends TriggeredAbilityImpl { @Override public String getRule() { StringBuilder sb = new StringBuilder("Graft"); - sb.append(" ").append(amount).append(" (This ").append(cardtype).append(" enters the battlefield with ") - .append(amount == 1 ? "a": CardUtil.numberToText(amount)) - .append(" +1/+1 counter on it. Whenever a creature enters the battlefield, you may move a +1/+1 counter from this ") - .append(cardtype).append(" onto it.)"); + sb.append(" ").append(amount).append(" (This ").append(cardtype).append(" enters the battlefield with ") + .append(amount == 1 ? "a" : CardUtil.numberToText(amount)) + .append(" +1/+1 counter on it. Whenever a creature enters the battlefield, you may move a +1/+1 counter from this ") + .append(cardtype).append(" onto it.)"); return sb.toString(); } @@ -126,7 +127,7 @@ class GraftStaticAbility extends StaticAbility { private String ruleText; public GraftStaticAbility(int amount) { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); + super(Zone.ALL, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); ruleText = new StringBuilder("This enters the battlefield with ").append(amount).append(" +1/+1 counter on it.").toString(); this.setRuleVisible(false); } @@ -147,7 +148,6 @@ class GraftStaticAbility extends StaticAbility { } } - class GraftDistributeCounterEffect extends OneShotEffect { public GraftDistributeCounterEffect() { diff --git a/Mage/src/mage/abilities/keyword/HideawayAbility.java b/Mage/src/mage/abilities/keyword/HideawayAbility.java index 57ff119d397..b312fc9f3fb 100644 --- a/Mage/src/mage/abilities/keyword/HideawayAbility.java +++ b/Mage/src/mage/abilities/keyword/HideawayAbility.java @@ -65,7 +65,7 @@ import mage.util.CardUtil; public class HideawayAbility extends StaticAbility { public HideawayAbility() { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new TapSourceEffect(true))); + super(Zone.ALL, new EntersBattlefieldEffect(new TapSourceEffect(true))); Ability ability = new EntersBattlefieldTriggeredAbility(new HideawayExileEffect(), false); ability.setRuleVisible(false); addSubAbility(ability); @@ -115,17 +115,17 @@ class HideawayExileEffect extends OneShotEffect { if (hideawaySource == null || controller == null) { return false; } - + Cards cards = new CardsImpl(Zone.LIBRARY); - cards.addAll(controller.getLibrary().getTopCards(game, 4)); + cards.addAll(controller.getLibrary().getTopCards(game, 4)); if (cards.size() > 0) { TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1); if (controller.choose(Outcome.Detriment, cards, target1, game)) { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), - "Hideaway (" + hideawaySource.getIdName() +")", source.getSourceId(), game, Zone.LIBRARY, false); + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), + "Hideaway (" + hideawaySource.getIdName() + ")", source.getSourceId(), game, Zone.LIBRARY, false); card.setFaceDown(true, game); } } @@ -159,7 +159,7 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (game.getState().getZone(objectId) != Zone.EXILED + if (game.getState().getZone(objectId) != Zone.EXILED || !game.getState().getCardState(objectId).isFaceDown()) { return false; } @@ -180,4 +180,3 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl { return false; } } - diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java index f7bc6c8ff84..138189fc086 100644 --- a/Mage/src/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/mage/abilities/keyword/KickerAbility.java @@ -203,7 +203,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo if (zcc == 0) { zcc = game.getState().getZoneChangeCounter(source.getSourceId()); } - if (zcc > 0 && (source.getAbilityType().equals(AbilityType.TRIGGERED) || source.getAbilityType().equals(AbilityType.STATIC))) { + if (zcc > 0 && (source.getAbilityType().equals(AbilityType.TRIGGERED))) { --zcc; } return String.valueOf(zcc) + ((kickerCosts.size() > 1) ? costText : ""); diff --git a/Mage/src/mage/abilities/keyword/ModularAbility.java b/Mage/src/mage/abilities/keyword/ModularAbility.java index 19219e21b2d..5efdb7a01a7 100644 --- a/Mage/src/mage/abilities/keyword/ModularAbility.java +++ b/Mage/src/mage/abilities/keyword/ModularAbility.java @@ -22,24 +22,24 @@ import mage.target.Target; import mage.target.common.TargetArtifactPermanent; import mage.util.CardUtil; - /** * * 702.41. Modular * - * 702.41a Modular represents both a static ability and a triggered ability. - * "Modular N" means "This permanent enters the battlefield with N +1/+1 - * counters on it" and "When this permanent is put into a graveyard - * from the battlefield, you may put a +1/+1 counter on target artifact - * creature for each +1/+1 counter on this permanent." - * 702.41b If a creature has multiple instances of modular, each one works separately. + * 702.41a Modular represents both a static ability and a triggered ability. + * "Modular N" means "This permanent enters the battlefield with N +1/+1 + * counters on it" and "When this permanent is put into a graveyard from the + * battlefield, you may put a +1/+1 counter on target artifact creature for each + * +1/+1 counter on this permanent." 702.41b If a creature has multiple + * instances of modular, each one works separately. + * * - * * @author Loki, LevelX2 */ - public class ModularAbility extends DiesTriggeredAbility { + private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact creature"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } @@ -74,7 +74,7 @@ public class ModularAbility extends DiesTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { if (super.checkTrigger(event, game)) { - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; if (zEvent.getTarget().getCounters().getCount(CounterType.P1P1) > 0) { return true; } @@ -94,9 +94,9 @@ public class ModularAbility extends DiesTriggeredAbility { sb.append("-Sunburst (This enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. When it dies, you may put its +1/+1 counters on target artifact creature.)"); } else { sb.append(" ").append(amount).append(" (This enters the battlefield with ") - .append(CardUtil.numberToText(amount, "a")) - .append(" +1/+1 counter").append(amount != 1 ? "s":"") - .append(" on it. When it dies, you may put its +1/+1 counters on target artifact creature.)"); + .append(CardUtil.numberToText(amount, "a")) + .append(" +1/+1 counter").append(amount != 1 ? "s" : "") + .append(" on it. When it dies, you may put its +1/+1 counters on target artifact creature.)"); } return sb.toString(); } @@ -108,10 +108,8 @@ class ModularStaticAbility extends StaticAbility { private String ruleText; public ModularStaticAbility(int amount) { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); - ruleText = new StringBuilder("This enters the battlefield with ").append(CardUtil.numberToText(amount, "a")) - .append(" +1/+1 counter").append(amount != 1 ? "s":"") - .append(" on it.").toString(); + super(Zone.ALL, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); + ruleText = "This enters the battlefield with " + CardUtil.numberToText(amount, "a") + " +1/+1 counter" + (amount != 1 ? "s" : "") + " on it."; this.setRuleVisible(false); } @@ -131,9 +129,10 @@ class ModularStaticAbility extends StaticAbility { } } - class ModularDistributeCounterEffect extends OneShotEffect { + private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact creature"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } diff --git a/Mage/src/mage/abilities/keyword/SunburstAbility.java b/Mage/src/mage/abilities/keyword/SunburstAbility.java index 12b9d7834ae..ba1b59adcee 100644 --- a/Mage/src/mage/abilities/keyword/SunburstAbility.java +++ b/Mage/src/mage/abilities/keyword/SunburstAbility.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.keyword; import mage.abilities.Ability; @@ -46,25 +45,22 @@ import mage.players.Player; * * @author Plopman */ +public class SunburstAbility extends EntersBattlefieldAbility { - -public class SunburstAbility extends EntersBattlefieldAbility{ - - private final static String ruleCreature ="Sunburst (This enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.)"; - private final static String ruleNonCreature ="Sunburst (This enters the battlefield with a charge counter on it for each color of mana spent to cast it.)"; + private final static String ruleCreature = "Sunburst (This enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.)"; + private final static String ruleNonCreature = "Sunburst (This enters the battlefield with a charge counter on it for each color of mana spent to cast it.)"; private boolean isCreature; - public SunburstAbility(Card card){ - super(new SunburstEffect(),""); + public SunburstAbility(Card card) { + super(new SunburstEffect(), ""); isCreature = card.getCardType().contains(CardType.CREATURE); } - - public SunburstAbility(final SunburstAbility ability){ + + public SunburstAbility(final SunburstAbility ability) { super(ability); this.isCreature = ability.isCreature; } - - + @Override public EntersBattlefieldAbility copy() { return new SunburstAbility(this); @@ -74,15 +70,13 @@ public class SunburstAbility extends EntersBattlefieldAbility{ public String getRule() { return isCreature ? ruleCreature : ruleNonCreature; } - - + } class SunburstEffect extends OneShotEffect { private static final DynamicValue amount = new SunburstCount(); - public SunburstEffect() { super(Outcome.Benefit); staticText = "Sunburst"; @@ -94,22 +88,21 @@ class SunburstEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { Counter counter; - if(permanent.getCardType().contains(CardType.CREATURE)){ - counter = CounterType.P1P1.createInstance(amount.calculate(game, source, this)); - } - else{ - counter = CounterType.CHARGE.createInstance(amount.calculate(game, source, this)); + if (permanent.getCardType().contains(CardType.CREATURE)) { + counter = CounterType.P1P1.createInstance(amount.calculate(game, source, this)); + } else { + counter = CounterType.CHARGE.createInstance(amount.calculate(game, source, this)); } if (counter != null) { - + permanent.addCounters(counter, game); if (!game.isSimulation()) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - game.informPlayers(player.getLogName()+ " puts " + counter.getCount() + " " + counter.getName() + " counter on " + permanent.getName()); + game.informPlayers(player.getLogName() + " puts " + counter.getCount() + " " + counter.getName() + " counter on " + permanent.getName()); } } } diff --git a/Mage/src/mage/abilities/keyword/TributeAbility.java b/Mage/src/mage/abilities/keyword/TributeAbility.java index ad5ad5b6b7b..5cf0b1cf8e5 100644 --- a/Mage/src/mage/abilities/keyword/TributeAbility.java +++ b/Mage/src/mage/abilities/keyword/TributeAbility.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.keyword; import java.util.UUID; @@ -46,23 +45,20 @@ import mage.util.CardUtil; * * @author LevelX2 */ - - -public class TributeAbility extends EntersBattlefieldAbility{ +public class TributeAbility extends EntersBattlefieldAbility { private int tributeValue; - public TributeAbility(int tributeValue){ - super(new TributeEffect(tributeValue), false); + public TributeAbility(int tributeValue) { + super(new TributeEffect(tributeValue)); this.tributeValue = tributeValue; } - public TributeAbility(final TributeAbility ability){ + public TributeAbility(final TributeAbility ability) { super(ability); this.tributeValue = ability.tributeValue; } - @Override public EntersBattlefieldAbility copy() { return new TributeAbility(this); @@ -81,7 +77,7 @@ public class TributeAbility extends EntersBattlefieldAbility{ class TributeEffect extends OneShotEffect { - private int tributeValue; + private final int tributeValue; public TributeEffect(int tributeValue) { super(Outcome.Detriment); @@ -101,7 +97,7 @@ class TributeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && sourcePermanent != null) { UUID opponentId; if (game.getOpponents(controller.getId()).size() == 1) { @@ -117,16 +113,18 @@ class TributeEffect extends OneShotEffect { StringBuilder sb = new StringBuilder("Pay tribute to "); sb.append(sourcePermanent.getName()); sb.append(" (add ").append(CardUtil.numberToText(tributeValue)).append(" +1/+1 counter"); - sb.append(tributeValue > 1 ? "s":"").append(" to it)?"); + sb.append(tributeValue > 1 ? "s" : "").append(" to it)?"); if (opponent.chooseUse(outcome, sb.toString(), source, game)) { - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(opponent.getLogName() + " pays tribute to " + sourcePermanent.getLogName()); + } game.getState().setValue("tributeValue" + source.getSourceId(), "yes"); return new AddCountersSourceEffect(CounterType.P1P1.createInstance(tributeValue), true).apply(game, source); } else { - if (!game.isSimulation()) + if (!game.isSimulation()) { game.informPlayers(opponent.getLogName() + " does not pay tribute to " + sourcePermanent.getLogName()); - game.getState().setValue("tributeValue"+ source.getSourceId(), "no"); + } + game.getState().setValue("tributeValue" + source.getSourceId(), "no"); } return true; } diff --git a/Mage/src/mage/abilities/keyword/UnleashAbility.java b/Mage/src/mage/abilities/keyword/UnleashAbility.java index 45112f075b2..953d482278f 100644 --- a/Mage/src/mage/abilities/keyword/UnleashAbility.java +++ b/Mage/src/mage/abilities/keyword/UnleashAbility.java @@ -26,64 +26,57 @@ * or implied, of BetaSteward_at_googlemail.com. */ package mage.abilities.keyword; - -import mage.constants.Duration; -import mage.constants.Outcome; + import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.RestrictionEffect; +import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; - -/** - * - * @author LevelX2 - */ - // // 702.96. Unleash // -// 702.96a Unleash is a keyword that represents two static abilities. +// 702.96a Unleash is a keyword that represents two static abilities. // "Unleash" means "You may have this permanent enter the battlefield with an additional +1/+1 counter on it" // and "This permanent can’t block as long as it has a +1/+1 counter on it." +public class UnleashAbility extends SimpleStaticAbility { - - public class UnleashAbility extends SimpleStaticAbility { - public UnleashAbility() { super(Zone.ALL, new UnleashReplacementEffect()); this.addEffect(new UnleashRestrictionEffect()); } - + public UnleashAbility(final UnleashAbility ability) { super(ability); } - + @Override public UnleashAbility copy() { return new UnleashAbility(this); } - + @Override public String getRule() { return "Unleash (You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it.)"; } } - + class UnleashReplacementEffect extends ReplacementEffectImpl { - + public UnleashReplacementEffect() { super(Duration.EndOfGame, Outcome.Detriment); } - + public UnleashReplacementEffect(UnleashReplacementEffect effect) { super(effect); } @@ -95,53 +88,51 @@ class UnleashReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getTargetId().equals(source.getSourceId())) { - return true; - } - return false; + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean apply(Game game, Ability source) { return false; } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { - if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", source, game)) { - if (!game.isSimulation()) + if (controller.chooseUse(outcome, "Unleash " + creature.getLogName() + "?", source, game)) { + if (!game.isSimulation()) { game.informPlayers(controller.getLogName() + " unleashes " + creature.getName()); + } creature.addCounters(CounterType.P1P1.createInstance(), game); } } return false; } - + @Override public String getText(Mode mode) { return staticText; } - + @Override public UnleashReplacementEffect copy() { return new UnleashReplacementEffect(this); } - + } - + class UnleashRestrictionEffect extends RestrictionEffect { - + public UnleashRestrictionEffect() { super(Duration.WhileOnBattlefield); } - + public UnleashRestrictionEffect(final UnleashRestrictionEffect effect) { super(effect); } - + @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (permanent != null && permanent.getId().equals(source.getSourceId())) { @@ -151,14 +142,14 @@ class UnleashRestrictionEffect extends RestrictionEffect { } return false; } - + @Override public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { return false; } - + @Override public UnleashRestrictionEffect copy() { return new UnleashRestrictionEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 2d3fa165cfe..a24fc9323df 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -512,7 +512,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } break; case STACK: - StackObject stackObject = game.getStack().getSpell(getSpellAbility().getId()); + StackObject stackObject; + if (getSpellAbility() != null) { + stackObject = game.getStack().getSpell(getSpellAbility().getId()); + } else { + stackObject = game.getStack().getSpell(this.getId()); + } if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId()); if (stackObject == null) { diff --git a/Mage/src/mage/cards/repository/CardRepository.java b/Mage/src/mage/cards/repository/CardRepository.java index 0605160f496..ab5ff527376 100644 --- a/Mage/src/mage/cards/repository/CardRepository.java +++ b/Mage/src/mage/cards/repository/CardRepository.java @@ -61,7 +61,7 @@ public enum CardRepository { private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE"; private static final String VERSION_ENTITY_NAME = "card"; // raise this if db structure was changed - private static final long CARD_DB_VERSION = 41; + private static final long CARD_DB_VERSION = 42; // raise this if new cards were added to the server private static final long CARD_CONTENT_VERSION = 40; diff --git a/Mage/src/mage/constants/AbilityWord.java b/Mage/src/mage/constants/AbilityWord.java index 29088e89d1f..f9c33524530 100644 --- a/Mage/src/mage/constants/AbilityWord.java +++ b/Mage/src/mage/constants/AbilityWord.java @@ -33,19 +33,37 @@ package mage.constants; */ public enum AbilityWord { - RALLY("Rally"), + BATTALION("Battalion"), BLOODRUSH("Bloodrush"), - CONVERGE("Converge"), + CHANNEL("Channel"), + CHROMA("Chroma"), CONSTELLATION("Constellation"), + CONVERGE("Converge"), + DOMAIN("Domain"), + FATEFUL_HOUR("Fateful hour"), FEROCIOUS("Ferocious"), FORMIDABLE("Formidable"), GRANDEUR("Grandeur"), HELLBENT("Hellbent"), HEROIC("Heroic"), + IMPRINT("Imprint"), + INSPIRED("Inspired"), + JOIN_FORCES("Join forces"), + KINSHIP("Kinship"), LANDFALL("Landfall"), + LIEUTENANT("Lieutenant"), METALCRAFT("Metalcraft"), + MORBID("Morbid"), PARLEY("Parley"), - RAID("Raid"); + RADIANCE("Radiance"), + RAID("Raid"), + RALLY("Rally"), + SPELL_MASTERY("Spell mastery"), + STRIVE("Strive"), + SWEEP("Sweep"), + TEMPTING_OFFER("Tempting offer"), + THRESHOLD("Threshold"), + WILL_OF_THE_COUNCIL("Will of the council"); private final String text; diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index b75ea6a76e5..432ade1bf80 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -115,6 +115,10 @@ public interface Game extends MageItem, Serializable { Permanent getPermanentOrLKIBattlefield(UUID permanentId); + Permanent getPermanentEntering(UUID permanentId); + + Map getPermanentsEntering(); + Map> getLKI(); Card getCard(UUID cardId); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index f67b6387437..816db0ded7b 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -176,6 +176,9 @@ public abstract class GameImpl implements Game, Serializable { // Used to check if an object was moved by the current effect in resolution (so Wrath like effect can be handled correctly) protected Map> shortLivingLKI = new EnumMap<>(Zone.class); + // Permanents entering the Battlefield while handling replacement effects before they are added to the battlefield + protected Map permanentsEntering = new HashMap<>(); + protected GameState state; private transient Stack savedStates = new Stack<>(); protected transient GameStates gameStates = new GameStates(); @@ -244,6 +247,7 @@ public abstract class GameImpl implements Game, Serializable { this.lki.putAll(game.lki); this.lkiExtended.putAll(game.lkiExtended); this.shortLivingLKI.putAll(game.shortLivingLKI); + this.permanentsEntering.putAll(game.permanentsEntering); if (logger.isDebugEnabled()) { copyCount++; copyTime += (System.currentTimeMillis() - t1); @@ -501,6 +505,16 @@ public abstract class GameImpl implements Game, Serializable { return permanent; } + @Override + public Permanent getPermanentEntering(UUID permanentId) { + return permanentsEntering.get(permanentId); + } + + @Override + public Map getPermanentsEntering() { + return permanentsEntering; + } + @Override public Card getCard(UUID cardId) { if (cardId == null) { @@ -891,7 +905,7 @@ public abstract class GameImpl implements Game, Serializable { return; } getState().setChoosingPlayerId(choosingPlayerId); // needed to start/stop the timer if active - if (choosingPlayer != null && choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { + if (choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { startingPlayerId = targetPlayer.getTargets().get(0); } else if (getState().getPlayers().size() < 3) { // not possible to choose starting player, choosing player has probably conceded, so stop here @@ -2539,8 +2553,10 @@ public abstract class GameImpl implements Game, Serializable { card.setZone(Zone.BATTLEFIELD, this); card.setOwnerId(ownerId); PermanentCard permanent = new PermanentCard(card.getCard(), ownerId, this); - getBattlefield().addPermanent(permanent); + getPermanentsEntering().put(permanent.getId(), permanent); permanent.entersBattlefield(permanent.getId(), this, Zone.OUTSIDE, false); + getBattlefield().addPermanent(permanent); + getPermanentsEntering().remove(permanent.getId()); ((PermanentImpl) permanent).removeSummoningSickness(); if (card.isTapped()) { permanent.setTapped(true); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 783801dc7f2..3b767772abc 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -647,6 +647,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (!game.replaceEvent(new GameEvent(GameEvent.EventType.ATTACH, objectId, permanentId, controllerId))) { this.attachments.add(permanentId); Permanent attachment = game.getPermanent(permanentId); + if (attachment == null) { + attachment = game.getPermanentEntering(permanentId); + } if (attachment != null) { attachment.attachTo(objectId, game); game.fireEvent(new GameEvent(GameEvent.EventType.ATTACHED, objectId, permanentId, controllerId)); diff --git a/Mage/src/mage/game/permanent/token/Token.java b/Mage/src/mage/game/permanent/token/Token.java index e60605b0892..5f9686cf8a9 100644 --- a/Mage/src/mage/game/permanent/token/Token.java +++ b/Mage/src/mage/game/permanent/token/Token.java @@ -42,6 +42,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import mage.players.Player; @@ -148,31 +149,43 @@ public class Token extends MageObjectImpl { GameEvent event = new GameEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount, this.getCardType().contains(CardType.CREATURE)); if (!game.replaceEvent(event)) { amount = event.getAmount(); + + List permanents = new ArrayList<>(); + List permanentsEntered = new ArrayList<>(); + for (int i = 0; i < amount; i++) { PermanentToken newToken = new PermanentToken(this, event.getPlayerId(), setCode, game); // use event.getPlayerId() because it can be replaced by replacement effect game.getState().addCard(newToken); - game.addPermanent(newToken); - if (tapped) { - newToken.setTapped(true); - } - this.lastAddedTokenIds.add(newToken.getId()); - this.lastAddedTokenId = newToken.getId(); - game.setScopeRelevant(true); - game.applyEffects(); - boolean entered = newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true); - game.setScopeRelevant(false); - game.applyEffects(); - if (entered) { - game.fireEvent(new ZoneChangeEvent(newToken, event.getPlayerId(), Zone.OUTSIDE, Zone.BATTLEFIELD)); - if (attacking && game.getCombat() != null) { - game.getCombat().addAttackingCreature(newToken.getId(), game); - } - if (!game.isSimulation()) { - game.informPlayers(controller.getLogName() + " puts a " + newToken.getLogName() + " token onto the battlefield"); - } + permanents.add(newToken); + game.getPermanentsEntering().put(newToken.getId(), newToken); + newToken.setTapped(tapped); + } + game.setScopeRelevant(true); + for (Permanent permanent : permanents) { + if (permanent.entersBattlefield(sourceId, game, Zone.OUTSIDE, true)) { + permanentsEntered.add(permanent); + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } + game.setScopeRelevant(false); + for (Permanent permanent : permanentsEntered) { + game.addPermanent(permanent); + permanent.setZone(Zone.BATTLEFIELD, game); + game.getPermanentsEntering().remove(permanent.getId()); + this.lastAddedTokenIds.add(permanent.getId()); + this.lastAddedTokenId = permanent.getId(); + game.addSimultaneousEvent(new ZoneChangeEvent(permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD)); + if (attacking && game.getCombat() != null) { + game.getCombat().addAttackingCreature(permanent.getId(), game); + } + if (!game.isSimulation()) { + game.informPlayers(controller.getLogName() + " puts a " + permanent.getLogName() + " token onto the battlefield"); + } + + } + game.applyEffects(); return true; } return false; diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 482bfb8451e..83b99d90d46 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -232,7 +232,7 @@ public class Spell extends StackObjImpl implements Card { card.getCardType().remove(CardType.CREATURE); card.getSubtype().add("Aura"); } - if (card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId)) { + if (controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null)) { if (bestow) { // card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed // TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities @@ -253,8 +253,7 @@ public class Spell extends StackObjImpl implements Card { // Aura has no legal target and its a bestow enchantment -> Add it to battlefield as creature if (this.getSpellAbility() instanceof BestowAbility) { updateOptionalCosts(0); - result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId); - return result; + return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); } else { //20091005 - 608.2b if (!game.isSimulation()) { @@ -265,9 +264,7 @@ public class Spell extends StackObjImpl implements Card { } } else { updateOptionalCosts(0); -// return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); - result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId, false, faceDown); - return result; + return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); } } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index b484fb8ccf9..7cfa4444370 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -629,15 +629,26 @@ public interface Player extends MageItem, Copyable { * @param game * @return */ + @Deprecated boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game); + @Deprecated boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game); + @Deprecated boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game); + boolean moveCards(Card card, Zone toZone, Ability source, Game game); + boolean moveCards(Card card, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects); + boolean moveCards(Cards cards, Zone toZone, Ability source, Game game); + + boolean moveCards(Set cards, Zone toZone, Ability source, Game game); + /** + * Iniversal method to move cards from one zone to another. Do not mix + * objects from different from zones to move. * * @param cards * @param toZone @@ -730,45 +741,6 @@ public interface Player extends MageItem, Copyable { */ boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName); - /** - * Uses putOntoBattlefield and posts also a info message about in the game - * log - * - * @param card - * @param game - * @param fromZone - * @param sourceId - * @return - */ - boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId); - - /** - * Uses putOntoBattlefield and posts also a info message about in the game - * log - * - * @param card - * @param game - * @param fromZone - * @param sourceId - * @param tapped the card enters the battlefield tapped - * @return - */ - boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped); - - /** - * Uses putOntoBattlefield and posts also a info message about in the game - * log - * - * @param card - * @param game - * @param fromZone - * @param sourceId - * @param tapped the card enters the battlefield tapped - * @param facedown the card enters the battlefield facedown - * @return - */ - boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown); - /** * Checks if the playerToCheckId is from an opponent in range * diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 011d716acd2..80129822440 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -773,6 +773,9 @@ public abstract class PlayerImpl implements Player, Serializable { public boolean addAttachment(UUID permanentId, Game game) { if (!this.attachments.contains(permanentId)) { Permanent aura = game.getPermanent(permanentId); + if (aura == null) { + aura = game.getPermanentEntering(permanentId); + } if (aura != null) { if (!game.replaceEvent(new GameEvent(GameEvent.EventType.ENCHANT_PLAYER, playerId, permanentId, aura.getControllerId()))) { this.attachments.add(permanentId); @@ -1016,8 +1019,7 @@ public abstract class PlayerImpl implements Player, Serializable { //20091005 - 305.1 if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) { // int bookmark = game.bookmarkState(); - Zone zone = game.getState().getZone(card.getId()); - if (card.putOntoBattlefield(game, zone, null, playerId)) { + if (moveCards(card, Zone.BATTLEFIELD, playLandAbility, game, false, false, false, null)) { landsPlayed++; game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId)); game.fireInformEvent(getLogName() + " plays " + card.getLogName()); @@ -2980,40 +2982,12 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game) { - if (cards.isEmpty()) { - return true; - } - Set successfulMovedCards = new LinkedHashSet<>(); - switch (toZone) { - case EXILED: - for (Card card : cards) { - fromZone = game.getState().getZone(card.getId()); - boolean withName = (fromZone.equals(Zone.BATTLEFIELD) || fromZone.equals(Zone.STACK)) || !card.isFaceDown(game); - if (moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName)) { - successfulMovedCards.add(card); - } - } - break; - case GRAVEYARD: - successfulMovedCards = moveCardsToGraveyardWithInfo(cards, source, game, fromZone); - break; - case HAND: - case BATTLEFIELD: - return moveCards(cards, toZone, source, game, false, false, false, null); - case LIBRARY: - for (Card card : cards) { - fromZone = game.getState().getZone(card.getId()); - boolean hideCard = fromZone.equals(Zone.HAND) || fromZone.equals(Zone.LIBRARY); - if (moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, !hideCard)) { - successfulMovedCards.add(card); - } - } - break; - default: - throw new UnsupportedOperationException("to Zone not supported yet"); - } - game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); - return successfulMovedCards.size() > 0; + return moveCards(cards, toZone, source, game, false, false, false, null); + } + + @Override + public boolean moveCards(Card card, Zone toZone, Ability source, Game game) { + return moveCards(card, toZone, source, game, false, false, false, null); } @Override @@ -3025,6 +2999,16 @@ public abstract class PlayerImpl implements Player, Serializable { return moveCards(cardList, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } + @Override + public boolean moveCards(Cards cards, Zone toZone, Ability source, Game game) { + return moveCards(cards.getCards(game), toZone, source, game); + } + + @Override + public boolean moveCards(Set cards, Zone toZone, Ability source, Game game) { + return moveCards(cards, toZone, source, game, false, false, false, null); + } + @Override public boolean moveCards(Set cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { if (cards.isEmpty()) { @@ -3033,11 +3017,15 @@ public abstract class PlayerImpl implements Player, Serializable { Set successfulMovedCards = new LinkedHashSet<>(); Zone fromZone = null; switch (toZone) { - case BATTLEFIELD: + case GRAVEYARD: + fromZone = game.getState().getZone(cards.iterator().next().getId()); + successfulMovedCards = moveCardsToGraveyardWithInfo(cards, source, game, fromZone); + break; + case BATTLEFIELD: // new logic that does not yet add the permanents to battlefield while replacement effects are handled List permanents = new ArrayList<>(); List permanentsEntered = new ArrayList<>(); for (Card card : cards) { - UUID controllingPlayerId = byOwner ? card.getOwnerId() : source.getControllerId(); + UUID controllingPlayerId = byOwner ? card.getOwnerId() : getId(); fromZone = game.getState().getZone(card.getId()); if (faceDown) { card.setFaceDown(true, game); @@ -3047,6 +3035,7 @@ public abstract class PlayerImpl implements Player, Serializable { // get permanent Permanent permanent = new PermanentCard(card, event.getPlayerId(), game);// controlling player can be replaced so use event player now permanents.add(permanent); + game.getPermanentsEntering().put(permanent.getId(), permanent); card.checkForCountersToAdd(permanent, game); permanent.setTapped(tapped); permanent.setFaceDown(faceDown, game); @@ -3060,6 +3049,8 @@ public abstract class PlayerImpl implements Player, Serializable { fromZone = game.getState().getZone(permanent.getId()); if (permanent.entersBattlefield(source.getSourceId(), game, fromZone, true)) { permanentsEntered.add(permanent); + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } game.setScopeRelevant(false); @@ -3071,11 +3062,16 @@ public abstract class PlayerImpl implements Player, Serializable { game.getContinuousEffects().setController(permanent.getId(), permanent.getControllerId()); game.addPermanent(permanent); permanent.setZone(Zone.BATTLEFIELD, game); - // check if there are counters to add to the permanent (e.g. from non replacement effects like Persist) - + game.getPermanentsEntering().remove(permanent.getId()); game.setScopeRelevant(true); successfulMovedCards.add(permanent); game.addSimultaneousEvent(new ZoneChangeEvent(permanent, permanent.getControllerId(), fromZone, Zone.BATTLEFIELD)); + if (!game.isSimulation()) { + game.informPlayers(this.getLogName() + " puts " + (faceDown ? "a card face down " : permanent.getLogName()) + + " from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + " onto the Battlefield"); + } + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } game.applyEffects(); @@ -3090,8 +3086,26 @@ public abstract class PlayerImpl implements Player, Serializable { } } break; + case EXILED: + for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); + boolean withName = (fromZone.equals(Zone.BATTLEFIELD) || fromZone.equals(Zone.STACK)) || !card.isFaceDown(game); + if (moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName)) { + successfulMovedCards.add(card); + } + } + break; + case LIBRARY: + for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); + boolean hideCard = fromZone.equals(Zone.HAND) || fromZone.equals(Zone.LIBRARY); + if (moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, !hideCard)) { + successfulMovedCards.add(card); + } + } + break; default: - throw new UnsupportedOperationException("to Zone not supported yet"); + throw new UnsupportedOperationException("to Zone" + toZone.toString() + " not supported yet"); } game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); @@ -3293,31 +3307,6 @@ public abstract class PlayerImpl implements Player, Serializable { return result; } - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) { - return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false, false); - } - - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) { - return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, false); - } - - @Override - public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) { - boolean result = false; - if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped, facedown)) { - if (!game.isSimulation()) { - game.informPlayers(new StringBuilder(this.getLogName()) - .append(" puts ").append(facedown ? "a card face down " : card.getLogName()) - .append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ") - .append("onto the Battlefield").toString()); - } - result = true; - } - return result; - } - @Override public boolean hasOpponent(UUID playerToCheckId, Game game) { return !this.getId().equals(playerToCheckId) && game.isOpponent(this, playerToCheckId); diff --git a/Mage/src/mage/util/functions/AddSubtypeApplier.java b/Mage/src/mage/util/functions/AddSubtypeApplier.java new file mode 100644 index 00000000000..a007b6a9f31 --- /dev/null +++ b/Mage/src/mage/util/functions/AddSubtypeApplier.java @@ -0,0 +1,40 @@ +/* + * 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.util.functions; + +import mage.MageObject; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class AddSubtypeApplier extends ApplyToPermanent { + + private final String subtype; + + public AddSubtypeApplier(String subtype) { + this.subtype = subtype; + } + + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSubtype().contains(subtype)) { + permanent.getSubtype().add(subtype); + } + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSubtype().contains(subtype)) { + mageObject.getSubtype().add(subtype); + } + return true; + } + +} diff --git a/Mage/src/mage/util/functions/CardTypeApplier.java b/Mage/src/mage/util/functions/CardTypeApplier.java index dcb8eeb8c33..48a3eb54130 100644 --- a/Mage/src/mage/util/functions/CardTypeApplier.java +++ b/Mage/src/mage/util/functions/CardTypeApplier.java @@ -27,10 +27,36 @@ */ package mage.util.functions; +import mage.MageObject; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.permanent.Permanent; + /** * * @author LevelX2 */ -public class CardTypeApplier { +public class CardTypeApplier extends ApplyToPermanent { + private final CardType cardType; + + public CardTypeApplier(CardType cardType) { + this.cardType = cardType; + } + + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getCardType().contains(cardType)) { + permanent.getCardType().add(cardType); + } + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getCardType().contains(cardType)) { + mageObject.getCardType().add(cardType); + } + return true; + } }