diff --git a/Mage.Sets/src/mage/cards/r/RedemptorDreadnought.java b/Mage.Sets/src/mage/cards/r/RedemptorDreadnought.java new file mode 100644 index 00000000000..ca611d5c44e --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RedemptorDreadnought.java @@ -0,0 +1,107 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; + +import java.util.Objects; +import java.util.UUID; + +/** + * @author xenohedron + */ +public final class RedemptorDreadnought extends CardImpl { + + public RedemptorDreadnought(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); + + this.subtype.add(SubType.ASTARTES); + this.subtype.add(SubType.DREADNOUGHT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Fallen Warrior -- As an additional cost to cast this spell, you may exile a creature card from your graveyard. + this.getSpellAbility().addCost(new ExileFromGraveCost( + new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD) + ).setText("")); + + this.addAbility(new SimpleStaticAbility(new InfoEffect("as an additional cost to cast this spell, you may exile a creature card from your graveyard")) + .setRuleAtTheTop(true).withFlavorWord("Fallen Warrior")); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Plasma Incinerator -- Whenever Redemptor Dreadnought attacks, if a card is exiled with it, it gets +X/+X until end of turn, where X is the power of the exiled card. + this.addAbility(new AttacksTriggeredAbility(new RedemptorDreadnoughtEffect()).withFlavorWord("Plasma Incinerator")); + + } + + private RedemptorDreadnought(final RedemptorDreadnought card) { + super(card); + } + + @Override + public RedemptorDreadnought copy() { + return new RedemptorDreadnought(this); + } +} + +class RedemptorDreadnoughtEffect extends OneShotEffect { + + RedemptorDreadnoughtEffect() { + super(Outcome.BoostCreature); + staticText = "if a card is exiled with it, it gets +X/+X until end of turn, where X is the power of the exiled card"; + } + + private RedemptorDreadnoughtEffect(final RedemptorDreadnoughtEffect effect) { + super(effect); + } + + @Override + public RedemptorDreadnoughtEffect copy() { + return new RedemptorDreadnoughtEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent == null) { + return false; + } + ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source, -1)); + if (exile == null || exile.isEmpty()) { + return false; + } + int xValue = exile.getCards(game) + .stream() + .filter(Objects::nonNull) + .map(MageObject::getPower) + .mapToInt(MageInt::getValue) + .sum(); + if (xValue > 0) { + game.addEffect(new BoostSourceEffect(xValue, xValue, Duration.EndOfTurn), source); + } + return true; + } + + +} diff --git a/Mage.Sets/src/mage/sets/Warhammer40000.java b/Mage.Sets/src/mage/sets/Warhammer40000.java index f8a686a54f5..b08d1cf8c48 100644 --- a/Mage.Sets/src/mage/sets/Warhammer40000.java +++ b/Mage.Sets/src/mage/sets/Warhammer40000.java @@ -212,6 +212,7 @@ public final class Warhammer40000 extends ExpansionSet { cards.add(new SetCardInfo("Ravener", 138, Rarity.RARE, mage.cards.r.Ravener.class)); cards.add(new SetCardInfo("Reaver Titan", 163, Rarity.RARE, mage.cards.r.ReaverTitan.class)); cards.add(new SetCardInfo("Reconnaissance Mission", 193, Rarity.UNCOMMON, mage.cards.r.ReconnaissanceMission.class)); + cards.add(new SetCardInfo("Redemptor Dreadnought", 164, Rarity.RARE, mage.cards.r.RedemptorDreadnought.class)); cards.add(new SetCardInfo("Reliquary Tower", 291, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.class)); cards.add(new SetCardInfo("Resurrection Orb", 165, Rarity.RARE, mage.cards.r.ResurrectionOrb.class)); cards.add(new SetCardInfo("Reverberate", 207, Rarity.RARE, mage.cards.r.Reverberate.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/_40k/RedemptorDreadnoughtTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/_40k/RedemptorDreadnoughtTest.java new file mode 100644 index 00000000000..f74f3bfa4e8 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/_40k/RedemptorDreadnoughtTest.java @@ -0,0 +1,55 @@ +package org.mage.test.cards.single._40k; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.player.TestPlayer; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class RedemptorDreadnoughtTest extends CardTestPlayerBase { + + private static final String redemptor = "Redemptor Dreadnought"; // {5} Artifact Creature 4/4 + // As an additional cost to cast this spell, you may exile a creature card from your graveyard. + // Trample + // Whenever Redemptor Dreadnought attacks, if a card is exiled with it, it gets +X/+X until end of turn, where X is the power of the exiled card. + + private static final String ghoul = "Warpath Ghoul"; // 3/2 + + @Test + public void testCastNoAdditionalCost() { + addCard(Zone.HAND, playerA, redemptor, 1); + addCard(Zone.GRAVEYARD, playerA, ghoul, 1); + addCard(Zone.BATTLEFIELD, playerA, "Wastes", 5); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, redemptor); + setChoice(playerA, TestPlayer.CHOICE_SKIP); // choose not to exile anything + + setStopAt(1, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertGraveyardCount(playerA, ghoul, 1); + assertPowerToughness(playerA, redemptor, 4, 4); + } + + @Test + public void testCastAdditionalCostAndTrigger() { + addCard(Zone.HAND, playerA, redemptor, 1); + addCard(Zone.GRAVEYARD, playerA, ghoul, 1); + addCard(Zone.BATTLEFIELD, playerA, "Wastes", 5); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, redemptor); + setChoice(playerA, ghoul); // exile Warpath Ghoul + + attack(3, playerA, redemptor, playerB); + + setStopAt(3, PhaseStep.END_TURN); + setStrictChooseMode(true); + execute(); + + assertExileCount(playerA, ghoul, 1); + assertPowerToughness(playerA, redemptor, 7, 7); + } + + +}