Implement Four Cards for M21 (#6651)

* Implement Four Cards for M21

Sanctum of Calm Waters
Sanctum of Shattered Heights
Transmogrify
Watcher of the Spheres

* Implement Sanctum of Calm Waters

* Implement Sanctum of Shattered Heights

* Implement Transmogrify

* Implement Watcher of the Spheres

* Add ability text and minimize number of lines

* Add ability text

* Clean up a few lines of code

* Update SanctumOfCalmWaters.java

* Update SanctumOfShatteredHeights.java

Co-authored-by: Evan Kranzler <theelk801@gmail.com>
This commit is contained in:
jmharmon 2020-06-17 15:34:17 -07:00 committed by GitHub
parent 7b3686e418
commit 327062240f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 262 additions and 0 deletions

View file

@ -0,0 +1,46 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfPreCombatMainTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import java.util.UUID;
/**
* @author jmharmon
*/
public final class SanctumOfCalmWaters extends CardImpl {
public SanctumOfCalmWaters(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SHRINE);
// At the beginning of your precombat main phase, you may draw X cards, where X is the number of Shrines you control. If you do, discard a card.
Ability ability = new BeginningOfPreCombatMainTriggeredAbility(new DrawCardSourceControllerEffect(new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE)))
.setText("At the beginning of your precombat main phase, you may draw X cards, where X is the number of Shrines you control"),
TargetController.YOU, true);
ability.addEffect(new DiscardControllerEffect(1).setText("If you do, discard a card"));
this.addAbility(ability);
}
public SanctumOfCalmWaters(final SanctumOfCalmWaters card) {
super(card);
}
@Override
public SanctumOfCalmWaters copy() {
return new SanctumOfCalmWaters(this);
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
* @author jmharmon
*/
public final class SanctumOfShatteredHeights extends CardImpl {
private static final FilterCard filter = new FilterCard("a land card or Shrine card");
static {
filter.add(Predicates.or(CardType.LAND.getPredicate(), SubType.SHRINE.getPredicate()));
}
public SanctumOfShatteredHeights(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SHRINE);
// {1}, Discard a land card or Shrine card: Sanctum of Shattered Heights deals X damage to target creature or planeswalker, where X is the number of Shrines you control.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.SHRINE)))
.setText("Sanctum of Shattered Heights deals X damage to target creature or planeswalker, where X is the number of Shrines you control"),
new ManaCostsImpl("{1}"));
ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter)));
this.addAbility(ability);
}
public SanctumOfShatteredHeights(final SanctumOfShatteredHeights card) {
super(card);
}
@Override
public SanctumOfShatteredHeights copy() {
return new SanctumOfShatteredHeights(this);
}
}

View file

@ -0,0 +1,92 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Library;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author jmharmon
*/
public final class Transmogrify extends CardImpl {
public Transmogrify(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}");
// Exile target creature.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new ExileTargetEffect());
// That creatures controller reveals cards from the top of their library until they reveal a creature card.
// That player puts that card onto the battlefield, then shuffles the rest into their library.
this.getSpellAbility().addEffect(new TransmogrifyEffect());
}
public Transmogrify(final Transmogrify card) {
super(card);
}
@Override
public Transmogrify copy() {
return new Transmogrify(this);
}
}
class TransmogrifyEffect extends OneShotEffect {
public TransmogrifyEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "That creatures controller reveals cards from the top of their library until they reveal a creature card. That player puts that card onto the battlefield, then shuffles the rest into their library";
}
public TransmogrifyEffect(final TransmogrifyEffect effect) {
super(effect);
}
@Override
public TransmogrifyEffect copy() {
return new TransmogrifyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
if (permanent != null) {
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
Library library = player.getLibrary();
if (library.hasCards()) {
Cards cards = new CardsImpl();
Card toBattlefield = null;
for (Card card : library.getCards(game)) {
cards.add(card);
if (card.isCreature()) {
toBattlefield = card;
break;
}
}
if (toBattlefield != null) {
player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game);
}
player.revealCards(source, cards, game);
cards.remove(toBattlefield);
if (!cards.isEmpty()) {
player.shuffleLibrary(source, game);
}
}
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,64 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import java.util.UUID;
/**
* @author jmharmon
*/
public final class WatcherOfTheSpheres extends CardImpl {
private static final FilterCreatureCard filter = new FilterCreatureCard("Creature spells with flying");
private static final FilterPermanent filter1 = new FilterControlledCreaturePermanent("another creature with flying");
static {
filter.add(new AbilityPredicate(FlyingAbility.class));
filter1.add(AnotherPredicate.instance);
filter1.add(new AbilityPredicate(FlyingAbility.class));
}
public WatcherOfTheSpheres(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{B}");
this.subtype.add(SubType.BIRD);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Creature spells with flying you cast cost {1} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1)));
// Whenever another creature with flying enters the battlefield under your control, Watcher of the Spheres gets +1/+1 until end of turn.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), filter1, false));
}
public WatcherOfTheSpheres(final WatcherOfTheSpheres card) {
super(card);
}
@Override
public WatcherOfTheSpheres copy() {
return new WatcherOfTheSpheres(this);
}
}

View file

