From 476358740b6da5a1a0c1a71788e015293e6d64f3 Mon Sep 17 00:00:00 2001 From: emerald000 Date: Fri, 18 Jul 2014 22:15:03 -0400 Subject: [PATCH] [NEW] Added Sky Hussar, Lantern of Insight, Nether Spirit, Necroplasm and Hypergenesis. --- .../mage/sets/alliances/SoldierOfFortune.java | 41 +---- .../src/mage/sets/dissension/SkyHussar.java | 89 +++++++++++ .../mage/sets/fifthdawn/LanternOfInsight.java | 72 +++++++++ .../sets/mercadianmasques/NetherSpirit.java | 91 +++++++++++ .../src/mage/sets/ravnika/Necroplasm.java | 117 +++++++++++++++ .../mage/sets/timespiral/Hypergenesis.java | 141 ++++++++++++++++++ .../common/ShuffleLibraryTargetEffect.java | 66 ++++++++ .../PlayWithTheTopCardRevealedEffect.java | 32 +++- 8 files changed, 609 insertions(+), 40 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/dissension/SkyHussar.java create mode 100644 Mage.Sets/src/mage/sets/fifthdawn/LanternOfInsight.java create mode 100644 Mage.Sets/src/mage/sets/mercadianmasques/NetherSpirit.java create mode 100644 Mage.Sets/src/mage/sets/ravnika/Necroplasm.java create mode 100644 Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java create mode 100644 Mage/src/mage/abilities/effects/common/ShuffleLibraryTargetEffect.java diff --git a/Mage.Sets/src/mage/sets/alliances/SoldierOfFortune.java b/Mage.Sets/src/mage/sets/alliances/SoldierOfFortune.java index dd28a5a3815..d845a4f97bc 100644 --- a/Mage.Sets/src/mage/sets/alliances/SoldierOfFortune.java +++ b/Mage.Sets/src/mage/sets/alliances/SoldierOfFortune.java @@ -28,19 +28,16 @@ package mage.sets.alliances; 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.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ShuffleLibraryTargetEffect; import mage.cards.CardImpl; -import mage.game.Game; -import mage.players.Player; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.TargetPlayer; /** @@ -59,7 +56,7 @@ public class SoldierOfFortune extends CardImpl { this.toughness = new MageInt(1); // {R}, {T}: Target player shuffles his or her library. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SoldierOfFortuneEffect(), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleLibraryTargetEffect(), new TapSourceCost()); ability.addManaCost(new ManaCostsImpl("{R}")); ability.addTarget(new TargetPlayer()); this.addAbility(ability); @@ -74,31 +71,3 @@ public class SoldierOfFortune extends CardImpl { return new SoldierOfFortune(this); } } - -class SoldierOfFortuneEffect extends OneShotEffect { - - public SoldierOfFortuneEffect() { - super(Outcome.Neutral); - this.staticText = "Target player shuffles his or her library"; - } - - public SoldierOfFortuneEffect(final SoldierOfFortuneEffect effect) { - super(effect); - } - - @Override - public SoldierOfFortuneEffect copy() { - return new SoldierOfFortuneEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(targetPointer.getFirst(game, source)); - if (player != null) { - player.shuffleLibrary(game); - return true; - } - return false; - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dissension/SkyHussar.java b/Mage.Sets/src/mage/sets/dissension/SkyHussar.java new file mode 100644 index 00000000000..e5f1cd3d57d --- /dev/null +++ b/Mage.Sets/src/mage/sets/dissension/SkyHussar.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.dissension; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ForecastAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author emerald000 + */ +public class SkyHussar extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped white and/or blue creatures you control"); + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.WHITE), new ColorPredicate(ObjectColor.BLUE))); + filter.add(Predicates.not(new TappedPredicate())); + } + + public SkyHussar(UUID ownerId) { + super(ownerId, 131, "Sky Hussar", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{W}{U}"); + this.expansionSetCode = "DIS"; + this.subtype.add("Human"); + this.subtype.add("Knight"); + + this.color.setBlue(true); + this.color.setWhite(true); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Sky Hussar enters the battlefield, untap all creatures you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new UntapAllControllerEffect(new FilterControlledCreaturePermanent(), "untap all creatures you control"), false)); + + // Forecast - Tap two untapped white and/or blue creatures you control, Reveal Sky Hussar from your hand: Draw a card. + this.addAbility(new ForecastAbility(new DrawCardSourceControllerEffect(1), new TapTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, true)))); + } + + public SkyHussar(final SkyHussar card) { + super(card); + } + + @Override + public SkyHussar copy() { + return new SkyHussar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fifthdawn/LanternOfInsight.java b/Mage.Sets/src/mage/sets/fifthdawn/LanternOfInsight.java new file mode 100644 index 00000000000..18c5d56604b --- /dev/null +++ b/Mage.Sets/src/mage/sets/fifthdawn/LanternOfInsight.java @@ -0,0 +1,72 @@ +/* + * 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.fifthdawn; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ShuffleLibraryTargetEffect; +import mage.abilities.effects.common.continious.PlayWithTheTopCardRevealedEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPlayer; + +/** + * + * @author emerald000 + */ +public class LanternOfInsight extends CardImpl { + + public LanternOfInsight(UUID ownerId) { + super(ownerId, 135, "Lantern of Insight", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "5DN"; + + // Each player plays with the top card of his or her library revealed. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithTheTopCardRevealedEffect(true))); + + // {tap}, Sacrifice Lantern of Insight: Target player shuffles his or her library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleLibraryTargetEffect(), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public LanternOfInsight(final LanternOfInsight card) { + super(card); + } + + @Override + public LanternOfInsight copy() { + return new LanternOfInsight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/NetherSpirit.java b/Mage.Sets/src/mage/sets/mercadianmasques/NetherSpirit.java new file mode 100644 index 00000000000..246b165fcb8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mercadianmasques/NetherSpirit.java @@ -0,0 +1,91 @@ +/* + * 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.mercadianmasques; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author emerald000 + */ +public class NetherSpirit extends CardImpl { + + public NetherSpirit(UUID ownerId) { + super(ownerId, 149, "Nether Spirit", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.expansionSetCode = "MMQ"; + this.subtype.add("Spirit"); + + this.color.setBlack(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, if Nether Spirit is the only creature card in your graveyard, you may return Nether Spirit to the battlefield. + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(), TargetController.YOU, true); + this.addAbility(new ConditionalTriggeredAbility(ability, new NetherSpiritCondition(), "At the beginning of your upkeep, if Nether Spirit is the only creature card in your graveyard, you may return Nether Spirit to the battlefield.", true)); + } + + public NetherSpirit(final NetherSpirit card) { + super(card); + } + + @Override + public NetherSpirit copy() { + return new NetherSpirit(this); + } +} + +class NetherSpiritCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Card card = game.getCard(source.getSourceId()); + if (card != null) { + return player.getGraveyard().contains(card.getId()) && player.getGraveyard().count(new FilterCreatureCard(), game) == 1; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/ravnika/Necroplasm.java b/Mage.Sets/src/mage/sets/ravnika/Necroplasm.java new file mode 100644 index 00000000000..01af5be53a2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/ravnika/Necroplasm.java @@ -0,0 +1,117 @@ +/* + * 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.ravnika; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DredgeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.counters.CounterType; +import mage.filter.Filter.ComparisonType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author emerald000 + */ +public class Necroplasm extends CardImpl { + + public Necroplasm(UUID ownerId) { + super(ownerId, 98, "Necroplasm", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.expansionSetCode = "RAV"; + this.subtype.add("Ooze"); + + this.color.setBlack(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, put a +1/+1 counter on Necroplasm. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false)); + + // At the beginning of your end step, destroy each creature with converted mana cost equal to the number of +1/+1 counters on Necroplasm. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new NecroplasmEffect(), TargetController.YOU, false)); + + // Dredge 2 + this.addAbility(new DredgeAbility(2)); + } + + public Necroplasm(final Necroplasm card) { + super(card); + } + + @Override + public Necroplasm copy() { + return new Necroplasm(this); + } +} + +class NecroplasmEffect extends OneShotEffect { + + NecroplasmEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy each creature with converted mana cost equal to the number of +1/+1 counters on {this}."; + } + + NecroplasmEffect(final NecroplasmEffect effect) { + super(effect); + } + + @Override + public NecroplasmEffect copy() { + return new NecroplasmEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (player != null && sourcePermanent != null) { + int numCounters = sourcePermanent.getCounters().getCount(CounterType.P1P1); + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ConvertedManaCostPredicate(ComparisonType.Equal, numCounters)); + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + permanent.destroy(source.getSourceId(), game, false); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java new file mode 100644 index 00000000000..837db7138a8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java @@ -0,0 +1,141 @@ +/* + * 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.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.SuspendAbility; +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.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.players.PlayerList; +import mage.target.Target; +import mage.target.common.TargetCardInHand; + +/** + * + * @author emerald000 + */ +public class Hypergenesis extends CardImpl { + + public Hypergenesis(UUID ownerId) { + super(ownerId, 201, "Hypergenesis", Rarity.RARE, new CardType[]{CardType.SORCERY}, ""); + this.expansionSetCode = "TSP"; + this.color.setGreen(true); + + // 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()); + } + + public Hypergenesis(final Hypergenesis card) { + super(card); + } + + @Override + public Hypergenesis copy() { + return new Hypergenesis(this); + } +} + +@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))); + } + + HypergenesisEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "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."; + } + + HypergenesisEffect(final HypergenesisEffect effect) { + super(effect); + } + + @Override + public HypergenesisEffect copy() { + return new HypergenesisEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + PlayerList playerList = game.getState().getPlayerList(); + while (!playerList.get().equals(source.getControllerId()) && controller.isInGame()) { + playerList.getNext(); + } + Player currentPlayer = game.getPlayer(playerList.get()); + UUID firstInactivePlayer = null; + Target target = new TargetCardInHand(filter); + + while (controller.isInGame()) { + if (currentPlayer != null && controller.getInRange().contains(currentPlayer.getId())) { + if (firstInactivePlayer == null) { + firstInactivePlayer = currentPlayer.getId(); + } + target.clearChosen(); + if (target.canChoose(source.getSourceId(), currentPlayer.getId(), game) + && currentPlayer.chooseUse(outcome, "Put card from your hand to play?", game)) { + 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()); + firstInactivePlayer = null; + } + } + } + } + // get next player + playerList.getNext(); + currentPlayer = game.getPlayer(playerList.get()); + // if all player since this player didn't put permanent in play finish the process + if (currentPlayer.getId().equals(firstInactivePlayer)) { + break; + } + } + return true; + } + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/ShuffleLibraryTargetEffect.java b/Mage/src/mage/abilities/effects/common/ShuffleLibraryTargetEffect.java new file mode 100644 index 00000000000..e3e9e5d1042 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/ShuffleLibraryTargetEffect.java @@ -0,0 +1,66 @@ +/* + * 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.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author Mael + */ +public class ShuffleLibraryTargetEffect extends OneShotEffect { + + public ShuffleLibraryTargetEffect() { + super(Outcome.Neutral); + this.staticText = "Target player shuffles his or her library"; + } + + public ShuffleLibraryTargetEffect(final ShuffleLibraryTargetEffect effect) { + super(effect); + } + + @Override + public ShuffleLibraryTargetEffect copy() { + return new ShuffleLibraryTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + player.shuffleLibrary(game); + return true; + } + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/continious/PlayWithTheTopCardRevealedEffect.java b/Mage/src/mage/abilities/effects/common/continious/PlayWithTheTopCardRevealedEffect.java index b3b68a41758..aa3ff3fa9ed 100644 --- a/Mage/src/mage/abilities/effects/common/continious/PlayWithTheTopCardRevealedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/PlayWithTheTopCardRevealedEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common.continious; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.Duration; @@ -40,21 +41,44 @@ import mage.players.Player; * @author nantuko */ public class PlayWithTheTopCardRevealedEffect extends ContinuousEffectImpl { + + protected boolean allPlayers; public PlayWithTheTopCardRevealedEffect() { + this(false); + } + + public PlayWithTheTopCardRevealedEffect(boolean allPlayers) { super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Detriment); - staticText = "Play with the top card of your library revealed"; + this.allPlayers = allPlayers; + if (allPlayers) { + staticText = "Each player plays with the top card of his or her library revealed."; + } + else { + staticText = "Play with the top card of your library revealed"; + } } public PlayWithTheTopCardRevealedEffect(final PlayWithTheTopCardRevealedEffect effect) { super(effect); + this.allPlayers = effect.allPlayers; } @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - player.setTopCardRevealed(true); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (allPlayers) { + for (UUID playerId : controller.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.setTopCardRevealed(true); + } + } + } + else { + controller.setTopCardRevealed(true); + } return true; } return false;