diff --git a/Mage.Sets/src/mage/cards/s/SerraParagon.java b/Mage.Sets/src/mage/cards/s/SerraParagon.java index 9d7d47fa10..c72965463e 100644 --- a/Mage.Sets/src/mage/cards/s/SerraParagon.java +++ b/Mage.Sets/src/mage/cards/s/SerraParagon.java @@ -86,6 +86,7 @@ class SerraParagonPlayEffect extends AsThoughEffectImpl { && source.isControlledBy(affectedControllerId) && game.isActivePlayer(affectedControllerId) && !SerraParagonWatcher.checkPlayer(source, game) + && card.isPermanent(game) && (card.isLand(game) || card.getManaValue() <= 3) && Zone.GRAVEYARD.match(game.getState().getZone(card.getId())); } @@ -136,7 +137,8 @@ class SerraParagonTriggeredAbility extends TriggeredAbilityImpl { class SerraParagonGainEffect extends ContinuousEffectImpl { private final MageObjectReference mor; - private final Ability ability = new DiesSourceTriggeredAbility(new ExileSourceEffect().setText("exile it")).setTriggerPhrase("When this permanent is put into a graveyard from the battlefield, "); + private final Ability ability = new DiesSourceTriggeredAbility(new ExileSourceEffect().setText("exile it")) + .setTriggerPhrase("When this permanent is put into a graveyard from the battlefield, "); { ability.addEffect(new GainLifeEffect(2).concatBy("and")); @@ -191,7 +193,9 @@ class SerraParagonWatcher extends Watcher { || event.getType() == GameEvent.EventType.LAND_PLAYED) && event.hasApprovingIdentifier(MageIdentifier.SerraParagonWatcher)) { map.computeIfAbsent( - event.getAdditionalReference().getApprovingMageObjectReference(), x -> new HashSet<>() + event.getAdditionalReference() + .getApprovingMageObjectReference(), + x -> new HashSet<>() ).add(event.getPlayerId()); } } @@ -207,7 +211,7 @@ class SerraParagonWatcher extends Watcher { .getState() .getWatcher(SerraParagonWatcher.class) .map - .getOrDefault(new MageObjectReference(source), Collections.emptySet()) + .getOrDefault(new MageObjectReference(source.getSourceId(), game), Collections.emptySet()) .contains(source.getControllerId()); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/dmu/SerraParagonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/dmu/SerraParagonTest.java new file mode 100644 index 0000000000..9c6e6cc743 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/dmu/SerraParagonTest.java @@ -0,0 +1,95 @@ +package org.mage.test.cards.single.dmu; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class SerraParagonTest extends CardTestPlayerBase { + + private static final String paragon = "Serra Paragon"; + private static final String swamp = "Swamp"; + private static final String mox = "Mox Pearl"; + private static final String sinkhole = "Sinkhole"; + private static final String naturalize = "Naturalize"; + + @Test + public void testLandGainsAbility() { + addCard(Zone.BATTLEFIELD, playerA, "Snow-Covered Swamp"); + addCard(Zone.BATTLEFIELD, playerA, paragon); + addCard(Zone.GRAVEYARD, playerA, swamp); + addCard(Zone.HAND, playerA, sinkhole); + + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, swamp); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, sinkhole, swamp); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20 + 2); + assertExileCount(playerA, swamp, 1); + } + + @Test + public void testLandPlayedOnce() { + addCard(Zone.BATTLEFIELD, playerA, paragon); + addCard(Zone.GRAVEYARD, playerA, swamp, 2); + + playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, swamp); + + playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, swamp); + + setStopAt(1, PhaseStep.END_TURN); + try { + execute(); + } catch (Throwable e) { + if (!e.getMessage().contains("Can't find ability to activate command: Play Swamp")) { + Assert.fail("Should have had error about not being able to play land, but got:\n" + e.getMessage()); + } + } + } + + @Test + public void testNonlandGainsAbility() { + addCard(Zone.BATTLEFIELD, playerA, "Forest"); + addCard(Zone.BATTLEFIELD, playerA, paragon); + addCard(Zone.GRAVEYARD, playerA, mox); + addCard(Zone.HAND, playerA, naturalize); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mox); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, naturalize, mox); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 20 + 2); + assertPermanentCount(playerA, mox, 0); + assertExileCount(playerA, mox, 1); + } + + @Test + public void testNonlandPlayedOnce() { + addCard(Zone.BATTLEFIELD, playerA, paragon); + addCard(Zone.GRAVEYARD, playerA, mox, 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mox); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, mox); + + setStopAt(1, PhaseStep.END_TURN); + try { + execute(); + Assert.fail("Two spells were cast from graveyard"); + } catch (Throwable e) { + if (!e.getMessage().contains("Can't find ability to activate command: Cast Mox Pearl")) { + Assert.fail("Should have had error about not being able to cast spell, but got:\n" + e.getMessage()); + } + } + } +}