From 64524a8c18880320a7063aa21eb3d9095fd1aec4 Mon Sep 17 00:00:00 2001 From: spjspj <spjspj4@gmail.com> Date: Mon, 26 Jun 2017 23:13:48 +1000 Subject: [PATCH] Implement The Scarab God (HOU) --- Mage.Sets/src/mage/cards/t/TheScarabGod.java | 202 ++++++++++++++++++ .../src/mage/sets/HourOfDevastation.java | 1 + ...tTokenOntoBattlefieldCopyTargetEffect.java | 22 ++ 3 files changed, 225 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TheScarabGod.java diff --git a/Mage.Sets/src/mage/cards/t/TheScarabGod.java b/Mage.Sets/src/mage/cards/t/TheScarabGod.java new file mode 100644 index 0000000000..f5f4709218 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheScarabGod.java @@ -0,0 +1,202 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextUpkeepDelayedTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +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.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author spjspj + */ +public class TheScarabGod extends CardImpl { + + public TheScarabGod(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("God"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // At the beginning of your upkeep, each opponent loses X life and you scry X, where X is the number of Zombies you control. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TheScarabGodEffect(), TargetController.YOU, false)); + + // {2}{U}{B}: Exile target creature card from a graveyard. Create a token that's a copy of it, except it's a 4/4 black Zombie. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TheScarabGodEffect2(), new ManaCostsImpl("{2}{U}{B}")); + ability.addTarget(new TargetCardInGraveyard(1, 1, new FilterCreatureCard("creature card from a graveyard"))); + this.addAbility(ability); + + // When The Scarab God dies, return it to its owner's hand at the beginning of the next upkeep. + this.addAbility(new DiesTriggeredAbility(new TheScarabGodEffect3())); + } + + public TheScarabGod(final TheScarabGod card) { + super(card); + } + + @Override + public TheScarabGod copy() { + return new TheScarabGod(this); + } +} + +class TheScarabGodEffect extends OneShotEffect { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped Zombies you control"); + + static { + filter.add(new SubtypePredicate(SubType.ZOMBIE)); + } + + public TheScarabGodEffect() { + super(Outcome.Benefit); + staticText = "each opponent loses X life and you scry X, where X is the number of Zombies you control"; + } + + public TheScarabGodEffect(final TheScarabGodEffect effect) { + super(effect); + } + + @Override + public TheScarabGodEffect copy() { + return new TheScarabGodEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int numZombies = game.getBattlefield().countAll(filter, source.getControllerId(), game); + + if (numZombies > 0) { + for (UUID playerId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(playerId); + if (opponent != null) { + opponent.loseLife(numZombies, game, false); + } + } + controller.scry(numZombies, source, game); + } + + return true; + } + return false; + } +} + +class TheScarabGodEffect2 extends OneShotEffect { + + public TheScarabGodEffect2() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Exile target creature card from a graveyard. Create a token that's a copy of it, except it's a 4/4 black Zombie."; + } + + public TheScarabGodEffect2(final TheScarabGodEffect2 effect) { + super(effect); + } + + @Override + public TheScarabGodEffect2 copy() { + return new TheScarabGodEffect2(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && card != null) { + controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place + PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, 1, false, false, null, 4, 4, false); + effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); + effect.setOnlySubType("Zombie"); + effect.setOnlyColor(ObjectColor.BLACK); + effect.apply(game, source); + return true; + } + + return false; + } +} + +class TheScarabGodEffect3 extends OneShotEffect { + + private static final String effectText = "return it to its owner's hand at the beginning of the next upkeep."; + + TheScarabGodEffect3() { + super(Outcome.Benefit); + staticText = effectText; + } + + TheScarabGodEffect3(TheScarabGodEffect3 effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + // Create delayed triggered ability + Effect effect = new ReturnToHandSourceEffect(false, true); + effect.setText(staticText); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextUpkeepDelayedTriggeredAbility(effect); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } + + @Override + public TheScarabGodEffect3 copy() { + return new TheScarabGodEffect3(this); + } +} diff --git a/Mage.Sets/src/mage/sets/HourOfDevastation.java b/Mage.Sets/src/mage/sets/HourOfDevastation.java index f90f254acf..23b71fe343 100644 --- a/Mage.Sets/src/mage/sets/HourOfDevastation.java +++ b/Mage.Sets/src/mage/sets/HourOfDevastation.java @@ -95,6 +95,7 @@ public class HourOfDevastation extends ExpansionSet { cards.add(new SetCardInfo("Solemnity", 22, Rarity.RARE, mage.cards.s.Solemnity.class)); cards.add(new SetCardInfo("Steadfast Sentinel", 24, Rarity.COMMON, mage.cards.s.SteadfastSentinel.class)); cards.add(new SetCardInfo("Supreme Will", 49, Rarity.UNCOMMON, mage.cards.s.SupremeWill.class)); + cards.add(new SetCardInfo("The Scarab God", 145, Rarity.MYTHIC, mage.cards.t.TheScarabGod.class)); cards.add(new SetCardInfo("The Scorpion God", 146, Rarity.MYTHIC, mage.cards.t.TheScorpionGod.class)); cards.add(new SetCardInfo("Torment of Hailfire", 77, Rarity.RARE, mage.cards.t.TormentOfHailfire.class)); cards.add(new SetCardInfo("Torment of Scarabs", 78, Rarity.UNCOMMON, mage.cards.t.TormentOfScarabs.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java index 55c1abcb2b..1e5b785bc3 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import mage.MageObject; +import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.Effect; @@ -60,6 +61,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { private final int number; private List<Permanent> addedTokenPermanents; private String additionalSubType; + private String onlySubType; private boolean tapped; private boolean attacking; private UUID attackedPlayer; @@ -67,6 +69,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { private final int tokenToughness; private boolean gainsFlying; private boolean becomesArtifact; + private ObjectColor color; public PutTokenOntoBattlefieldCopyTargetEffect() { super(Outcome.PutCreatureInPlay); @@ -75,11 +78,13 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.addedTokenPermanents = new ArrayList<>(); this.number = 1; this.additionalSubType = null; + this.onlySubType = null; this.attackedPlayer = null; this.tokenPower = Integer.MIN_VALUE; this.tokenToughness = Integer.MIN_VALUE; this.gainsFlying = false; this.becomesArtifact = false; + this.color = null; } public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId) { @@ -135,6 +140,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.addedTokenPermanents = new ArrayList<>(effect.addedTokenPermanents); this.number = effect.number; this.additionalSubType = effect.additionalSubType; + this.onlySubType = effect.onlySubType; this.tapped = effect.tapped; this.attacking = effect.attacking; this.attackedPlayer = effect.attackedPlayer; @@ -142,6 +148,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.tokenToughness = effect.tokenToughness; this.gainsFlying = effect.gainsFlying; this.becomesArtifact = effect.becomesArtifact; + this.color = effect.color; } public void setBecomesArtifact(boolean becomesArtifact) { @@ -210,6 +217,13 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { if (additionalSubType != null && !token.getSubtype(game).contains(additionalSubType)) { token.getSubtype(game).add(additionalSubType); } + if (onlySubType != null && !token.getSubtype(game).contains(onlySubType)) { + token.getSubtype(game).clear(); + token.getSubtype(game).add(onlySubType); + } + if (color != null) { + token.getColor(game).setColor(color); + } token.putOntoBattlefield(number, game, source.getSourceId(), playerId == null ? source.getControllerId() : playerId, tapped, attacking, attackedPlayer); for (UUID tokenId : token.getLastAddedTokenIds()) { // by cards like Doubling Season multiple tokens can be added to the battlefield @@ -261,4 +275,12 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { public void setAdditionalSubType(String additionalSubType) { this.additionalSubType = additionalSubType; } + + public void setOnlySubType(String onlySubType) { + this.onlySubType = onlySubType; + } + + public void setOnlyColor(ObjectColor color) { + this.color = color; + } }