@ -206,6 +206,8 @@ public final class CoreSet2021 extends ExpansionSet {
cards.add(new SetCardInfo("Rugged Highlands", 249, Rarity.COMMON, mage.cards.r.RuggedHighlands.class)); cards.add(new SetCardInfo("Rugged Highlands", 249, Rarity.COMMON, mage.cards.r.RuggedHighlands.class));
cards.add(new SetCardInfo("Runed Halo", 32, Rarity.RARE, mage.cards.r.RunedHalo.class)); cards.add(new SetCardInfo("Runed Halo", 32, Rarity.RARE, mage.cards.r.RunedHalo.class));
cards.add(new SetCardInfo("Sabertooth Mauler", 202, Rarity.COMMON, mage.cards.s.SabertoothMauler.class)); cards.add(new SetCardInfo("Sabertooth Mauler", 202, Rarity.COMMON, mage.cards.s.SabertoothMauler.class));
cards.add(new SetCardInfo("Sanctum of Calm Waters", 68, Rarity.UNCOMMON, mage.cards.s.SanctumOfCalmWaters.class));
cards.add(new SetCardInfo("Sanctum of Shattered Heights", 157, Rarity.UNCOMMON, mage.cards.s.SanctumOfShatteredHeights.class));
cards.add(new SetCardInfo("Scavenging Ooze", 204, Rarity.RARE, mage.cards.s.ScavengingOoze.class)); cards.add(new SetCardInfo("Scavenging Ooze", 204, Rarity.RARE, mage.cards.s.ScavengingOoze.class));
cards.add(new SetCardInfo("Scorching Dragonfire", 158, Rarity.COMMON, mage.cards.s.ScorchingDragonfire.class)); cards.add(new SetCardInfo("Scorching Dragonfire", 158, Rarity.COMMON, mage.cards.s.ScorchingDragonfire.class));
cards.add(new SetCardInfo("Scoured Barrens", 250, Rarity.COMMON, mage.cards.s.ScouredBarrens.class)); cards.add(new SetCardInfo("Scoured Barrens", 250, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
@ -262,6 +264,7 @@ public final class CoreSet2021 extends ExpansionSet {
cards.add(new SetCardInfo("Tolarian Kraken", 80, Rarity.UNCOMMON, mage.cards.t.TolarianKraken.class)); cards.add(new SetCardInfo("Tolarian Kraken", 80, Rarity.UNCOMMON, mage.cards.t.TolarianKraken.class));
cards.add(new SetCardInfo("Tormod's Crypt", 241, Rarity.UNCOMMON, mage.cards.t.TormodsCrypt.class)); cards.add(new SetCardInfo("Tormod's Crypt", 241, Rarity.UNCOMMON, mage.cards.t.TormodsCrypt.class));
cards.add(new SetCardInfo("Traitorous Greed", 166, Rarity.UNCOMMON, mage.cards.t.TraitorousGreed.class)); cards.add(new SetCardInfo("Traitorous Greed", 166, Rarity.UNCOMMON, mage.cards.t.TraitorousGreed.class));
cards.add(new SetCardInfo("Transmogrify", 167, Rarity.RARE, mage.cards.t.Transmogrify.class));
cards.add(new SetCardInfo("Tranquil Cove", 258, Rarity.COMMON, mage.cards.t.TranquilCove.class)); cards.add(new SetCardInfo("Tranquil Cove", 258, Rarity.COMMON, mage.cards.t.TranquilCove.class));
cards.add(new SetCardInfo("Trufflesnout", 212, Rarity.COMMON, mage.cards.t.Trufflesnout.class)); cards.add(new SetCardInfo("Trufflesnout", 212, Rarity.COMMON, mage.cards.t.Trufflesnout.class));
cards.add(new SetCardInfo("Turn to Slag", 168, Rarity.COMMON, mage.cards.t.TurnToSlag.class)); cards.add(new SetCardInfo("Turn to Slag", 168, Rarity.COMMON, mage.cards.t.TurnToSlag.class));
@ -282,6 +285,7 @@ public final class CoreSet2021 extends ExpansionSet {
cards.add(new SetCardInfo("Wall of Runes", 85, Rarity.COMMON, mage.cards.w.WallOfRunes.class)); cards.add(new SetCardInfo("Wall of Runes", 85, Rarity.COMMON, mage.cards.w.WallOfRunes.class));
cards.add(new SetCardInfo("Warded Battlements", 44, Rarity.COMMON, mage.cards.w.WardedBattlements.class)); cards.add(new SetCardInfo("Warded Battlements", 44, Rarity.COMMON, mage.cards.w.WardedBattlements.class));
cards.add(new SetCardInfo("Warden of the Woods", 213, Rarity.UNCOMMON, mage.cards.w.WardenOfTheWoods.class)); cards.add(new SetCardInfo("Warden of the Woods", 213, Rarity.UNCOMMON, mage.cards.w.WardenOfTheWoods.class));
cards.add(new SetCardInfo("Watcher of the Spheres", 227, Rarity.UNCOMMON, mage.cards.w.WatcherOfTheSpheres.class));
cards.add(new SetCardInfo("Wildwood Patrol", 339, Rarity.COMMON, mage.cards.w.WildwoodPatrol.class)); cards.add(new SetCardInfo("Wildwood Patrol", 339, Rarity.COMMON, mage.cards.w.WildwoodPatrol.class));
cards.add(new SetCardInfo("Wildwood Scourge", 214, Rarity.UNCOMMON, mage.cards.w.WildwoodScourge.class)); cards.add(new SetCardInfo("Wildwood Scourge", 214, Rarity.UNCOMMON, mage.cards.w.WildwoodScourge.class));
cards.add(new SetCardInfo("Wind-Scarred Crag", 259, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 259, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));