From 2daf1945e79988d5804f11f4a1096f0469b7c400 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 27 Feb 2021 15:35:04 -0500 Subject: [PATCH] [RTR] reworked Nivmagus Elemental and added test --- .../src/mage/cards/n/NivmagusElemental.java | 86 ++++++++++++++----- .../single/rtr/NivmagusElementalTest.java | 59 +++++++++++++ .../costs/common/ExileFromStackCost.java | 63 -------------- 3 files changed, 124 insertions(+), 84 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/rtr/NivmagusElementalTest.java delete mode 100644 Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java diff --git a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java index 226bf4d82c..daf54a843c 100644 --- a/Mage.Sets/src/mage/cards/n/NivmagusElemental.java +++ b/Mage.Sets/src/mage/cards/n/NivmagusElemental.java @@ -1,38 +1,29 @@ - package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.ExileFromStackCost; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterSpell; -import mage.filter.predicate.Predicates; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.game.Game; +import mage.game.stack.Spell; +import mage.players.Player; import mage.target.TargetSpell; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class NivmagusElemental extends CardImpl { - private static final FilterSpell filter = new FilterSpell("an instant or sorcery spell you control"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - filter.add(Predicates.or( - CardType.INSTANT.getPredicate(), - CardType.SORCERY.getPredicate())); - } - public NivmagusElemental(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/R}"); this.subtype.add(SubType.ELEMENTAL); @@ -41,9 +32,9 @@ public final class NivmagusElemental extends CardImpl { this.toughness = new MageInt(2); // Exile an instant or sorcery spell you control: Put two +1/+1 counters on Nivmagus Elemental. (That spell won't resolve.) - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ExileFromStackCost(new TargetSpell(filter))); - this.addAbility(ability); - + this.addAbility(new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new NivmagusElementalCost() + )); } private NivmagusElemental(final NivmagusElemental card) { @@ -55,3 +46,56 @@ public final class NivmagusElemental extends CardImpl { return new NivmagusElemental(this); } } + +class NivmagusElementalCost extends CostImpl { + + private static final FilterSpell filter = new FilterInstantOrSorcerySpell("an instant or sorcery spell you control"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + } + + NivmagusElementalCost() { + super(); + TargetSpell target = new TargetSpell(filter); + target.setNotTarget(true); + this.addTarget(target); + this.text = "Exile an instant or sorcery spell you control"; + } + + private NivmagusElementalCost(NivmagusElementalCost cost) { + super(cost); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + Player player = game.getPlayer(controllerId); + if (player == null) { + return false; + } + player.chooseTarget(Outcome.Exile, targets.get(0), source, game); + Spell spell = game.getSpell(targets.getFirstTarget()); + if (spell == null) { + return false; + } + String spellName = spell.getName(); + if (spell.isCopy()) { + game.getStack().remove(spell, game); + } else { + player.moveCards(spell, Zone.EXILED, source, game); + } + paid = true; + game.informPlayers(player.getLogName() + " exiles " + spellName + " (as costs)"); + return paid; + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return targets.canChoose(source.getSourceId(), controllerId, game); + } + + @Override + public NivmagusElementalCost copy() { + return new NivmagusElementalCost(this); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/rtr/NivmagusElementalTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/rtr/NivmagusElementalTest.java new file mode 100644 index 0000000000..00f14b7ca3 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/rtr/NivmagusElementalTest.java @@ -0,0 +1,59 @@ +package org.mage.test.cards.single.rtr; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class NivmagusElementalTest extends CardTestPlayerBase { + + private static final String nivmagus = "Nivmagus Elemental"; + private static final String bolt = "Lightning Bolt"; + private static final String grapeshot = "Grapeshot"; + + @Test + public void testNivmagusElemental() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain"); + addCard(Zone.BATTLEFIELD, playerA, nivmagus); + addCard(Zone.HAND, playerA, bolt); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertCounterCount(playerA, nivmagus, CounterType.P1P1, 2); + assertLife(playerB, 20); + assertExileCount(playerA, bolt, 1); + } + + @Test + public void testNivmagusElementalStorm() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); + addCard(Zone.BATTLEFIELD, playerA, nivmagus); + addCard(Zone.HAND, playerA, bolt); + addCard(Zone.HAND, playerA, grapeshot); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerB); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, grapeshot, playerB); + setChoice(playerA, "No"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile"); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + assertAllCommandsUsed(); + + assertCounterCount(playerA, nivmagus, CounterType.P1P1, 6); + assertLife(playerB, 20); + assertExileCount(playerA, bolt, 1); + assertExileCount(playerA, grapeshot, 1); + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java deleted file mode 100644 index 62fe1191fc..0000000000 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileFromStackCost.java +++ /dev/null @@ -1,63 +0,0 @@ - -package mage.abilities.costs.common; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.stack.Spell; -import mage.players.Player; -import mage.target.TargetSpell; - -/** - * - * @author LevelX2 - */ -public class ExileFromStackCost extends CostImpl { - - public ExileFromStackCost(TargetSpell target) { - this.addTarget(target); - this.text = "Exile " + target.getTargetName(); - } - - public ExileFromStackCost(ExileFromStackCost cost) { - super(cost); - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), game)) { - Player player = game.getPlayer(controllerId); - for (UUID targetId : targets.get(0).getTargets()) { - Spell spellToExile = game.getStack().getSpell(targetId); - if (spellToExile == null) { - return false; - } - String spellName = spellToExile.getName(); - if (spellToExile.isCopy()) { - game.getStack().remove(spellToExile, game); - } else { - spellToExile.moveToExile(null, "", ability, game); - } - paid = true; - if (!game.isSimulation()) { - game.informPlayers(player.getLogName() + " exiles " + spellName + " (as costs)"); - } - } - } - return paid; - } - - @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return targets.canChoose(source.getSourceId(), controllerId, game); - } - - @Override - public ExileFromStackCost copy() { - return new ExileFromStackCost(this); - } - -}