From 547c7078bfec11d5d7e951724aaaa63992252676 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 3 Jan 2018 18:02:27 +0100 Subject: [PATCH] [Rix] Added 6 cards. --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 3 +- .../cards/f/ForerunnerOfTheCoalition.java | 34 ++- .../mage/cards/f/ForerunnerOfTheEmpire.java | 7 +- Mage.Sets/src/mage/cards/g/GroundSeal.java | 49 +---- Mage.Sets/src/mage/cards/m/BafflingEnd.java | 86 ++++++++ .../src/mage/cards/m/MerfolkMistbinder.java | 78 +++++++ .../src/mage/cards/p/PathToDiscovery.java | 64 ++++++ .../src/mage/cards/p/PiratesPillage.java | 65 ++++++ .../src/mage/cards/s/SilentGravestone.java | 73 +++++++ Mage.Sets/src/mage/cards/s/SphinxsDecree.java | 153 ++++++++++++++ .../src/mage/cards/u/UnderworldCerberus.java | 56 +---- Mage.Sets/src/mage/sets/RivalsOfIxalan.java | 198 +++++++++--------- .../CantBeTargetedCardsGraveyardsEffect.java | 82 ++++++++ .../effects/keyword/ExploreSourceEffect.java | 48 ++--- .../effects/keyword/ExploreTargetEffect.java | 60 ++++++ 15 files changed, 811 insertions(+), 245 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/m/BafflingEnd.java create mode 100644 Mage.Sets/src/mage/cards/m/MerfolkMistbinder.java create mode 100644 Mage.Sets/src/mage/cards/p/PathToDiscovery.java create mode 100644 Mage.Sets/src/mage/cards/p/PiratesPillage.java create mode 100644 Mage.Sets/src/mage/cards/s/SilentGravestone.java create mode 100644 Mage.Sets/src/mage/cards/s/SphinxsDecree.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedCardsGraveyardsEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/keyword/ExploreTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java index cd291187e8..a7406924a9 100644 --- a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -27,6 +27,7 @@ */ package mage.cards.a; +import java.util.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; @@ -48,8 +49,6 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetNonlandPermanent; import mage.watchers.Watcher; -import java.util.*; - /** * * @author TheElk801 diff --git a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheCoalition.java b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheCoalition.java index 4c82be5087..95762b8f5a 100644 --- a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheCoalition.java +++ b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheCoalition.java @@ -30,15 +30,15 @@ package mage.cards.f; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; import mage.filter.common.FilterBySubtypeCard; -import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCardInLibrary; @@ -49,7 +49,8 @@ import mage.target.common.TargetCardInLibrary; */ public class ForerunnerOfTheCoalition extends CardImpl { - private static final FilterCreaturePermanent filterAnotherPirate = new FilterCreaturePermanent(SubType.PIRATE, "another " + SubType.PIRATE.toString()); + private static final FilterPermanent filterAnotherPirate = new FilterPermanent(SubType.PIRATE, "another " + SubType.PIRATE.toString()); + static { filterAnotherPirate.add(new AnotherPredicate()); filterAnotherPirate.add(new ControllerPredicate(TargetController.YOU)); @@ -64,24 +65,15 @@ public class ForerunnerOfTheCoalition extends CardImpl { this.toughness = new MageInt(2); // When Forerunner of the Coalition enters the battlefield, you may search your library for a Pirate card, reveal it, then shuffle your library and put that card on top of it. - this.addAbility( - new EntersBattlefieldTriggeredAbility( - new SearchLibraryPutOnLibraryEffect( - new TargetCardInLibrary(new FilterBySubtypeCard(SubType.PIRATE)), - true, - true - ), - true - ) - ); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new SearchLibraryPutOnLibraryEffect( + new TargetCardInLibrary(new FilterBySubtypeCard(SubType.PIRATE)), + true, true), true)); // Whenever another Pirate enters the battlefield under your control, each opponent loses 1 life. - Ability ability = new CreatureEntersBattlefieldTriggeredAbility( - Zone.BATTLEFIELD, - new LoseLifeOpponentsEffect(1), - filterAnotherPirate, - false, - false); + Ability ability = new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(1), + filterAnotherPirate, false); this.addAbility(ability); } @@ -93,4 +85,4 @@ public class ForerunnerOfTheCoalition extends CardImpl { public ForerunnerOfTheCoalition copy() { return new ForerunnerOfTheCoalition(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java index 2e772a96e9..b17846dcfb 100644 --- a/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java +++ b/Mage.Sets/src/mage/cards/f/ForerunnerOfTheEmpire.java @@ -34,9 +34,9 @@ import mage.abilities.common.CreatureEntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.*; import mage.filter.common.FilterBySubtypeCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; @@ -49,6 +49,7 @@ import mage.target.common.TargetCardInLibrary; public class ForerunnerOfTheEmpire extends CardImpl { private static final FilterCreaturePermanent filterAnyDinosaur = new FilterCreaturePermanent(SubType.DINOSAUR, SubType.DINOSAUR.toString()); + static { filterAnyDinosaur.add(new ControllerPredicate(TargetController.YOU)); } @@ -76,7 +77,7 @@ public class ForerunnerOfTheEmpire extends CardImpl { // Whenever a Dinosaur enters the battlefield under your control, you may have Forerunner of the Empire deal 1 damage to each creature. Ability ability = new CreatureEntersBattlefieldTriggeredAbility( Zone.BATTLEFIELD, - new DamageAllEffect(1, new FilterCreaturePermanent()), + new DamageAllEffect(1, new FilterCreaturePermanent()).setText("have {this} deal 1 damage to each creature"), filterAnyDinosaur, true, false); @@ -91,4 +92,4 @@ public class ForerunnerOfTheEmpire extends CardImpl { public ForerunnerOfTheEmpire copy() { return new ForerunnerOfTheEmpire(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GroundSeal.java b/Mage.Sets/src/mage/cards/g/GroundSeal.java index 24e9a9b1f9..f3f5817665 100644 --- a/Mage.Sets/src/mage/cards/g/GroundSeal.java +++ b/Mage.Sets/src/mage/cards/g/GroundSeal.java @@ -28,21 +28,14 @@ package mage.cards.g; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.CantBeTargetedCardsGraveyardsEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.StackObject; /** * @author jeffwadsworth @@ -52,12 +45,11 @@ public class GroundSeal extends CardImpl { public GroundSeal(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); - // When Ground Seal enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); // Cards in graveyards can't be the targets of spells or abilities. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GroundSealEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedCardsGraveyardsEffect())); } public GroundSeal(final GroundSeal card) { @@ -69,40 +61,3 @@ public class GroundSeal extends CardImpl { return new GroundSeal(this); } } - -class GroundSealEffect extends ContinuousRuleModifyingEffectImpl { - - public GroundSealEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Cards in graveyards can't be the targets of spells or abilities"; - } - - public GroundSealEffect(final GroundSealEffect effect) { - super(effect); - } - - @Override - public GroundSealEffect copy() { - return new GroundSealEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.TARGET) { - Card targetCard = game.getCard(event.getTargetId()); - StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); - if (targetCard != null && stackObject != null) { - Zone zone = game.getState().getZone(targetCard.getId()); - if (zone != null && zone == Zone.GRAVEYARD) { - return true; - } - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/m/BafflingEnd.java b/Mage.Sets/src/mage/cards/m/BafflingEnd.java new file mode 100644 index 0000000000..2c43e9888a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/BafflingEnd.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.permanent.token.DinosaurToken; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class BafflingEnd extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with converted mana cost 3 or less an opponent controls"); + + static { + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 4)); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public BafflingEnd(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + // When Mysterious end enters the battlefield, exile target creature with converted mana cost 3 or less an opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // When Mysterious end leaves the battlefield, target opponent create a 3/3 green Dinosaur creature token with trample. + ability = new LeavesBattlefieldTriggeredAbility(new CreateTokenTargetEffect(new DinosaurToken()), false); + Target target = new TargetOpponent(); + ability.addTarget(target); + this.addAbility(ability); + + } + + public BafflingEnd(final BafflingEnd card) { + super(card); + } + + @Override + public BafflingEnd copy() { + return new BafflingEnd(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MerfolkMistbinder.java b/Mage.Sets/src/mage/cards/m/MerfolkMistbinder.java new file mode 100644 index 0000000000..9b58c8dc88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MerfolkMistbinder.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class MerfolkMistbinder extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Merfolk you control"); + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public MerfolkMistbinder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Other Merfolk you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + } + + public MerfolkMistbinder(final MerfolkMistbinder card) { + super(card); + } + + @Override + public MerfolkMistbinder copy() { + return new MerfolkMistbinder(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PathToDiscovery.java b/Mage.Sets/src/mage/cards/p/PathToDiscovery.java new file mode 100644 index 0000000000..8156d52e65 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PathToDiscovery.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.keyword.ExploreTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.StaticFilters; + +/** + * + * @author LevelX2 + */ +public class PathToDiscovery extends CardImpl { + + public PathToDiscovery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + // Whenever a creature enters the battlefield under your control, it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on the creature, then put the card back or put it into your graveyard.) + this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, new ExploreTargetEffect(), + StaticFilters.FILTER_CONTROLLED_A_CREATURE, false, SetTargetPointer.PERMANENT, null)); + + } + + public PathToDiscovery(final PathToDiscovery card) { + super(card); + } + + @Override + public PathToDiscovery copy() { + return new PathToDiscovery(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PiratesPillage.java b/Mage.Sets/src/mage/cards/p/PiratesPillage.java new file mode 100644 index 0000000000..294f37a42d --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiratesPillage.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author LevelX2 + */ +public class PiratesPillage extends CardImpl { + + public PiratesPillage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); + + // As an additional cost to cast Pirate's Pillage, discard a card. + this.getSpellAbility().addCost(new DiscardCardCost(true)); + + // Draw two cards and create two colorless Treasure artifacts with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken(), 2) + .setText("and create two colorless Treasure artifacts with \"{T}, Sacrifice this artifact: Add one mana of any color to your mana pool")); + } + + public PiratesPillage(final PiratesPillage card) { + super(card); + } + + @Override + public PiratesPillage copy() { + return new PiratesPillage(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SilentGravestone.java b/Mage.Sets/src/mage/cards/s/SilentGravestone.java new file mode 100644 index 0000000000..b016798674 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SilentGravestone.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.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CantBeTargetedCardsGraveyardsEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; +import mage.abilities.effects.common.ExileSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class SilentGravestone extends CardImpl { + + public SilentGravestone(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + // Cards in graveyards can't be the targets of spells or abilities. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedCardsGraveyardsEffect())); + + // {4}, {t}: Exile Silent Gravestone and all cards from all graveyards. Draw a card. + Ability ability = new SimpleActivatedAbility(new ExileSourceEffect(), new GenericManaCost(4)); + ability.addCost(new TapSourceCost()); + ability.addEffect(new ExileGraveyardAllPlayersEffect().setText("and all cards from all graveyards")); + ability.addEffect(new DrawCardSourceControllerEffect(1)); + this.addAbility(ability); + } + + public SilentGravestone(final SilentGravestone card) { + super(card); + } + + @Override + public SilentGravestone copy() { + return new SilentGravestone(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SphinxsDecree.java b/Mage.Sets/src/mage/cards/s/SphinxsDecree.java new file mode 100644 index 0000000000..827eef4782 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SphinxsDecree.java @@ -0,0 +1,153 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class SphinxsDecree extends CardImpl { + + public SphinxsDecree(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{W}"); + + // Each opponent can't cast instant or sorcery spells during that player's next turn. + this.getSpellAbility().addEffect(new SphinxsDecreeEffect()); + } + + public SphinxsDecree(final SphinxsDecree card) { + super(card); + } + + @Override + public SphinxsDecree copy() { + return new SphinxsDecree(this); + } +} + +class SphinxsDecreeEffect extends OneShotEffect { + + public SphinxsDecreeEffect() { + super(Outcome.Benefit); + this.staticText = "Each opponent can't cast instant or sorcery spells during that player's next turn"; + } + + public SphinxsDecreeEffect(final SphinxsDecreeEffect effect) { + super(effect); + } + + @Override + public SphinxsDecreeEffect copy() { + return new SphinxsDecreeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + ContinuousEffect effect = new SphinxsDecreeCantCastEffect(); + effect.setTargetPointer(new FixedTarget(opponentId)); + game.addEffect(effect, source); + } + return true; + } +} + +class SphinxsDecreeCantCastEffect extends ContinuousRuleModifyingEffectImpl { + + int playersNextTurn; + + public SphinxsDecreeCantCastEffect() { + super(Duration.Custom, Outcome.Detriment); + staticText = "You can't cast instant or sorcery spells during this turn"; + playersNextTurn = 0; + } + + public SphinxsDecreeCantCastEffect(final SphinxsDecreeCantCastEffect effect) { + super(effect); + this.playersNextTurn = effect.playersNextTurn; + } + + @Override + public SphinxsDecreeCantCastEffect copy() { + return new SphinxsDecreeCantCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null) { + return "You can't cast instant or sorcery spells this turn (" + mageObject.getIdName() + ")."; + } + return null; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + UUID opponentId = getTargetPointer().getFirst(game, source); + if (game.getActivePlayerId().equals(opponentId)) { + if (playersNextTurn == 0) { + playersNextTurn = game.getTurnNum(); + } + if (playersNextTurn == game.getTurnNum()) { + if (opponentId.equals(event.getPlayerId())) { + MageObject object = game.getObject(event.getSourceId()); + if (event.getType() == GameEvent.EventType.CAST_SPELL) { + if (object.isInstant() || object.isSorcery()) { + return true; + } + } + } + } else { + discard(); + } + } else if (playersNextTurn > 0) { + discard(); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnderworldCerberus.java b/Mage.Sets/src/mage/cards/u/UnderworldCerberus.java index 7fe7b0a3f3..bbf9cab2f5 100644 --- a/Mage.Sets/src/mage/cards/u/UnderworldCerberus.java +++ b/Mage.Sets/src/mage/cards/u/UnderworldCerberus.java @@ -32,22 +32,16 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.CantBeTargetedCardsGraveyardsEffect; import mage.abilities.effects.common.ExileSourceEffect; import mage.abilities.effects.common.ReturnToHandFromGraveyardAllEffect; import mage.abilities.effects.common.combat.CantBeBlockedByOneEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.StackObject; /** * @@ -56,7 +50,7 @@ import mage.game.stack.StackObject; public class UnderworldCerberus extends CardImpl { public UnderworldCerberus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{R}"); this.subtype.add(SubType.HOUND); this.power = new MageInt(6); @@ -64,10 +58,10 @@ public class UnderworldCerberus extends CardImpl { // Underworld Cerberus can't be blocked except by three or more creatures. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByOneEffect(3))); - + // Cards in graveyards can't be the targets of spells or abilities. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new UnderworldCerberusEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedCardsGraveyardsEffect())); + // When Underworld Cerberus dies, exile it and each player returns all creature cards from his or her graveyard to his or her hand. Ability ability = new DiesTriggeredAbility(new ExileSourceEffect()); ability.addEffect(new ReturnToHandFromGraveyardAllEffect(new FilterCreatureCard("creature cards"))); @@ -83,43 +77,3 @@ public class UnderworldCerberus extends CardImpl { return new UnderworldCerberus(this); } } - -class UnderworldCerberusEffect extends ContinuousRuleModifyingEffectImpl { - - public UnderworldCerberusEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Cards in graveyards can't be the targets of spells or abilities"; - } - - public UnderworldCerberusEffect(final UnderworldCerberusEffect effect) { - super(effect); - } - - @Override - public UnderworldCerberusEffect copy() { - return new UnderworldCerberusEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TARGET; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Card targetCard = game.getCard(event.getTargetId()); - StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); - if (targetCard != null && stackObject != null) { - Zone zone = game.getState().getZone(targetCard.getId()); - if (zone != null && zone == Zone.GRAVEYARD) { - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index 5f97eadcf3..72919af296 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -1,96 +1,102 @@ -/* -* 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; - -import mage.cards.ExpansionSet; -import mage.constants.Rarity; -import mage.constants.SetType; - -/** - * - * @author fireshoes - */ -public class RivalsOfIxalan extends ExpansionSet { - - private static final RivalsOfIxalan instance = new RivalsOfIxalan(); - - public static RivalsOfIxalan getInstance() { - return instance; - } - - private RivalsOfIxalan() { - super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION); - this.blockName = "Ixalan"; - this.parentSet = Ixalan.getInstance(); - this.hasBoosters = true; - this.hasBasicLands = false; - this.numBoosterLands = 1; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 8; - - cards.add(new SetCardInfo("Angrath's Ambusher", 202, Rarity.UNCOMMON, mage.cards.a.AngrathsAmbusher.class)); - cards.add(new SetCardInfo("Angrath's Fury", 204, Rarity.RARE, mage.cards.a.AngrathsFury.class)); - cards.add(new SetCardInfo("Angrath, Minotaur Pirate", 201, Rarity.MYTHIC, mage.cards.a.AngrathMinotaurPirate.class)); - cards.add(new SetCardInfo("Atzal, Cave of Eternity", 160, Rarity.RARE, mage.cards.a.AtzalCaveOfEternity.class)); - cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class)); - cards.add(new SetCardInfo("Captain's Hook", 177, Rarity.RARE, mage.cards.c.CaptainsHook.class)); - cards.add(new SetCardInfo("Cinder Barrens", 205, Rarity.RARE, mage.cards.c.CinderBarrens.class)); - cards.add(new SetCardInfo("Dusk Charger", 69, Rarity.COMMON, mage.cards.d.DuskCharger.class)); - cards.add(new SetCardInfo("Elenda, the Dusk Rose", 157, Rarity.MYTHIC, mage.cards.e.ElendaTheDuskRose.class)); - cards.add(new SetCardInfo("Evolving Wilds", 186, Rarity.RARE, mage.cards.e.EvolvingWilds.class)); - cards.add(new SetCardInfo("Forerunner of the Coalition", 72, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheCoalition.class)); - cards.add(new SetCardInfo("Forerunner of the Empire", 102, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheEmpire.class)); - cards.add(new SetCardInfo("Forerunner of the Heralds", 129, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheHeralds.class)); - cards.add(new SetCardInfo("Forerunner of the Legion", 9, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheLegion.class)); - cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); - cards.add(new SetCardInfo("Glorious Destiny", 18, Rarity.RARE, mage.cards.g.GloriousDestiny.class)); - cards.add(new SetCardInfo("Jadelight Ranger", 136, Rarity.RARE, mage.cards.j.JadelightRanger.class)); - cards.add(new SetCardInfo("Journey to Eternity", 160, Rarity.RARE, mage.cards.j.JourneyToEternity.class)); - cards.add(new SetCardInfo("Kumena's Awakening", 42, Rarity.RARE, mage.cards.k.KumenasAwakening.class)); - cards.add(new SetCardInfo("Kumena, Tyrant of Orazca", 162, Rarity.MYTHIC, mage.cards.k.KumenaTyrantOfOrazca.class)); - cards.add(new SetCardInfo("Legion Lieutenant", 163, Rarity.UNCOMMON, mage.cards.l.LegionLieutenant.class)); - cards.add(new SetCardInfo("Paladin of Atonement", 16, Rarity.RARE, mage.cards.p.PaladinOfAtonement.class)); - cards.add(new SetCardInfo("Seafloor Oracle", 51, Rarity.RARE, mage.cards.s.SeafloorOracle.class)); - cards.add(new SetCardInfo("Secrets of the Golden City", 52, Rarity.COMMON, mage.cards.s.SecretsOfTheGoldenCity.class)); - cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class)); - cards.add(new SetCardInfo("Skymarcher Aspirant", 21, Rarity.UNCOMMON, mage.cards.s.SkymarcherAspirant.class)); - cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class)); - cards.add(new SetCardInfo("Swab Goblin", 203, Rarity.COMMON, mage.cards.s.SwabGoblin.class)); - cards.add(new SetCardInfo("Tetzimoc, Primal Death", 86, Rarity.RARE, mage.cards.t.TetzimocPrimalDeath.class)); - cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class)); - cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class)); - cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class)); - cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class)); - cards.add(new SetCardInfo("Vraska's Conquistador", 199, Rarity.UNCOMMON, mage.cards.v.VraskasConquistador.class)); - cards.add(new SetCardInfo("Vraska's Scorn", 200, Rarity.RARE, mage.cards.v.VraskasScorn.class)); - cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class)); - cards.add(new SetCardInfo("Zetalpa, Primal Dawn", 30, Rarity.RARE, mage.cards.z.ZetalpaPrimalDawn.class)); - } -} +/* +* 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; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * + * @author fireshoes + */ +public class RivalsOfIxalan extends ExpansionSet { + + private static final RivalsOfIxalan instance = new RivalsOfIxalan(); + + public static RivalsOfIxalan getInstance() { + return instance; + } + + private RivalsOfIxalan() { + super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION); + this.blockName = "Ixalan"; + this.parentSet = Ixalan.getInstance(); + this.hasBoosters = true; + this.hasBasicLands = false; + this.numBoosterLands = 1; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + + cards.add(new SetCardInfo("Angrath's Ambusher", 202, Rarity.UNCOMMON, mage.cards.a.AngrathsAmbusher.class)); + cards.add(new SetCardInfo("Angrath's Fury", 204, Rarity.RARE, mage.cards.a.AngrathsFury.class)); + cards.add(new SetCardInfo("Angrath, Minotaur Pirate", 201, Rarity.MYTHIC, mage.cards.a.AngrathMinotaurPirate.class)); + cards.add(new SetCardInfo("Atzal, Cave of Eternity", 160, Rarity.RARE, mage.cards.a.AtzalCaveOfEternity.class)); + cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class)); + cards.add(new SetCardInfo("Buffling End", 1, Rarity.UNCOMMON, mage.cards.m.BafflingEnd.class)); + cards.add(new SetCardInfo("Captain's Hook", 177, Rarity.RARE, mage.cards.c.CaptainsHook.class)); + cards.add(new SetCardInfo("Cinder Barrens", 205, Rarity.RARE, mage.cards.c.CinderBarrens.class)); + cards.add(new SetCardInfo("Dusk Charger", 69, Rarity.COMMON, mage.cards.d.DuskCharger.class)); + cards.add(new SetCardInfo("Elenda, the Dusk Rose", 157, Rarity.MYTHIC, mage.cards.e.ElendaTheDuskRose.class)); + cards.add(new SetCardInfo("Evolving Wilds", 186, Rarity.RARE, mage.cards.e.EvolvingWilds.class)); + cards.add(new SetCardInfo("Forerunner of the Coalition", 72, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheCoalition.class)); + cards.add(new SetCardInfo("Forerunner of the Empire", 102, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheEmpire.class)); + cards.add(new SetCardInfo("Forerunner of the Heralds", 129, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheHeralds.class)); + cards.add(new SetCardInfo("Forerunner of the Legion", 9, Rarity.UNCOMMON, mage.cards.f.ForerunnerOfTheLegion.class)); + cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); + cards.add(new SetCardInfo("Glorious Destiny", 18, Rarity.RARE, mage.cards.g.GloriousDestiny.class)); + cards.add(new SetCardInfo("Jadelight Ranger", 136, Rarity.RARE, mage.cards.j.JadelightRanger.class)); + cards.add(new SetCardInfo("Journey to Eternity", 160, Rarity.RARE, mage.cards.j.JourneyToEternity.class)); + cards.add(new SetCardInfo("Kumena's Awakening", 42, Rarity.RARE, mage.cards.k.KumenasAwakening.class)); + cards.add(new SetCardInfo("Kumena, Tyrant of Orazca", 162, Rarity.MYTHIC, mage.cards.k.KumenaTyrantOfOrazca.class)); + cards.add(new SetCardInfo("Legion Lieutenant", 163, Rarity.UNCOMMON, mage.cards.l.LegionLieutenant.class)); + cards.add(new SetCardInfo("Merfolk Mistbinder", 164, Rarity.UNCOMMON, mage.cards.m.MerfolkMistbinder.class)); + cards.add(new SetCardInfo("Paladin of Atonement", 16, Rarity.RARE, mage.cards.p.PaladinOfAtonement.class)); + cards.add(new SetCardInfo("Path to Discovery", 142, Rarity.RARE, mage.cards.p.PathToDiscovery.class)); + cards.add(new SetCardInfo("Pirate's Pillage", 109, Rarity.UNCOMMON, mage.cards.p.PiratesPillage.class)); + cards.add(new SetCardInfo("Seafloor Oracle", 51, Rarity.RARE, mage.cards.s.SeafloorOracle.class)); + cards.add(new SetCardInfo("Secrets of the Golden City", 52, Rarity.COMMON, mage.cards.s.SecretsOfTheGoldenCity.class)); + cards.add(new SetCardInfo("Silent Gravestone", 182, Rarity.RARE, mage.cards.s.SilentGravestone.class)); + cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class)); + cards.add(new SetCardInfo("Skymarcher Aspirant", 21, Rarity.UNCOMMON, mage.cards.s.SkymarcherAspirant.class)); + cards.add(new SetCardInfo("Sphinx's Decree", 24, Rarity.RARE, mage.cards.s.SphinxsDecree.class)); + cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class)); + cards.add(new SetCardInfo("Swab Goblin", 203, Rarity.COMMON, mage.cards.s.SwabGoblin.class)); + cards.add(new SetCardInfo("Tetzimoc, Primal Death", 86, Rarity.RARE, mage.cards.t.TetzimocPrimalDeath.class)); + cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class)); + cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class)); + cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class)); + cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class)); + cards.add(new SetCardInfo("Vraska's Conquistador", 199, Rarity.UNCOMMON, mage.cards.v.VraskasConquistador.class)); + cards.add(new SetCardInfo("Vraska's Scorn", 200, Rarity.RARE, mage.cards.v.VraskasScorn.class)); + cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class)); + cards.add(new SetCardInfo("Zetalpa, Primal Dawn", 30, Rarity.RARE, mage.cards.z.ZetalpaPrimalDawn.class)); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedCardsGraveyardsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedCardsGraveyardsEffect.java new file mode 100644 index 0000000000..c7d6151057 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/CantBeTargetedCardsGraveyardsEffect.java @@ -0,0 +1,82 @@ +/* + * 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.ContinuousRuleModifyingEffectImpl; +import mage.cards.Card; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.StackObject; + +/** + * + * @author LevelX2 + */ +public class CantBeTargetedCardsGraveyardsEffect extends ContinuousRuleModifyingEffectImpl { + + public CantBeTargetedCardsGraveyardsEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Cards in graveyards can't be the targets of spells or abilities"; + } + + public CantBeTargetedCardsGraveyardsEffect(final CantBeTargetedCardsGraveyardsEffect effect) { + super(effect); + } + + @Override + public CantBeTargetedCardsGraveyardsEffect copy() { + return new CantBeTargetedCardsGraveyardsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TARGET; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Card targetCard = game.getCard(event.getTargetId()); + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); + if (targetCard != null && stackObject != null) { + Zone zone = game.getState().getZone(targetCard.getId()); + if (zone != null && zone == Zone.GRAVEYARD) { + return true; + } + } + return false; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java index a64c9aad8c..06030eb1a1 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java @@ -27,17 +27,15 @@ */ package mage.abilities.effects.keyword; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; -import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -49,15 +47,11 @@ import mage.players.Player; */ public class ExploreSourceEffect extends OneShotEffect { - private static final FilterCard filter = new FilterCard("a land card"); - - static { - filter.add(new CardTypePredicate(CardType.LAND)); - } + public static final String RULE_TEXT = "it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)"; public ExploreSourceEffect() { super(Outcome.Benefit); - this.staticText = "it explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.)"; + this.staticText = RULE_TEXT; } public ExploreSourceEffect(final ExploreSourceEffect effect) { @@ -71,35 +65,39 @@ public class ExploreSourceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(source.getSourceId()); - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + return explorePermanent(game, source.getSourceId(), source); + } + + public static boolean explorePermanent(Game game, UUID permanentId, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(permanentId); + if (permanent == null) { return false; } - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLORED, source.getSourceId(), source.getSourceId(), source.getControllerId())); - if (player.getLibrary().hasCards()) { - Card card = player.getLibrary().getFromTop(game); + Player permanentController = game.getPlayer(source.getControllerId()); + if (permanentController == null) { + return false; + } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLORED, permanentId, source.getSourceId(), permanent.getControllerId())); + if (permanentController.getLibrary().hasCards()) { + Card card = permanentController.getLibrary().getFromTop(game); Cards cards = new CardsImpl(); cards.add(card); - player.revealCards("Explored card", cards, game); + permanentController.revealCards("Explored card", cards, game); if (card != null) { - if (filter.match(card, game)) { + if (card.isLand()) { card.moveToZone(Zone.HAND, source.getSourceId(), game, true); } else { - if (creature != null) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); - } - if (player.chooseUse(Outcome.Neutral, "Put " + card.getLogName() + " in your graveyard?", source, game)) { + permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + if (permanentController.chooseUse(Outcome.Neutral, "Put " + card.getLogName() + " in your graveyard?", source, game)) { card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); - game.informPlayers(player.getLogName() + " puts " + card.getLogName() + " into their graveyard."); + game.informPlayers(permanentController.getLogName() + " puts " + card.getLogName() + " into their graveyard."); } else { - game.informPlayers(player.getLogName() + " leaves " + card.getLogName() + " on top of their library."); + game.informPlayers(permanentController.getLogName() + " leaves " + card.getLogName() + " on top of their library."); } } } - return true; } - return false; + return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreTargetEffect.java new file mode 100644 index 0000000000..8c204656f9 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreTargetEffect.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.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; + +/** + * + * @author LevelX2 + */ +public class ExploreTargetEffect extends OneShotEffect { + + public ExploreTargetEffect() { + super(Outcome.Benefit); + this.staticText = ExploreSourceEffect.RULE_TEXT; + } + + public ExploreTargetEffect(final ExploreTargetEffect effect) { + super(effect); + } + + @Override + public ExploreTargetEffect copy() { + return new ExploreTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return ExploreSourceEffect.explorePermanent(game, getTargetPointer().getFirst(game, source), source); + } + +}