diff --git a/Mage.Sets/src/mage/cards/e/EllieAndAlanPaleontologists.java b/Mage.Sets/src/mage/cards/e/EllieAndAlanPaleontologists.java new file mode 100644 index 00000000000..c7f72c0cd03 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EllieAndAlanPaleontologists.java @@ -0,0 +1,80 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.DiscoverEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class EllieAndAlanPaleontologists extends CardImpl { + + public EllieAndAlanPaleontologists(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}{U}"); + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCIENTIST); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // {T}, Exile a creature card from your graveyard: Discover X, where X is the mana value of the exiled card. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(new EllieAndAlanDiscoverEffect(), new TapSourceCost()); + ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD), true)); + this.addAbility(ability); + } + + private EllieAndAlanPaleontologists(final EllieAndAlanPaleontologists card) { + super(card); + } + + @Override + public EllieAndAlanPaleontologists copy() { + return new EllieAndAlanPaleontologists(this); + } +} + +class EllieAndAlanDiscoverEffect extends OneShotEffect { + + EllieAndAlanDiscoverEffect() { + super(Outcome.Benefit); + staticText = "discover X, where X is the mana value of the exiled card"; + } + + private EllieAndAlanDiscoverEffect(final EllieAndAlanDiscoverEffect effect) { + super(effect); + } + + @Override + public EllieAndAlanDiscoverEffect copy() { + return new EllieAndAlanDiscoverEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + Player player = game.getPlayer(source.getControllerId()); + if (player == null || card == null) { + return false; + } + DiscoverEffect.doDiscover(player, card.getManaValue(), game, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/l/LifeFindsAWay.java b/Mage.Sets/src/mage/cards/l/LifeFindsAWay.java new file mode 100644 index 00000000000..53940d13cfd --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LifeFindsAWay.java @@ -0,0 +1,44 @@ +package mage.cards.l; + +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.common.PopulateEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.permanent.TokenPredicate; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class LifeFindsAWay extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("nontoken creature with power 4 or greater"); + + static { + filter.add(TokenPredicate.FALSE); + filter.add(new PowerPredicate(ComparisonType.OR_GREATER, 4)); + } + + public LifeFindsAWay(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + + // Whenever a nontoken creature with power 4 or greater enters the battlefield under your control, populate. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new PopulateEffect(), filter)); + } + + private LifeFindsAWay(final LifeFindsAWay card) { + super(card); + } + + @Override + public LifeFindsAWay copy() { + return new LifeFindsAWay(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RavenousTyrannosaurus.java b/Mage.Sets/src/mage/cards/r/RavenousTyrannosaurus.java new file mode 100644 index 00000000000..9062fc841ca --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavenousTyrannosaurus.java @@ -0,0 +1,54 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.common.DamageWithExcessEffect; +import mage.abilities.keyword.DevourAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class RavenousTyrannosaurus extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other target creature"); + + static { + filter.add(AnotherPredicate.instance); + } + public RavenousTyrannosaurus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Devour 3 + this.addAbility(new DevourAbility(3)); + + // Whenever Ravenous Tyrannosaurus attacks, it deals damage equal to its power to up to one other target creature. Excess damage is dealt to that creature's controller instead. + Ability ability = new AttacksTriggeredAbility(new DamageWithExcessEffect(new SourcePermanentPowerCount(false)) + .setText("it deals damage equal to its power to up to one other target creature. Excess damage is dealt to that creature's controller instead.")); + ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false)); + this.addAbility(ability); + } + + private RavenousTyrannosaurus(final RavenousTyrannosaurus card) { + super(card); + } + + @Override + public RavenousTyrannosaurus copy() { + return new RavenousTyrannosaurus(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SavageOrder.java b/Mage.Sets/src/mage/cards/s/SavageOrder.java new file mode 100644 index 00000000000..533a1b6d964 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SavageOrder.java @@ -0,0 +1,109 @@ +package mage.cards.s; + +import java.util.UUID; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.SearchEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; +import mage.target.targetpointer.FixedTarget; +import mage.util.SubTypes; + +/** + * + * @author notgreat + */ +public final class SavageOrder extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature with power 4 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.OR_GREATER, 4)); + } + public SavageOrder(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}{G}"); + + // As an additional cost to cast this spell, sacrifice a creature with power 4 or greater. + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); + // Search your library for a Dinosaur creature card, put it onto the battlefield, then shuffle. It gains indestructible until your next turn. + this.getSpellAbility().addEffect(new SavageOrderEffect()); + } + + private SavageOrder(final SavageOrder card) { + super(card); + } + + @Override + public SavageOrder copy() { + return new SavageOrder(this); + } +} +//Based on Nahiri, the Harbinger +class SavageOrderEffect extends SearchEffect { + private static final FilterCreatureCard filterCard = new FilterCreatureCard("Dinosaur creature card"); + + static { + filterCard.add(SubType.DINOSAUR.getPredicate()); + } + + SavageOrderEffect() { + super(new TargetCardInLibrary(0, 1, filterCard), Outcome.PutCardInPlay); + this.staticText = "Search your library for a Dinosaur creature card, put it onto the battlefield, then shuffle. It gains indestructible until your next turn"; + } + + private SavageOrderEffect(final SavageOrderEffect effect) { + super(effect); + } + + @Override + public SavageOrderEffect copy() { + return new SavageOrderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.searchLibrary(target, source, game)) { + if (!target.getTargets().isEmpty()) { + Card card = controller.getLibrary().getCard(target.getFirstTarget(), game); + if (card != null) { + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ContinuousEffect effect = new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game))); + game.addEffect(effect, source); + } + } + } + controller.shuffleLibrary(source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpittingDilophosaurus.java b/Mage.Sets/src/mage/cards/s/SpittingDilophosaurus.java new file mode 100644 index 00000000000..fc593a2191a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpittingDilophosaurus.java @@ -0,0 +1,81 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class SpittingDilophosaurus extends CardImpl { + + public SpittingDilophosaurus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.DINOSAUR); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Spitting Dilophosaurus enters the battlefield or attacks, put a -1/-1 counter on up to one target creature. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance())); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + // Creatures your opponents control with -1/-1 counters on them can't block. + this.addAbility(new SimpleStaticAbility(new SpittingDilophosaurusRestrictionEffect())); + } + + private SpittingDilophosaurus(final SpittingDilophosaurus card) { + super(card); + } + + @Override + public SpittingDilophosaurus copy() { + return new SpittingDilophosaurus(this); + } +} +//Based on Kulrath Knight/UnleashAbility +class SpittingDilophosaurusRestrictionEffect extends RestrictionEffect { + + public SpittingDilophosaurusRestrictionEffect() { + super(Duration.WhileOnBattlefield); + staticText = "Creatures your opponents control with -1/-1 counters on them can't block."; + } + + private SpittingDilophosaurusRestrictionEffect(final SpittingDilophosaurusRestrictionEffect effect) { + super(effect); + } + + @Override + public SpittingDilophosaurusRestrictionEffect copy() { + return new SpittingDilophosaurusRestrictionEffect(this); + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { + return false; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null && permanent != null && game.isOpponent(player, permanent.getControllerId())) { + return permanent.getCounters(game).getCount(CounterType.M1M1) > 0; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java index 54956c8de10..85cc160e9c2 100644 --- a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java +++ b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java @@ -23,17 +23,22 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Command Tower", 26, Rarity.COMMON, mage.cards.c.CommandTower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Command Tower", "26b", Rarity.COMMON, mage.cards.c.CommandTower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Don't Move", 1, Rarity.RARE, mage.cards.d.DontMove.class)); + cards.add(new SetCardInfo("Ellie and Alan, Paleontologists", 10, Rarity.RARE, mage.cards.e.EllieAndAlanPaleontologists.class)); cards.add(new SetCardInfo("Forest", 25, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Forest", "25b", Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Hunting Velociraptor", 4, Rarity.RARE, mage.cards.h.HuntingVelociraptor.class)); cards.add(new SetCardInfo("Island", 22, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", "22b", Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Jurassic Park", 7, Rarity.RARE, mage.cards.j.JurassicPark.class)); + cards.add(new SetCardInfo("Life Finds a Way", 5, Rarity.RARE, mage.cards.l.LifeFindsAWay.class)); cards.add(new SetCardInfo("Mountain", 24, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", "24b", Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Permission Denied", 17, Rarity.RARE, mage.cards.p.PermissionDenied.class)); cards.add(new SetCardInfo("Plains", 21, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", "21b", Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Ravenous Tyrannosaurus", 18, Rarity.RARE, mage.cards.r.RavenousTyrannosaurus.class)); + cards.add(new SetCardInfo("Savage Order", 6, Rarity.RARE, mage.cards.s.SavageOrder.class)); + cards.add(new SetCardInfo("Spitting Dilophosaurus", 3, Rarity.RARE, mage.cards.s.SpittingDilophosaurus.class)); cards.add(new SetCardInfo("Swamp", 23, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Swamp", "23b", Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Welcome to . . .", 7, Rarity.RARE, mage.cards.w.WelcomeTo.class));